diff --git a/Android.bp b/Android.bp
index d205aeb..b599141 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,6 +14,47 @@
 
 package {
     default_visibility: ["//visibility:private"],
+    default_applicable_licenses: ["libcore_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+//
+// large-scale-change included anything that looked like it might be a license
+// text as a license_text. e.g. LICENSE, NOTICE, COPYING etc.
+//
+// Please consider removing redundant or irrelevant files from 'license_text:'.
+// http://go/android-license-faq
+license {
+    name: "libcore_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-GPL",
+        "SPDX-license-identifier-GPL-2.0",
+        "SPDX-license-identifier-LGPL",
+        "SPDX-license-identifier-MIT",
+        "SPDX-license-identifier-OpenSSL",
+        "SPDX-license-identifier-Unicode-DFS",
+        "SPDX-license-identifier-W3C",
+        "legacy_unencumbered",
+    ],
+    license_text: [
+        "LICENSE",
+        "NOTICE",
+    ],
 }
 
 build = [
@@ -21,18 +62,16 @@
     "NativeCode.bp",
 ]
 
-genrule {
-    name: "notices-for-framework-stubs",
-    visibility: [
-        "//frameworks/base",
-    ],
+java_genrule {
+    name: "notices-for-stubs-jar",
+    tools: ["soong_zip"],
     tool_files: [
         "NOTICE",
         "ojluni/NOTICE",
     ],
-    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",
-    ],
+    cmd: "mkdir $(genDir)/NOTICES && " +
+        "cp -f $(location NOTICE) $(genDir)/NOTICES/libcore-NOTICE && " +
+        "cp -f $(location ojluni/NOTICE) $(genDir)/NOTICES/ojluni-NOTICE && " +
+        "$(location soong_zip) -o $(out) -C $(genDir) -D $(genDir)/NOTICES",
+    out: ["notices-for-stubs.jar"],
 }
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 6731942..a6f42eb 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -146,6 +146,7 @@
             "-Xep:ConstantOverflow:WARN", // Known constant overflow in SplittableRandom
         ],
     },
+    min_sdk_version: "31",
 }
 
 //
@@ -163,12 +164,18 @@
         // Use the source code for the I18N module intra core API as using the
         // compiled version does not work due to limitations in either soong or the javac
         // toolchain. See http://b/142056316 for more details.
-        ":i18n-module-intra-core-api-stubs-source",
+        ":i18n.module.intra.core.api{.public.stubs.source}",
         ":core_oj_java_files",
         ":core_libart_java_files",
+        // framework-api-annotations contain API annotations, e.g. @SystemApi.
+        ":framework-api-annotations",
         ":openjdk_lambda_stub_files",
         ":openjdk_generated_annotation_stub_files",
         ":app-compat-annotations-source",
+
+        // Use the okhttp source too to allow libcore code to reference it
+        // directly.
+        ":okhttp_impl_files",
     ],
 
     sdk_version: "none",
@@ -187,11 +194,18 @@
         "compat-changeid-annotation-processor",
         "unsupportedappusage-annotation-processor",
     ],
+    libs: [
+        "conscrypt.module.intra.core.api",
+    ],
 }
 
 platform_compat_config {
     name: "libcore-platform-compat-config",
     src: ":core-all",
+    visibility: [
+        "//art/build/apex",
+        "//art/build/sdk",
+    ],
 }
 
 // A system modules definition for use by core library targets only. It only
@@ -200,13 +214,15 @@
 // 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.
+// bouncycastle, etc. It is also used to compile Libcore tests, as well as ART
+// Java tests (run-tests).
 java_system_modules {
     name: "core-all-system-modules",
 
     // Visibility is deliberately restricted to a small set of build modules that
     // the core library team control.
     visibility: [
+        "//art/test:__subpackages__",
         "//external/apache-harmony:__subpackages__",
         "//external/apache-xml",
         "//external/okhttp",
@@ -221,11 +237,13 @@
     name: "core-oj",
     visibility: [
         "//art/build/apex",
+        "//art/build/sdk",
         "//external/wycheproof",
         "//libcore/benchmarks",
+        "//packages/modules/ArtPrebuilt",
     ],
     apex_available: [
-        "com.android.art.release",
+        "com.android.art",
         "com.android.art.debug",
     ],
     defaults: ["libcore_java_defaults"],
@@ -258,6 +276,9 @@
 
     notice: "ojluni/NOTICE",
 
+    hiddenapi_additional_annotations: [
+        "core-oj-hiddenapi-annotations",
+    ],
 }
 
 // Contains parts of core library not associated with OpenJDK. Contains not
@@ -267,13 +288,13 @@
     name: "core-libart",
     visibility: [
         "//art/build/apex",
-        "//external/robolectric-shadows",
+        "//art/build/sdk",
         "//external/wycheproof",
         "//libcore/benchmarks",
-        "//frameworks/layoutlib",
+        "//packages/modules/ArtPrebuilt",
     ],
     apex_available: [
-        "com.android.art.release",
+        "com.android.art",
         "com.android.art.debug",
     ],
     defaults: ["libcore_java_defaults"],
@@ -307,19 +328,30 @@
                 "tz_version_host_tzdata_apex",
             ],
         },
+        darwin: {
+            enabled: false,
+        },
     },
 }
 
+// Java library for use on host, e.g. by robolectric or layoutlib.
+java_library {
+    name: "core-libart-for-host",
+    visibility: [
+        "//art/build/sdk",
+        "//external/robolectric-shadows",
+        "//frameworks/layoutlib",
+    ],
+    static_libs: [
+        "core-libart",
+    ],
+    sdk_version: "none",
+    system_modules: "none",
+}
+
 // Provided solely to contribute information about which hidden parts of the
 // core-oj API are used by apps.
 //
-// The build system determines that this library provides hiddenapi information
-// for the core-oj bootjar because its name is of the form <x>-hiddenapi, where
-// <x> is the name of a boot jar. That triggers the generation of a flags.csv
-// file which encapsulates information extracted from the UnsupportedAppUsage
-// annotations in the dex. The information from that file is then encoded into
-// the core-oj file.
-//
 // Usually, e.g. for core-libart, the UnsupportedAppUsage annotations are
 // added to the source that is compiled directly into the bootjar and the build
 // system extracts the information about UnsupportedAppUsage directly from
@@ -331,7 +363,7 @@
 // difficult to pull down changes from upstream.
 //
 java_library {
-    name: "core-oj-hiddenapi",
+    name: "core-oj-hiddenapi-annotations",
     // Do not allow this to be accessed from outside this directory.
     visibility: ["//visibility:private"],
     defaults: ["libcore_java_defaults"],
@@ -345,40 +377,6 @@
     plugins: ["unsupportedappusage-annotation-processor"],
 }
 
-//
-// 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"],
-    sdk_version: "none",
-    system_modules: "core-all-system-modules",
-    dxflags: ["--core-library"],
-    dex_preopt: {
-        enabled: false,
-    },
-    java_version: "1.9",
-    notice: "ojluni/NOTICE",
-}
-
-java_library {
-    name: "core-libart-testdex",
-    installable: true,
-    static_libs: ["core-libart"],
-    sdk_version: "none",
-    system_modules: "core-all-system-modules",
-    dxflags: ["--core-library"],
-    dex_preopt: {
-        enabled: false,
-    },
-    notice: "ojluni/NOTICE",
-}
-
 java_defaults {
     name: "core_lambda_stubs_defaults",
     defaults: ["libcore_java_defaults"],
@@ -510,8 +508,7 @@
         "//libcore/benchmarks",
         "//packages/apps/KeyChain/tests",
         "//system/timezone/distro/core",
-        "//packages/modules/Connectivity/tests/cts/net",
-        "//packages/modules/Connectivity/tests/cts/net/api23Test",
+        "//packages/modules/Connectivity/tests:__subpackages__",
     ],
     hostdex: true,
     srcs: ["support/src/test/java/**/*.java"],
@@ -529,6 +526,7 @@
 java_test {
     name: "jsr166-tests",
     visibility: [
+        "//art/build/sdk",
         "//cts/tests/libcore/jsr166",
     ],
     srcs: ["jsr166-tests/src/test/java/**/*.java"],
@@ -555,10 +553,19 @@
     tools: ["smali"],
 }
 
+filegroup {
+    name: "core-ojtests-javax-resources",
+    // Set path to keep the resources and .class files in the same directory in the jar file.
+    path: "ojluni/src",
+    srcs: ["ojluni/src/test/javax/**/*"],
+    exclude_srcs: ["ojluni/src/test/javax/**/*.java"],
+}
+
 // Builds the core-tests library.
 java_test {
     name: "core-tests",
     visibility: [
+        "//art/build/sdk",
         "//cts/tests/libcore/luni",
     ],
     defaults: ["libcore_java_defaults"],
@@ -588,6 +595,7 @@
     ],
     exclude_java_resource_dirs: [
         "ojluni/src/test/java",
+        "ojluni/src/test/javax",
         "ojluni/src/test/resources",
     ],
 
@@ -618,7 +626,6 @@
         "nist-pkix-tests",
         "slf4j-jdk14",
         "sqlite-jdbc",
-        "tzdata-testing",
         "truth-prebuilt-jar",
     ],
 
@@ -643,11 +650,9 @@
         "harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/*.java",
         "luni/src/test/java/libcore/javax/crypto/**/*.java",
         "luni/src/test/java/libcore/javax/net/ssl/**/*.java",
+        "luni/src/test/java/libcore/libcore/util/SerializationTester.java",
         "luni/src/test/java/org/apache/harmony/crypto/**/*.java",
     ],
-    exclude_srcs: [
-        "luni/src/test/java/org/apache/harmony/crypto/tests/javax/crypto/SealedObjectTest.java",
-    ],
 
     java_resource_dirs: [
         "luni/src/test/java",
@@ -674,12 +679,17 @@
 
     srcs: [
         "ojluni/src/test/java/**/*.java",
+        "ojluni/src/test/javax/**/*.java",
     ],
     java_resource_dirs: [
         "ojluni/src/test/java",
         "ojluni/src/test/resources",
     ],
 
+    java_resources: [
+        ":core-ojtests-javax-resources",
+    ],
+
     sdk_version: "none",
     system_modules: "core-all-system-modules",
     libs: [
@@ -687,7 +697,10 @@
         "bouncycastle",
     ],
 
-    static_libs: ["testng"],
+    static_libs: [
+        "junit",
+        "testng",
+    ],
 
     // ojluni/src/test/java/util/stream/{bootlib,boottest}
     // contains tests that are in packages from java.base;
@@ -711,11 +724,13 @@
 java_test {
     name: "core-ojtests-public",
     visibility: [
+        "//art/build/sdk",
         "//cts/tests/libcore/ojluni",
     ],
     defaults: ["libcore_java_defaults"],
     srcs: [
         "ojluni/src/test/java/**/*.java",
+        "ojluni/src/test/javax/**/*.java",
     ],
     // Filter out the following:
     // 1.) DeserializeMethodTest and SerializedLambdaTest, because they depends on stub classes
@@ -734,10 +749,15 @@
         "ojluni/src/test/dist",
     ],
 
+    java_resources: [
+        ":core-ojtests-javax-resources",
+    ],
+
     sdk_version: "none",
     system_modules: "core-all-system-modules",
     libs: [
         "bouncycastle",
+        "junit",
         "okhttp",
         "testng",
     ],
@@ -747,6 +767,9 @@
 // available to metalava. Used for nullability annotations in OpenJDK source.
 droiddoc_exported_dir {
     name: "ojluni-annotated-sdk-stubs",
+    visibility: [
+        "//libcore:__subpackages__",
+    ],
     path: "ojluni/annotations/sdk",
 }
 
@@ -814,7 +837,7 @@
     system_modules: "none",
 }
 
-// A special set of system modules needed to build art.module.public.api.stubs
+// A special set of system modules needed to build art.module.public.api
 // that contain nullability annotations when targeting java language level 1.9
 // and above.
 java_system_modules {
@@ -843,47 +866,74 @@
     // replacement (with $1, $2 backreferences to the regex groups)
     "'$$1https://docs.oracle.com/javase/8/docs/$$2\">' "
 
-// Generates stubs for the parts of the public SDK API provided by the ART module.
-//
-// Only for use by art.module.public.api.stubs target below and the building of the
-// public API.
-droidstubs {
-    name: "art-module-public-api-stubs-source",
+java_library {
+    name: "framework-api-annotations-lib",
+    srcs: [":framework-api-annotations"],
+    sdk_version: "none",
+    patch_module: "java.base",
+    system_modules: "core-all-system-modules",
+    installable: false,
     visibility: [
+        "//visibility:private",
+    ],
+}
+
+// Define the public SDK API provided by the ART module.
+java_sdk_library {
+    name: "art.module.public.api",
+    visibility: [
+        "//art/build/sdk",
         "//frameworks/base",
+        "//frameworks/base/api",
     ],
     srcs: [
         ":core_oj_api_files",
         ":core_libart_api_files",
     ],
-    java_version: "1.9",
-    installable: false,
-    sdk_version: "none",
-    system_modules: "java-current-stubs-system-modules",
     libs: [
+        // Put framework-api-annotations into libs to avoid exposing the definition of framework's
+        // annotations from libcore (wrong place) instead of framework (correct place).
+        "framework-api-annotations-lib",
         // Provide access to I18N constants that are used to initialize
         // constants in the public API. i.e. to allow the value of the
         // java.text.CollectionElementIterator.NULLORDER to be initialized from
         // android.icu.text.CollationElementIterator.NULLORDER.
         "i18n.module.intra.core.api.stubs",
     ],
+    stub_only_static_libs: ["notices-for-stubs-jar"],
+    java_version: "1.9",
 
-    args: rewrite_openjdk_doc_args,
+    // Make dex jars for the stubs available for use by hiddenapi processing.
+    compile_dex: true,
 
-    create_doc_stubs: true,
+    public: {
+        enabled: true,
+    },
+    system: {
+        enabled: true,
+    },
+    module_lib: {
+        enabled: true,
+    },
+
+    api_only: true,
+    droiddoc_options: [
+        rewrite_openjdk_doc_args,
+        "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* ",
+    ],
 
     // Emit nullability annotations from the source to the stub files.
     annotations_enabled: true,
 
     merge_annotations_dirs: [
+        "metalava-manual",
         "ojluni-annotated-sdk-stubs",
     ],
-}
 
-// A stubs target containing the parts of the public SDK API provided by the ART module.
-java_library {
-    name: "art.module.public.api.stubs",
-    srcs: [":art-module-public-api-stubs-source"],
+    doctag_files: [
+        ":known-oj-tags",
+    ],
+
     errorprone: {
         javacflags: [
             "-Xep:MissingOverride:OFF",
@@ -892,6 +942,13 @@
     patch_module: "java.base",
     sdk_version: "none",
     system_modules: "java-current-stubs-system-modules",
+    // The base name for the artifacts that are automatically published to the
+    // dist and which end up in one of the sub-directories of prebuilts/sdk.
+    // As long as this matches the name of the artifacts in prebuilts/sdk then
+    // the API will be checked for compatibility against the latest released
+    // version of the API.
+    dist_stem: "art",
+    dist_group: "android",
 }
 
 // Used when compiling higher-level code against art.module.public.api.stubs.
@@ -1017,18 +1074,6 @@
     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",
-    visibility: [
-        "//art/build/sdk",
-        "//system/timezone/distro/core",
-    ],
-    srcs: [":timezone_host_files"],
-}
-
 // A special set of system modules for building the following library for use
 // in the art-module-public-api-system-modules.
 java_system_modules {
@@ -1060,6 +1105,8 @@
 java_library {
     name: "art.module.api.annotations",
     visibility: [
+        "//art/build/sdk",
+        "//external/icu/android_icu4j",
         "//frameworks/base",
     ],
     host_supported: true,
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..6d8601b
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+  license_type: RESTRICTED
+}
diff --git a/NativeCode.bp b/NativeCode.bp
index 9619420..18a8abc 100644
--- a/NativeCode.bp
+++ b/NativeCode.bp
@@ -20,6 +20,7 @@
 
 cc_defaults {
     name: "core_native_default_flags",
+    defaults: ["art_module_source_build_defaults"],
     host_supported: true,
     cflags: [
         "-Wall",
@@ -33,16 +34,18 @@
             enabled: false,
         },
     },
+    min_sdk_version: "S",
 }
 
 cc_defaults {
     name: "core_native_default_libs",
-
+    header_libs: ["jni_headers"],
     shared_libs: [
         "libbase",
         "liblog",
         "libnativehelper",
     ],
+    static_libs: ["libnativehelper_compat_libc++"],
 }
 
 cc_library_shared {
@@ -51,7 +54,7 @@
         "//art/build/apex",
     ],
     apex_available: [
-        "com.android.art.release",
+        "com.android.art",
         "com.android.art.debug",
     ],
     defaults: [
@@ -60,47 +63,29 @@
     ],
     srcs: [
         ":luni_native_srcs",
-        "dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp",
     ],
     shared_libs: [
         "libandroidio",
-        "libbase",
         "libcrypto",
+        "libicu",
         "libexpat",
-        "libicuuc",
-        "libicui18n",
-        "libnativehelper",
         "libz",
     ],
     static_libs: [
-        "libandroidicuinit",
         "libziparchive",
     ],
-    target: {
-        android: {
-            cflags: [
-                // -DANDROID_LINK_SHARED_ICU4C to enable access to the full ICU4C.
-                // See external/icu/android_icu4c/include/uconfig_local.h
-                // for more information.
-                "-DANDROID_LINK_SHARED_ICU4C",
-            ],
-        },
-    },
 }
 
 cc_library_shared {
     name: "libandroidio",
     visibility: [
         "//art/build/apex",
+        "//art/build/sdk",
         "//external/conscrypt",
     ],
     apex_available: [
-        "com.android.art.release",
+        "com.android.art",
         "com.android.art.debug",
-        // TODO(b/147813447) remove this. This is currently due to the 'runtime_libs'
-        // dependency from libjavacrypto in the conscrypt APEX.
-        "com.android.conscrypt",
-        "test_com.android.conscrypt",
     ],
     defaults: [
         "core_native_default_flags",
@@ -141,11 +126,12 @@
     shared_libs: [
         "libandroidio",
         "libcrypto",
-        "libicuuc",
-        "libnativehelper",
+        "libicu",
         "libz",
     ],
-    static_libs: ["libfdlibm"],
+    static_libs: [
+        "libfdlibm",
+    ],
 
     target: {
         linux_glibc: {
@@ -157,12 +143,6 @@
             ],
         },
         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",
             ],
@@ -178,7 +158,7 @@
         "//art/build/apex",
     ],
     apex_available: [
-        "com.android.art.release",
+        "com.android.art",
         "com.android.art.debug",
     ],
     defaults: ["libopenjdk_native_defaults"],
@@ -219,14 +199,10 @@
         "luni/src/test/native/libcore_java_nio_BufferTest.cpp",
         "luni/src/test/native/libcore_libcore_util_NativeAllocationRegistryTest.cpp",
     ],
-    target: {
-        android: {
-            shared_libs: ["libnativehelper_compat_libc++"],
-        },
-        host: {
-            shared_libs: ["libnativehelper"],
-        },
-    },
+    shared_libs: [
+        "liblog",
+        "libnativehelper",
+    ],
 
     strip: {
         keep_symbols: true,
@@ -238,12 +214,26 @@
     name: "libjavacore-unit-tests",
     defaults: ["core_native_default_flags"],
 
+    // TODO(b/172480617): Fix this source dependency from
+    // platform_testing/build/tasks/tests/native_test_list.mk.
+    enabled: true,
+
     // Add -fno-builtin so that the compiler doesn't attempt to inline
     // memcpy calls that are not really aligned.
     cflags: ["-fno-builtin"],
-    srcs: ["luni/src/test/native/libcore_io_Memory_test.cpp"],
+    srcs: [
+        "luni/src/test/native/libcore_io_Memory_test.cpp",
+        // libcore_io_Memory_test.cpp includes libcore_io_Memory.cpp which
+        // depends on JniConstants.cpp (but these are not used in the tests).
+        "luni/src/main/native/JniConstants.cpp",
+    ],
 
-    shared_libs: ["libnativehelper"],
+    shared_libs: [
+        "liblog",
+        "libnativehelper",
+    ],
+
+    static_libs: ["libnativehelper_compat_libc++"],
 }
 
 // Set of benchmarks for libjavacore functions.
@@ -251,8 +241,20 @@
     name: "libjavacore-benchmarks",
     defaults: ["core_native_default_flags"],
 
-    srcs: ["luni/src/benchmark/native/libcore_io_Memory_bench.cpp"],
+    // TODO(b/172480617): Fix this source dependency from
+    // platform_testing/build/tasks/tests/native_metric_test_list.mk.
+    enabled: true,
+
+    srcs: [
+        "luni/src/benchmark/native/libcore_io_Memory_bench.cpp",
+        // libcore_io_Memory_bench.cpp includes libcore_io_Memory.cpp which
+        // depends on JniConstants.cpp (but these are not used in the benchmark).
+        "luni/src/main/native/JniConstants.cpp",
+    ],
     test_suites: ["device-tests"],
 
-    shared_libs: ["libnativehelper"],
+    shared_libs: [
+        "liblog",
+        "libnativehelper",
+    ],
 }
diff --git a/OWNERS b/OWNERS
index 174fb87..56d718b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -6,17 +6,16 @@
 # People who can approve changes for submission; don't send review emails to them
 # unless you know what you're doing.
 dauletz@google.com
-narayan@google.com
+mingaleev@google.com
 nfuller@google.com
 nikitai@google.com
 paulduffin@google.com
-peteg@google.com
 prb@google.com
-tobiast@google.com
+rpl@google.com
 vichang@google.com
 
 # Don't send these folks any review emails for this project.
+calin@google.com
+narayan@google.com
 ngeoffray@google.com
-sehr@google.com
 vmarko@google.com
-dbrazdil@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index f8c149d..f399594 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,7 +1,90 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
-      "name": "CtsSaxTestCases"
+      "name": "CtsLibcoreTestCases",
+      "options": [
+        {
+          "exclude-filter": "com.android.org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH"
+        },
+        {
+          "exclude-filter": "com.android.org.conscrypt.java.security.KeyPairGeneratorTest"
+        },
+        {
+          "exclude-filter": "com.android.org.conscrypt.java.security.SignatureTest"
+        },
+        {
+          "exclude-filter": "com.android.org.conscrypt.javax.crypto.CipherBasicsTest"
+        },
+        {
+          "exclude-filter": "com.android.org.conscrypt.javax.net.ssl.KeyManagerFactoryTest"
+        },
+        {
+          "exclude-filter": "com.android.org.conscrypt.javax.net.ssl.SSLSocketVersionCompatibilityTest"
+        },
+        {
+          "exclude-filter": "libcore.java.lang.OldRuntimeTest"
+        },
+        {
+          "exclude-filter": "libcore.java.lang.OldThreadTest"
+        },
+        {
+          "exclude-filter": "libcore.java.lang.ref.FinalizeTest"
+        },
+        {
+          "exclude-filter": "libcore.java.math.BigIntegerTest"
+        },
+        {
+          "exclude-filter": "libcore.java.net.ConcurrentCloseTest"
+        },
+        {
+          "exclude-filter": "libcore.java.net.OldSocketTest"
+        },
+        {
+          "exclude-filter": "libcore.java.net.URLConnectionTest"
+        },
+        {
+          "exclude-filter": "libcore.java.nio.channels.DatagramChannelMulticastTest"
+        },
+        {
+          "exclude-filter": "libcore.libcore.net.NetworkSecurityPolicyTest"
+        },
+        {
+          "exclude-filter": "libcore.libcore.util.NativeAllocationRegistryTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.logging.tests.java.util.logging.SocketHandlerTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.lang.ObjectTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.lang.ProcessManagerTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.math.OldBigIntegerTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.net.InetAddressThreadTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.nio.channels.DatagramChannelTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.util.ScannerTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.util.TimerTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.java.util.WeakHashMapTest"
+        },
+        {
+          "exclude-filter": "org.apache.harmony.tests.javax.net.ssl.SSLSessionTest"
+        },
+        {
+          "exclude-filter": "tests.java.sql.StressTest"
+        }
+      ]
     }
   ]
-}
+}
\ No newline at end of file
diff --git a/apex/Android.bp b/apex/Android.bp
deleted file mode 100644
index 51a7335..0000000
--- a/apex/Android.bp
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// 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.
-
-// i18n APEX is intended as a home for ICU as of July 2019.
-// Various parts and dependencies of ICU would be gradually moved into this APEX,
-// and the below build rules should reflect the latest status.
-// TODO(b/138434658): Move the apex declaration back to external/icu
-// The apex is declared in libcore/ to workaround new dependency from external/icu
-// to system/sepolicy in a downstream branch.
-apex {
-    name: "com.android.i18n",
-    defaults: ["com.android.i18n-defaults"],
-    certificate: ":com.android.i18n.certificate",
-}
-
-apex_defaults {
-    name: "com.android.i18n-defaults",
-    compile_multilib: "both",
-    manifest: "manifest.json",
-    prebuilts: ["apex_icu.dat"],
-    key: "com.android.i18n.key",
-}
-
-apex_key {
-    name: "com.android.i18n.key",
-    public_key: "com.android.i18n.avbpubkey",
-    private_key: "com.android.i18n.pem",
-}
-
-android_app_certificate {
-    name: "com.android.i18n.certificate",
-    certificate: "com.android.i18n",
-}
diff --git a/apex/com.android.i18n.avbpubkey b/apex/com.android.i18n.avbpubkey
deleted file mode 100644
index f1c97a0..0000000
--- a/apex/com.android.i18n.avbpubkey
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.i18n.pem b/apex/com.android.i18n.pem
deleted file mode 100644
index 7676453..0000000
--- a/apex/com.android.i18n.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIJKwIBAAKCAgEA89VXuQrlqB0L731Es2ud65k5XkyGn0FjQfynPYRPz3nkpNaF
-3LbJ6JXIGKUQMY2pVQFNl2wUtylTJohNv8SWu/hPBMOmHu2zGvvfErKN7QD25y12
-D9jws3VlPhCWQsEZSjloYKI1MvMPcvtLgHoSuMl6JlT8mngC+uR8WLGtDKZYGICf
-I2rhQ5ugzDp00tGJJV9HKAXHx7zA9X+29HbMte57ibOrO4Xs7zLankV3rVEc0ZcD
-phA1RYh6lg9KYfsq/zbEbCRGPLTlqKa3zDPrnXTKInR//5fW7tWgqqRyXGumM8pA
-B1Huba878WnMwcWWYLjxRMQ6hOOCnGY7167JoAnX+NRmUZWXrrSiaCr6o61ingb6
-6BvQTN0f1q2lXIf1bOPRkeNkxBB7q3YFa4XaF9ZpQs7V4vlrvE/uLWDmhTQ6snML
-zWYbD+/nQ6u5BIdh+1rNk5RWp53IoNTGyJQnTpSkA2u+rtDuyKG4av6Vx2cPJ5Mu
-8vAALAyEOqlZr0CeJR0h3m6XVt0PpDxNUvQU53tlzIKD2BuELWeRSJ79DkYf+Soh
-vc0upDbdsy1r4C/Df5UpKnOKCmrYmJ1tdiigVeDH3y0B0ilD2dUqubqlc5Tw0a13
-PkpWPdJV7QpTyb3GDWa4DRpYRxCGDylCsS2rsXbsiMGqJFL3G0w06ahTmFUCAwEA
-AQKCAgEA4nVbQsXHI8rOYgADBWxGwCCPsm/6fABbslZ38N9ozHYWD64ZpzKw9W3e
-6FytXIiIIyXRrXe5CZ+81UW0iA2KPUvR/8fCCmmTddVFifUBcYP6zBxh0TgX3WSD
-wg/frmHvHguRUGZ2aDpsN8sChXFa3/pnkyBNdx1NDz2T60AhS2VW3nLe2iMS0hrB
-Tcxg4cevy2DhEl/D+1LoF1olTojjeXjjjbGrr92jf0jI2EQGcZaq4FGUFvBouYqW
-57WNzNBcT6nK5fEOtqT/wxIMFACIrLViYnu2wWiBO1J3JOUUPZfRRbpqmyHSAlbE
-omMzwyfCkVRS6B4jh3ZRwPYGUDvKjyNLeXXEr7Q6sAiwhvgz8Z5DIyzZr9SkExuQ
-5jfjfYCNsFaA/QmA34hV5KsPLfLFbW3hvDc6ApOn3yvOkIP3Cb2JM/mfyHh7cRpz
-y/UTep2e3uNj7fDkdrqp2oj/EOSKa0KSJCpqkgUwEFFCEvxeYeUgwlM+axSZNXEx
-ocRgQpui/2tVH8rgny3ayYDknleVaWtzxg7QLH7vV90ztjh4XjmZgl4R6N6vO1IT
-G2XN05vySoE+8ZdQVz3Ko3w3NLon4gwyXv8K+PmHBUsIoY37OPpZoj24n/Uajcuh
-crr5zSGlXhC+OzNk1tJ1NosHF70b/sYwdSIRpxEzA7QggSi6iAUCggEBAP5yHpkr
-BZB/C95zT4xd8ugYAw/5rFQXgwYkf1CYUp/lEXBUJGnimIwo5Gr9tGAAxTwXTTJH
-TI25EhAFu/WEh4h31SkL2b3S6jqupCqYwZdrl5TAY/35FBpGZN+ZirTHPP6ZobxX
-8zhHTl+7mKN/neA6sbLwH4WDZa+LUHScTnVSjzyL2PorPdsolFjOLILQE6LZjinB
-5bX972wjK4Q72gfdkia/Csq8Wo2/k53A2ur0fFojRHHI1M9Fthe6OI4RX/RwyHih
-R9S68xrz2bcYQ8XpoaaNpLY/FXev8WcBicjApN+eQQCK2ZGA9+UxgQRld317Wvqf
-zAyKp5idtRJUbb8CggEBAPVSoNyrghZFfaWGDe3pCnKkeZhqNsLbI5YrQohX6Quy
-BhRCP5t5wyNuMQX5rRZqeb3VgbW/06faVwZZ+bwA0KT7RYy0zgJhfD6bZ7WmzQMc
-HmAVqvN8iZIIjpMeN/174yYdqq0ShUYmra151ReL/CWs32kBWNKT6l487J7DAoYR
-ZHtec9nbs2ZFqea+PNAP8VAcsmsemwXe1w63RxDgdZccJmMj0TWmBj47RstMWTLE
-CrCGfXW9qmvs/Itzbuy589DS0AXZfTW+U0TD4RnCcjV7JDyEZASA3V7lMiyKXDTJ
-6+CUcgzOWzdTfAeVcG0olXXNCdCePX8uiqkwSCaXpusCggEBAI4tHkPf8kAHfY5T
-SIPaizx9DlkC3fQvHxtzkWBrfN+zk8b8fUxdPXgz8U6HbR6nz44ARzZs+K3IV/tz
-+M77uu/aZdWFtamIDTG1HC5hJOuDRzPrPPRRFZaI9xyqIwNYwRBSsDkZu+IalgSQ
-Qn45dPIyWdDus+5auZsZcV93Z6/O7hKa4icHuoyXZC0rJ1wBALficLmMitrihcIa
-9Nnyx6XVfTEBVvppvP+vqMBhXvIiosmLI1ehLKiU/2bKu4dG1iM0UhB1rjmELQtG
-bsUMXfJc1eLHCt566XfzbCRui5sNahM5zoCLFX9kXSBIRRs7x0TqhK++Uro/T97L
-YL5ZRukCggEBAOaEpB93EZ/34F7/HmumBWlAX/n2JErpPAFJ2RTg9l1FBS1YKwjf
-W5wZWPtyZ1Ce8JKO43lzLWGWaxvOxDoC0guVCP90jffyvprd0JACkrYPYAONmLt/
-FI4ieEaJqLcKCKGyUsSamJ0Yjy5pQvEDWwXT8YJr/5iv4RR4TyfHusFb6n16fYYD
-SgoZ/9KQg/hGYsySipzZf3X+tTpgweh74kMB8phJ+bZdsZQcgyNZNJ/dUuYZGh7f
-ABq174DiESNkgFSDI3G7skoj8360SPq5mjPi6GPtS0ZoCJu45nKv+ICqFHlNQ/YA
-mfnc+rjtlV0dO4QcDNL5PnQZubXNZp7M9c0CggEBAIrfxdeELSqeVld3nhHFty0b
-ZdmFJWRj6k9zjoOYe8LPkAiue0Zm10sCiLFiRgTH6msnfBloYJ2iiDgSSnIlUvaH
-HFxoLWtv2az2B3g6gfJ5KbdE8mqfz0hGMOUBPFBarC4HrPslR28Cwn8mD5CvN4a/
-oAz3kOlaGokVF6Ikwd606JBFTVKSwr2niTJUwGXgn85tViCWqUm4v24BntbZZ9Rs
-k6ffBUl/k02zw/U405I3qTjCAnetNY3wHmjvdqkCcoWTAmG04IfGlqVE3NMjjLQD
-h9Xx2Nr5SV6djWbmYfT0Ox4Ha/IPuCCAZbBv6Or2wQSOQwb5fUgFcu3NrXU1rQQ=
------END RSA PRIVATE KEY-----
diff --git a/apex/com.android.i18n.pk8 b/apex/com.android.i18n.pk8
deleted file mode 100644
index 100ed14..0000000
--- a/apex/com.android.i18n.pk8
+++ /dev/null
Binary files differ
diff --git a/apex/com.android.i18n.x509.pem b/apex/com.android.i18n.x509.pem
deleted file mode 100644
index fcf1a53..0000000
--- a/apex/com.android.i18n.x509.pem
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIFUTCCAzmgAwIBAgIUHufr9X4LD87MyuJ/8AaMvsIhXjUwDQYJKoZIhvcNAQEL
-BQAwNzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmcm9uaWExEzARBgNVBAoM
-Ckdvb2dsZSBMTEMwIBcNMTkwNzA1MTU0ODM2WhgPNDc1NzA1MzExNTQ4MzZaMDcx
-CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZnJvbmlhMRMwEQYDVQQKDApHb29n
-bGUgTExDMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsUMFBc1QNyhj
-gU47F2O3kUrZhATA6Gz644sXvrqUg03retG3jsIEFmBXgbXngvF2yq9sRiGm4D5j
-9Sf5fguDqy9C/Q8MiUEAqQo1ygy9MubMfdGVLb2dcFoKXwyig8KzSS03+73IiUnF
-iCy5GzPO6ltga4nsbXUE6egexE3WGLQ0Lu7gCLNZn1Zd20p4BlTUl64CEu9zt6NN
-D6okd7IGceipBbpK9WDMW6ygXJ5sTJohZYSrSOPkoQFVilWFd5VryBxboTmxhSyo
-4dvNavnNCKOhsCCi8QIHOlXMDWxN970giv60FzoXoD2QwD5o+3I6SIIutEnGmh/d
-SECcK9yK+YECqw2XhvoBR4NH4RltaWKZsy62YPSYZXJXZ4H1P+9L9Q5dwLlI2Itt
-IWtYY88T8P2w8e2KzYewkE/XM4kRUw8pNWod1Hok2WuvZxdbPJ0+Hhvo1FVTwV1K
-kdtUuVPut6fpA2hEfGmwdKpK18Qe5ZLBZ1r1lSrjlfct+BWelADaZRNNyJey0u/s
-DgZGbiJG6tJqDESN229/eMTRt9gDncIx7S37RFgOv8jlUul5miKH3QP6neotofWw
-EWEKFjaDNhqU83rdpk48Br/HTiXA6pvaGlN0RQyBVB7uavvTYKTp8cGU11hkIx8p
-Vkp0EOCs9ajlt1+GyMCrPOk8A10rrOcCAwEAAaNTMFEwHQYDVR0OBBYEFMXzY0Gf
-eAdY8RjzwPnOou8VgjD3MB8GA1UdIwQYMBaAFMXzY0GfeAdY8RjzwPnOou8VgjD3
-MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBABrAExrvMkg26gQg
-rUh170Ms8T5jvIpWyIb7fSLjsA0c2q+zZiIUViO1t2eNQtdExGcmEOBF1+LqAIbT
-zA8nz9ZHweGZi01VodPaGKuz2VWWMzQaENW2RQGaxO9g8nCHGrbwchE7IbNOT1FD
-jzVYWcCKydr4niJWjSy9ey8eNDv/Iqto64/nPI7PxtBVfH7G8hgamyVtwWhhciTH
-nlg6X0EAxq5VwZSK4G8n+gsozPQHRjvBrSzt0A187vh/g6LQPLDZjPnzbZVtfFtM
-pv+hImxyDN3DZYrna2aGxWBIXEFjH61xueBGWaCo8TwvR8NIHM/i4s/zyhUxGUYL
-307i940cEF3rYJ/urzZzXJlxiu8p0Y12i/t+vXRqXM8d65QSMLqDDBHqZ3mPkcBp
-U7hWVi5HuyWGQF4FMK8sdemJITJpg1xztybsvRJ9kDeWxPNQllC4dREaKVhI/3WM
-eP7bpMmZxngoHbAB2f11lQf1A0fWFkng/Gntqnw0Dd6J+++NuuoFUjZLAWzUpoje
-J6J9CuxBjng0n94ZN+E8E5zsAtaO9WvhSQwTvNbHZmERxvtSm6mIH1XEBTi5tOHZ
-PBAAJuzZrFFZWevI44vgpCrF4lO3F9qE+sKn+2sARGuAjGCNV+jJCD+7tySjf7js
-2uaWgWOl7EexciIHD9FbZ3ANsiRU
------END CERTIFICATE-----
diff --git a/apex/manifest.json b/apex/manifest.json
deleted file mode 100644
index 4d1b2b6..0000000
--- a/apex/manifest.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
-  "name": "com.android.i18n",
-  "version": 1
-}
\ No newline at end of file
diff --git a/api/current.txt b/api/current.txt
new file mode 100755
index 0000000..5276996
--- /dev/null
+++ b/api/current.txt
@@ -0,0 +1,20388 @@
+// Signature format: 2.0
+package android.system {
+
+  public final class ErrnoException extends java.lang.Exception {
+    ctor public ErrnoException(String, int);
+    ctor public ErrnoException(String, int, Throwable);
+    method @NonNull public java.io.IOException rethrowAsIOException() throws java.io.IOException;
+    method @NonNull public java.net.SocketException rethrowAsSocketException() throws java.net.SocketException;
+    field public final int errno;
+  }
+
+  public class Int64Ref {
+    ctor public Int64Ref(long);
+    field public long value;
+  }
+
+  public final class Os {
+    method public static java.io.FileDescriptor accept(java.io.FileDescriptor, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static boolean access(String, int) throws android.system.ErrnoException;
+    method public static void bind(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void bind(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void chmod(String, int) throws android.system.ErrnoException;
+    method public static void chown(String, int, int) throws android.system.ErrnoException;
+    method public static void close(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void connect(java.io.FileDescriptor, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void connect(@NonNull java.io.FileDescriptor, @NonNull java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static java.io.FileDescriptor dup(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor dup2(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static String[] environ();
+    method public static void execv(String, String[]) throws android.system.ErrnoException;
+    method public static void execve(String, String[], String[]) throws android.system.ErrnoException;
+    method public static void fchmod(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static void fchown(java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int fcntlInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static void fdatasync(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStat fstat(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStatVfs fstatvfs(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void fsync(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void ftruncate(java.io.FileDescriptor, long) throws android.system.ErrnoException;
+    method public static String gai_strerror(int);
+    method public static int getegid();
+    method public static String getenv(String);
+    method public static int geteuid();
+    method public static int getgid();
+    method public static java.net.SocketAddress getpeername(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static int getpid();
+    method public static int getppid();
+    method public static java.net.SocketAddress getsockname(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method @NonNull public static android.system.StructTimeval getsockoptTimeval(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int gettid();
+    method public static int getuid();
+    method public static byte[] getxattr(String, String) throws android.system.ErrnoException;
+    method public static String if_indextoname(int);
+    method public static int if_nametoindex(String);
+    method public static java.net.InetAddress inet_pton(int, String);
+    method public static boolean isatty(java.io.FileDescriptor);
+    method public static void kill(int, int) throws android.system.ErrnoException;
+    method public static void lchown(String, int, int) throws android.system.ErrnoException;
+    method public static void link(String, String) throws android.system.ErrnoException;
+    method public static void listen(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static String[] listxattr(String) throws android.system.ErrnoException;
+    method public static long lseek(java.io.FileDescriptor, long, int) throws android.system.ErrnoException;
+    method public static android.system.StructStat lstat(String) throws android.system.ErrnoException;
+    method @NonNull public static java.io.FileDescriptor memfd_create(@NonNull String, int) throws android.system.ErrnoException;
+    method public static void mincore(long, long, byte[]) throws android.system.ErrnoException;
+    method public static void mkdir(String, int) throws android.system.ErrnoException;
+    method public static void mkfifo(String, int) throws android.system.ErrnoException;
+    method public static void mlock(long, long) throws android.system.ErrnoException;
+    method public static long mmap(long, long, int, int, java.io.FileDescriptor, long) throws android.system.ErrnoException;
+    method public static void msync(long, long, int) throws android.system.ErrnoException;
+    method public static void munlock(long, long) throws android.system.ErrnoException;
+    method public static void munmap(long, long) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor open(String, int, int) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor[] pipe() throws android.system.ErrnoException;
+    method public static int poll(android.system.StructPollfd[], int) throws android.system.ErrnoException;
+    method public static void posix_fallocate(java.io.FileDescriptor, long, long) throws android.system.ErrnoException;
+    method public static int prctl(int, long, long, long, long) throws android.system.ErrnoException;
+    method public static int pread(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pread(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pwrite(java.io.FileDescriptor, java.nio.ByteBuffer, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int pwrite(java.io.FileDescriptor, byte[], int, int, long) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int read(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int read(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static String readlink(String) throws android.system.ErrnoException;
+    method public static int readv(java.io.FileDescriptor, Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int recvfrom(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int recvfrom(java.io.FileDescriptor, byte[], int, int, int, java.net.InetSocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int recvmsg(@NonNull java.io.FileDescriptor, @NonNull android.system.StructMsghdr, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static void remove(String) throws android.system.ErrnoException;
+    method public static void removexattr(String, String) throws android.system.ErrnoException;
+    method public static void rename(String, String) throws android.system.ErrnoException;
+    method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
+    method public static int sendmsg(@NonNull java.io.FileDescriptor, @NonNull android.system.StructMsghdr, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
+    method public static int sendto(@NonNull java.io.FileDescriptor, @NonNull byte[], int, int, int, @Nullable java.net.SocketAddress) throws android.system.ErrnoException, java.net.SocketException;
+    method @Deprecated public static void setegid(int) throws android.system.ErrnoException;
+    method public static void setenv(String, String, boolean) throws android.system.ErrnoException;
+    method @Deprecated public static void seteuid(int) throws android.system.ErrnoException;
+    method @Deprecated public static void setgid(int) throws android.system.ErrnoException;
+    method public static int setsid() throws android.system.ErrnoException;
+    method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
+    method public static void setsockoptTimeval(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructTimeval) throws android.system.ErrnoException;
+    method @Deprecated public static void setuid(int) throws android.system.ErrnoException;
+    method public static void setxattr(String, String, byte[], int) throws android.system.ErrnoException;
+    method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static java.io.FileDescriptor socket(int, int, int) throws android.system.ErrnoException;
+    method public static void socketpair(int, int, int, java.io.FileDescriptor, java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static android.system.StructStat stat(String) throws android.system.ErrnoException;
+    method public static android.system.StructStatVfs statvfs(String) throws android.system.ErrnoException;
+    method public static String strerror(int);
+    method public static String strsignal(int);
+    method public static void symlink(String, String) throws android.system.ErrnoException;
+    method public static long sysconf(int);
+    method public static void tcdrain(java.io.FileDescriptor) throws android.system.ErrnoException;
+    method public static void tcsendbreak(java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method public static int umask(int);
+    method public static android.system.StructUtsname uname();
+    method public static void unsetenv(String) throws android.system.ErrnoException;
+    method public static int write(java.io.FileDescriptor, java.nio.ByteBuffer) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int write(java.io.FileDescriptor, byte[], int, int) throws android.system.ErrnoException, java.io.InterruptedIOException;
+    method public static int writev(java.io.FileDescriptor, Object[], int[], int[]) throws android.system.ErrnoException, java.io.InterruptedIOException;
+  }
+
+  public final class OsConstants {
+    method public static boolean S_ISBLK(int);
+    method public static boolean S_ISCHR(int);
+    method public static boolean S_ISDIR(int);
+    method public static boolean S_ISFIFO(int);
+    method public static boolean S_ISLNK(int);
+    method public static boolean S_ISREG(int);
+    method public static boolean S_ISSOCK(int);
+    method public static boolean WCOREDUMP(int);
+    method public static int WEXITSTATUS(int);
+    method public static boolean WIFEXITED(int);
+    method public static boolean WIFSIGNALED(int);
+    method public static boolean WIFSTOPPED(int);
+    method public static int WSTOPSIG(int);
+    method public static int WTERMSIG(int);
+    method public static String errnoName(int);
+    method public static String gaiName(int);
+    field public static final int AF_INET;
+    field public static final int AF_INET6;
+    field public static final int AF_NETLINK;
+    field public static final int AF_PACKET;
+    field public static final int AF_UNIX;
+    field public static final int AF_UNSPEC;
+    field public static final int AF_VSOCK;
+    field public static final int AI_ADDRCONFIG;
+    field public static final int AI_ALL;
+    field public static final int AI_CANONNAME;
+    field public static final int AI_NUMERICHOST;
+    field public static final int AI_NUMERICSERV;
+    field public static final int AI_PASSIVE;
+    field public static final int AI_V4MAPPED;
+    field public static final int ARPHRD_ETHER;
+    field public static final int CAP_AUDIT_CONTROL;
+    field public static final int CAP_AUDIT_WRITE;
+    field public static final int CAP_BLOCK_SUSPEND;
+    field public static final int CAP_CHOWN;
+    field public static final int CAP_DAC_OVERRIDE;
+    field public static final int CAP_DAC_READ_SEARCH;
+    field public static final int CAP_FOWNER;
+    field public static final int CAP_FSETID;
+    field public static final int CAP_IPC_LOCK;
+    field public static final int CAP_IPC_OWNER;
+    field public static final int CAP_KILL;
+    field public static final int CAP_LAST_CAP;
+    field public static final int CAP_LEASE;
+    field public static final int CAP_LINUX_IMMUTABLE;
+    field public static final int CAP_MAC_ADMIN;
+    field public static final int CAP_MAC_OVERRIDE;
+    field public static final int CAP_MKNOD;
+    field public static final int CAP_NET_ADMIN;
+    field public static final int CAP_NET_BIND_SERVICE;
+    field public static final int CAP_NET_BROADCAST;
+    field public static final int CAP_NET_RAW;
+    field public static final int CAP_SETFCAP;
+    field public static final int CAP_SETGID;
+    field public static final int CAP_SETPCAP;
+    field public static final int CAP_SETUID;
+    field public static final int CAP_SYSLOG;
+    field public static final int CAP_SYS_ADMIN;
+    field public static final int CAP_SYS_BOOT;
+    field public static final int CAP_SYS_CHROOT;
+    field public static final int CAP_SYS_MODULE;
+    field public static final int CAP_SYS_NICE;
+    field public static final int CAP_SYS_PACCT;
+    field public static final int CAP_SYS_PTRACE;
+    field public static final int CAP_SYS_RAWIO;
+    field public static final int CAP_SYS_RESOURCE;
+    field public static final int CAP_SYS_TIME;
+    field public static final int CAP_SYS_TTY_CONFIG;
+    field public static final int CAP_WAKE_ALARM;
+    field public static final int E2BIG;
+    field public static final int EACCES;
+    field public static final int EADDRINUSE;
+    field public static final int EADDRNOTAVAIL;
+    field public static final int EAFNOSUPPORT;
+    field public static final int EAGAIN;
+    field public static final int EAI_AGAIN;
+    field public static final int EAI_BADFLAGS;
+    field public static final int EAI_FAIL;
+    field public static final int EAI_FAMILY;
+    field public static final int EAI_MEMORY;
+    field public static final int EAI_NODATA;
+    field public static final int EAI_NONAME;
+    field public static final int EAI_OVERFLOW;
+    field public static final int EAI_SERVICE;
+    field public static final int EAI_SOCKTYPE;
+    field public static final int EAI_SYSTEM;
+    field public static final int EALREADY;
+    field public static final int EBADF;
+    field public static final int EBADMSG;
+    field public static final int EBUSY;
+    field public static final int ECANCELED;
+    field public static final int ECHILD;
+    field public static final int ECONNABORTED;
+    field public static final int ECONNREFUSED;
+    field public static final int ECONNRESET;
+    field public static final int EDEADLK;
+    field public static final int EDESTADDRREQ;
+    field public static final int EDOM;
+    field public static final int EDQUOT;
+    field public static final int EEXIST;
+    field public static final int EFAULT;
+    field public static final int EFBIG;
+    field public static final int EHOSTUNREACH;
+    field public static final int EIDRM;
+    field public static final int EILSEQ;
+    field public static final int EINPROGRESS;
+    field public static final int EINTR;
+    field public static final int EINVAL;
+    field public static final int EIO;
+    field public static final int EISCONN;
+    field public static final int EISDIR;
+    field public static final int ELOOP;
+    field public static final int EMFILE;
+    field public static final int EMLINK;
+    field public static final int EMSGSIZE;
+    field public static final int EMULTIHOP;
+    field public static final int ENAMETOOLONG;
+    field public static final int ENETDOWN;
+    field public static final int ENETRESET;
+    field public static final int ENETUNREACH;
+    field public static final int ENFILE;
+    field public static final int ENOBUFS;
+    field public static final int ENODATA;
+    field public static final int ENODEV;
+    field public static final int ENOENT;
+    field public static final int ENOEXEC;
+    field public static final int ENOLCK;
+    field public static final int ENOLINK;
+    field public static final int ENOMEM;
+    field public static final int ENOMSG;
+    field public static final int ENONET;
+    field public static final int ENOPROTOOPT;
+    field public static final int ENOSPC;
+    field public static final int ENOSR;
+    field public static final int ENOSTR;
+    field public static final int ENOSYS;
+    field public static final int ENOTCONN;
+    field public static final int ENOTDIR;
+    field public static final int ENOTEMPTY;
+    field public static final int ENOTSOCK;
+    field public static final int ENOTSUP;
+    field public static final int ENOTTY;
+    field public static final int ENXIO;
+    field public static final int EOPNOTSUPP;
+    field public static final int EOVERFLOW;
+    field public static final int EPERM;
+    field public static final int EPIPE;
+    field public static final int EPROTO;
+    field public static final int EPROTONOSUPPORT;
+    field public static final int EPROTOTYPE;
+    field public static final int ERANGE;
+    field public static final int EROFS;
+    field public static final int ESPIPE;
+    field public static final int ESRCH;
+    field public static final int ESTALE;
+    field public static final int ETH_P_ALL;
+    field public static final int ETH_P_ARP;
+    field public static final int ETH_P_IP;
+    field public static final int ETH_P_IPV6;
+    field public static final int ETIME;
+    field public static final int ETIMEDOUT;
+    field public static final int ETXTBSY;
+    field public static final int EXDEV;
+    field public static final int EXIT_FAILURE;
+    field public static final int EXIT_SUCCESS;
+    field public static final int FD_CLOEXEC;
+    field public static final int FIONREAD;
+    field public static final int F_DUPFD;
+    field public static final int F_DUPFD_CLOEXEC;
+    field public static final int F_GETFD;
+    field public static final int F_GETFL;
+    field public static final int F_GETLK;
+    field public static final int F_GETLK64;
+    field public static final int F_GETOWN;
+    field public static final int F_OK;
+    field public static final int F_RDLCK;
+    field public static final int F_SETFD;
+    field public static final int F_SETFL;
+    field public static final int F_SETLK;
+    field public static final int F_SETLK64;
+    field public static final int F_SETLKW;
+    field public static final int F_SETLKW64;
+    field public static final int F_SETOWN;
+    field public static final int F_UNLCK;
+    field public static final int F_WRLCK;
+    field public static final int ICMP6_ECHO_REPLY;
+    field public static final int ICMP6_ECHO_REQUEST;
+    field public static final int ICMP_ECHO;
+    field public static final int ICMP_ECHOREPLY;
+    field public static final int IFA_F_DADFAILED;
+    field public static final int IFA_F_DEPRECATED;
+    field public static final int IFA_F_HOMEADDRESS;
+    field public static final int IFA_F_NODAD;
+    field public static final int IFA_F_OPTIMISTIC;
+    field public static final int IFA_F_PERMANENT;
+    field public static final int IFA_F_SECONDARY;
+    field public static final int IFA_F_TEMPORARY;
+    field public static final int IFA_F_TENTATIVE;
+    field public static final int IFF_ALLMULTI;
+    field public static final int IFF_AUTOMEDIA;
+    field public static final int IFF_BROADCAST;
+    field public static final int IFF_DEBUG;
+    field public static final int IFF_DYNAMIC;
+    field public static final int IFF_LOOPBACK;
+    field public static final int IFF_MASTER;
+    field public static final int IFF_MULTICAST;
+    field public static final int IFF_NOARP;
+    field public static final int IFF_NOTRAILERS;
+    field public static final int IFF_POINTOPOINT;
+    field public static final int IFF_PORTSEL;
+    field public static final int IFF_PROMISC;
+    field public static final int IFF_RUNNING;
+    field public static final int IFF_SLAVE;
+    field public static final int IFF_UP;
+    field public static final int IPPROTO_ICMP;
+    field public static final int IPPROTO_ICMPV6;
+    field public static final int IPPROTO_IP;
+    field public static final int IPPROTO_IPV6;
+    field public static final int IPPROTO_RAW;
+    field public static final int IPPROTO_TCP;
+    field public static final int IPPROTO_UDP;
+    field public static final int IPV6_CHECKSUM;
+    field public static final int IPV6_MULTICAST_HOPS;
+    field public static final int IPV6_MULTICAST_IF;
+    field public static final int IPV6_MULTICAST_LOOP;
+    field public static final int IPV6_RECVDSTOPTS;
+    field public static final int IPV6_RECVHOPLIMIT;
+    field public static final int IPV6_RECVHOPOPTS;
+    field public static final int IPV6_RECVPKTINFO;
+    field public static final int IPV6_RECVRTHDR;
+    field public static final int IPV6_RECVTCLASS;
+    field public static final int IPV6_TCLASS;
+    field public static final int IPV6_UNICAST_HOPS;
+    field public static final int IPV6_V6ONLY;
+    field public static final int IP_MULTICAST_IF;
+    field public static final int IP_MULTICAST_LOOP;
+    field public static final int IP_MULTICAST_TTL;
+    field public static final int IP_TOS;
+    field public static final int IP_TTL;
+    field public static final int MAP_ANONYMOUS;
+    field public static final int MAP_FIXED;
+    field public static final int MAP_PRIVATE;
+    field public static final int MAP_SHARED;
+    field public static final int MCAST_BLOCK_SOURCE;
+    field public static final int MCAST_JOIN_GROUP;
+    field public static final int MCAST_JOIN_SOURCE_GROUP;
+    field public static final int MCAST_LEAVE_GROUP;
+    field public static final int MCAST_LEAVE_SOURCE_GROUP;
+    field public static final int MCAST_UNBLOCK_SOURCE;
+    field public static final int MCL_CURRENT;
+    field public static final int MCL_FUTURE;
+    field public static final int MFD_CLOEXEC;
+    field public static final int MSG_CTRUNC;
+    field public static final int MSG_DONTROUTE;
+    field public static final int MSG_EOR;
+    field public static final int MSG_OOB;
+    field public static final int MSG_PEEK;
+    field public static final int MSG_TRUNC;
+    field public static final int MSG_WAITALL;
+    field public static final int MS_ASYNC;
+    field public static final int MS_INVALIDATE;
+    field public static final int MS_SYNC;
+    field public static final int NETLINK_INET_DIAG;
+    field public static final int NETLINK_NETFILTER;
+    field public static final int NETLINK_ROUTE;
+    field public static final int NI_DGRAM;
+    field public static final int NI_NAMEREQD;
+    field public static final int NI_NOFQDN;
+    field public static final int NI_NUMERICHOST;
+    field public static final int NI_NUMERICSERV;
+    field public static final int O_ACCMODE;
+    field public static final int O_APPEND;
+    field public static final int O_CLOEXEC;
+    field public static final int O_CREAT;
+    field public static final int O_DSYNC;
+    field public static final int O_EXCL;
+    field public static final int O_NOCTTY;
+    field public static final int O_NOFOLLOW;
+    field public static final int O_NONBLOCK;
+    field public static final int O_RDONLY;
+    field public static final int O_RDWR;
+    field public static final int O_SYNC;
+    field public static final int O_TRUNC;
+    field public static final int O_WRONLY;
+    field public static final int POLLERR;
+    field public static final int POLLHUP;
+    field public static final int POLLIN;
+    field public static final int POLLNVAL;
+    field public static final int POLLOUT;
+    field public static final int POLLPRI;
+    field public static final int POLLRDBAND;
+    field public static final int POLLRDNORM;
+    field public static final int POLLWRBAND;
+    field public static final int POLLWRNORM;
+    field public static final int PROT_EXEC;
+    field public static final int PROT_NONE;
+    field public static final int PROT_READ;
+    field public static final int PROT_WRITE;
+    field public static final int PR_GET_DUMPABLE;
+    field public static final int PR_SET_DUMPABLE;
+    field public static final int PR_SET_NO_NEW_PRIVS;
+    field public static final int RTMGRP_NEIGH;
+    field public static final int RT_SCOPE_HOST;
+    field public static final int RT_SCOPE_LINK;
+    field public static final int RT_SCOPE_NOWHERE;
+    field public static final int RT_SCOPE_SITE;
+    field public static final int RT_SCOPE_UNIVERSE;
+    field public static final int R_OK;
+    field public static final int SEEK_CUR;
+    field public static final int SEEK_END;
+    field public static final int SEEK_SET;
+    field public static final int SHUT_RD;
+    field public static final int SHUT_RDWR;
+    field public static final int SHUT_WR;
+    field public static final int SIGABRT;
+    field public static final int SIGALRM;
+    field public static final int SIGBUS;
+    field public static final int SIGCHLD;
+    field public static final int SIGCONT;
+    field public static final int SIGFPE;
+    field public static final int SIGHUP;
+    field public static final int SIGILL;
+    field public static final int SIGINT;
+    field public static final int SIGIO;
+    field public static final int SIGKILL;
+    field public static final int SIGPIPE;
+    field public static final int SIGPROF;
+    field public static final int SIGPWR;
+    field public static final int SIGQUIT;
+    field public static final int SIGRTMAX;
+    field public static final int SIGRTMIN;
+    field public static final int SIGSEGV;
+    field public static final int SIGSTKFLT;
+    field public static final int SIGSTOP;
+    field public static final int SIGSYS;
+    field public static final int SIGTERM;
+    field public static final int SIGTRAP;
+    field public static final int SIGTSTP;
+    field public static final int SIGTTIN;
+    field public static final int SIGTTOU;
+    field public static final int SIGURG;
+    field public static final int SIGUSR1;
+    field public static final int SIGUSR2;
+    field public static final int SIGVTALRM;
+    field public static final int SIGWINCH;
+    field public static final int SIGXCPU;
+    field public static final int SIGXFSZ;
+    field public static final int SIOCGIFADDR;
+    field public static final int SIOCGIFBRDADDR;
+    field public static final int SIOCGIFDSTADDR;
+    field public static final int SIOCGIFNETMASK;
+    field public static final int SOCK_CLOEXEC;
+    field public static final int SOCK_DGRAM;
+    field public static final int SOCK_NONBLOCK;
+    field public static final int SOCK_RAW;
+    field public static final int SOCK_SEQPACKET;
+    field public static final int SOCK_STREAM;
+    field public static final int SOL_SOCKET;
+    field public static final int SOL_UDP;
+    field public static final int SO_BINDTODEVICE;
+    field public static final int SO_BROADCAST;
+    field public static final int SO_DEBUG;
+    field public static final int SO_DONTROUTE;
+    field public static final int SO_ERROR;
+    field public static final int SO_KEEPALIVE;
+    field public static final int SO_LINGER;
+    field public static final int SO_OOBINLINE;
+    field public static final int SO_PASSCRED;
+    field public static final int SO_PEERCRED;
+    field public static final int SO_RCVBUF;
+    field public static final int SO_RCVLOWAT;
+    field public static final int SO_RCVTIMEO;
+    field public static final int SO_REUSEADDR;
+    field public static final int SO_SNDBUF;
+    field public static final int SO_SNDLOWAT;
+    field public static final int SO_SNDTIMEO;
+    field public static final int SO_TYPE;
+    field public static final int STDERR_FILENO;
+    field public static final int STDIN_FILENO;
+    field public static final int STDOUT_FILENO;
+    field public static final int ST_MANDLOCK;
+    field public static final int ST_NOATIME;
+    field public static final int ST_NODEV;
+    field public static final int ST_NODIRATIME;
+    field public static final int ST_NOEXEC;
+    field public static final int ST_NOSUID;
+    field public static final int ST_RDONLY;
+    field public static final int ST_RELATIME;
+    field public static final int ST_SYNCHRONOUS;
+    field public static final int S_IFBLK;
+    field public static final int S_IFCHR;
+    field public static final int S_IFDIR;
+    field public static final int S_IFIFO;
+    field public static final int S_IFLNK;
+    field public static final int S_IFMT;
+    field public static final int S_IFREG;
+    field public static final int S_IFSOCK;
+    field public static final int S_IRGRP;
+    field public static final int S_IROTH;
+    field public static final int S_IRUSR;
+    field public static final int S_IRWXG;
+    field public static final int S_IRWXO;
+    field public static final int S_IRWXU;
+    field public static final int S_ISGID;
+    field public static final int S_ISUID;
+    field public static final int S_ISVTX;
+    field public static final int S_IWGRP;
+    field public static final int S_IWOTH;
+    field public static final int S_IWUSR;
+    field public static final int S_IXGRP;
+    field public static final int S_IXOTH;
+    field public static final int S_IXUSR;
+    field public static final int TCP_NODELAY;
+    field public static final int TCP_USER_TIMEOUT;
+    field public static final int UDP_GRO;
+    field public static final int UDP_SEGMENT;
+    field public static final int VMADDR_CID_ANY;
+    field public static final int VMADDR_CID_HOST;
+    field public static final int VMADDR_CID_LOCAL;
+    field public static final int VMADDR_PORT_ANY;
+    field public static final int WCONTINUED;
+    field public static final int WEXITED;
+    field public static final int WNOHANG;
+    field public static final int WNOWAIT;
+    field public static final int WSTOPPED;
+    field public static final int WUNTRACED;
+    field public static final int W_OK;
+    field public static final int X_OK;
+    field public static final int _SC_2_CHAR_TERM;
+    field public static final int _SC_2_C_BIND;
+    field public static final int _SC_2_C_DEV;
+    field public static final int _SC_2_C_VERSION;
+    field public static final int _SC_2_FORT_DEV;
+    field public static final int _SC_2_FORT_RUN;
+    field public static final int _SC_2_LOCALEDEF;
+    field public static final int _SC_2_SW_DEV;
+    field public static final int _SC_2_UPE;
+    field public static final int _SC_2_VERSION;
+    field public static final int _SC_AIO_LISTIO_MAX;
+    field public static final int _SC_AIO_MAX;
+    field public static final int _SC_AIO_PRIO_DELTA_MAX;
+    field public static final int _SC_ARG_MAX;
+    field public static final int _SC_ASYNCHRONOUS_IO;
+    field public static final int _SC_ATEXIT_MAX;
+    field public static final int _SC_AVPHYS_PAGES;
+    field public static final int _SC_BC_BASE_MAX;
+    field public static final int _SC_BC_DIM_MAX;
+    field public static final int _SC_BC_SCALE_MAX;
+    field public static final int _SC_BC_STRING_MAX;
+    field public static final int _SC_CHILD_MAX;
+    field public static final int _SC_CLK_TCK;
+    field public static final int _SC_COLL_WEIGHTS_MAX;
+    field public static final int _SC_DELAYTIMER_MAX;
+    field public static final int _SC_EXPR_NEST_MAX;
+    field public static final int _SC_FSYNC;
+    field public static final int _SC_GETGR_R_SIZE_MAX;
+    field public static final int _SC_GETPW_R_SIZE_MAX;
+    field public static final int _SC_IOV_MAX;
+    field public static final int _SC_JOB_CONTROL;
+    field public static final int _SC_LINE_MAX;
+    field public static final int _SC_LOGIN_NAME_MAX;
+    field public static final int _SC_MAPPED_FILES;
+    field public static final int _SC_MEMLOCK;
+    field public static final int _SC_MEMLOCK_RANGE;
+    field public static final int _SC_MEMORY_PROTECTION;
+    field public static final int _SC_MESSAGE_PASSING;
+    field public static final int _SC_MQ_OPEN_MAX;
+    field public static final int _SC_MQ_PRIO_MAX;
+    field public static final int _SC_NGROUPS_MAX;
+    field public static final int _SC_NPROCESSORS_CONF;
+    field public static final int _SC_NPROCESSORS_ONLN;
+    field public static final int _SC_OPEN_MAX;
+    field public static final int _SC_PAGESIZE;
+    field public static final int _SC_PAGE_SIZE;
+    field public static final int _SC_PASS_MAX;
+    field public static final int _SC_PHYS_PAGES;
+    field public static final int _SC_PRIORITIZED_IO;
+    field public static final int _SC_PRIORITY_SCHEDULING;
+    field public static final int _SC_REALTIME_SIGNALS;
+    field public static final int _SC_RE_DUP_MAX;
+    field public static final int _SC_RTSIG_MAX;
+    field public static final int _SC_SAVED_IDS;
+    field public static final int _SC_SEMAPHORES;
+    field public static final int _SC_SEM_NSEMS_MAX;
+    field public static final int _SC_SEM_VALUE_MAX;
+    field public static final int _SC_SHARED_MEMORY_OBJECTS;
+    field public static final int _SC_SIGQUEUE_MAX;
+    field public static final int _SC_STREAM_MAX;
+    field public static final int _SC_SYNCHRONIZED_IO;
+    field public static final int _SC_THREADS;
+    field public static final int _SC_THREAD_ATTR_STACKADDR;
+    field public static final int _SC_THREAD_ATTR_STACKSIZE;
+    field public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS;
+    field public static final int _SC_THREAD_KEYS_MAX;
+    field public static final int _SC_THREAD_PRIORITY_SCHEDULING;
+    field public static final int _SC_THREAD_PRIO_INHERIT;
+    field public static final int _SC_THREAD_PRIO_PROTECT;
+    field public static final int _SC_THREAD_SAFE_FUNCTIONS;
+    field public static final int _SC_THREAD_STACK_MIN;
+    field public static final int _SC_THREAD_THREADS_MAX;
+    field public static final int _SC_TIMERS;
+    field public static final int _SC_TIMER_MAX;
+    field public static final int _SC_TTY_NAME_MAX;
+    field public static final int _SC_TZNAME_MAX;
+    field public static final int _SC_VERSION;
+    field public static final int _SC_XBS5_ILP32_OFF32;
+    field public static final int _SC_XBS5_ILP32_OFFBIG;
+    field public static final int _SC_XBS5_LP64_OFF64;
+    field public static final int _SC_XBS5_LPBIG_OFFBIG;
+    field public static final int _SC_XOPEN_CRYPT;
+    field public static final int _SC_XOPEN_ENH_I18N;
+    field public static final int _SC_XOPEN_LEGACY;
+    field public static final int _SC_XOPEN_REALTIME;
+    field public static final int _SC_XOPEN_REALTIME_THREADS;
+    field public static final int _SC_XOPEN_SHM;
+    field public static final int _SC_XOPEN_UNIX;
+    field public static final int _SC_XOPEN_VERSION;
+    field public static final int _SC_XOPEN_XCU_VERSION;
+  }
+
+  public final class StructCmsghdr {
+    ctor public StructCmsghdr(int, int, short);
+    ctor public StructCmsghdr(int, int, @NonNull byte[]);
+    field @NonNull public final byte[] cmsg_data;
+    field public final int cmsg_level;
+    field public final int cmsg_type;
+  }
+
+  public final class StructMsghdr {
+    ctor public StructMsghdr(@Nullable java.net.SocketAddress, @NonNull java.nio.ByteBuffer[], @Nullable android.system.StructCmsghdr[], int);
+    field @Nullable public android.system.StructCmsghdr[] msg_control;
+    field public int msg_flags;
+    field @NonNull public final java.nio.ByteBuffer[] msg_iov;
+    field @Nullable public java.net.SocketAddress msg_name;
+  }
+
+  public final class StructPollfd {
+    ctor public StructPollfd();
+    field public short events;
+    field public java.io.FileDescriptor fd;
+    field public short revents;
+    field public Object userData;
+  }
+
+  public final class StructStat {
+    ctor public StructStat(long, long, int, long, int, int, long, long, long, long, long, long, long);
+    ctor public StructStat(long, long, int, long, int, int, long, long, android.system.StructTimespec, android.system.StructTimespec, android.system.StructTimespec, long, long);
+    field public final android.system.StructTimespec st_atim;
+    field public final long st_atime;
+    field public final long st_blksize;
+    field public final long st_blocks;
+    field public final android.system.StructTimespec st_ctim;
+    field public final long st_ctime;
+    field public final long st_dev;
+    field public final int st_gid;
+    field public final long st_ino;
+    field public final int st_mode;
+    field public final android.system.StructTimespec st_mtim;
+    field public final long st_mtime;
+    field public final long st_nlink;
+    field public final long st_rdev;
+    field public final long st_size;
+    field public final int st_uid;
+  }
+
+  public final class StructStatVfs {
+    ctor public StructStatVfs(long, long, long, long, long, long, long, long, long, long, long);
+    field public final long f_bavail;
+    field public final long f_bfree;
+    field public final long f_blocks;
+    field public final long f_bsize;
+    field public final long f_favail;
+    field public final long f_ffree;
+    field public final long f_files;
+    field public final long f_flag;
+    field public final long f_frsize;
+    field public final long f_fsid;
+    field public final long f_namemax;
+  }
+
+  public final class StructTimespec implements java.lang.Comparable<android.system.StructTimespec> {
+    ctor public StructTimespec(long, long);
+    method public int compareTo(android.system.StructTimespec);
+    field public final long tv_nsec;
+    field public final long tv_sec;
+  }
+
+  public final class StructTimeval {
+    method @NonNull public static android.system.StructTimeval fromMillis(long);
+    method public long toMillis();
+    field public final long tv_sec;
+    field public final long tv_usec;
+  }
+
+  public final class StructUtsname {
+    ctor public StructUtsname(String, String, String, String, String);
+    field public final String machine;
+    field public final String nodename;
+    field public final String release;
+    field public final String sysname;
+    field public final String version;
+  }
+
+}
+
+package dalvik.annotation {
+
+  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.ANNOTATION_TYPE}) public @interface TestTarget {
+    method @Deprecated public abstract String conceptName() default "";
+    method @Deprecated public abstract Class<?>[] methodArgs() default {};
+    method @Deprecated public abstract String methodName() default "";
+  }
+
+  @Deprecated @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE}) public @interface TestTargetClass {
+    method @Deprecated public abstract Class<?> value();
+  }
+
+}
+
+package dalvik.bytecode {
+
+  public final class OpcodeInfo {
+    field public static final int MAXIMUM_PACKED_VALUE;
+    field public static final int MAXIMUM_VALUE;
+  }
+
+  public interface Opcodes {
+    field public static final int OP_ADD_DOUBLE = 171; // 0xab
+    field public static final int OP_ADD_DOUBLE_2ADDR = 203; // 0xcb
+    field public static final int OP_ADD_FLOAT = 166; // 0xa6
+    field public static final int OP_ADD_FLOAT_2ADDR = 198; // 0xc6
+    field public static final int OP_ADD_INT = 144; // 0x90
+    field public static final int OP_ADD_INT_2ADDR = 176; // 0xb0
+    field public static final int OP_ADD_INT_LIT16 = 208; // 0xd0
+    field public static final int OP_ADD_INT_LIT8 = 216; // 0xd8
+    field public static final int OP_ADD_LONG = 155; // 0x9b
+    field public static final int OP_ADD_LONG_2ADDR = 187; // 0xbb
+    field public static final int OP_AGET = 68; // 0x44
+    field public static final int OP_AGET_BOOLEAN = 71; // 0x47
+    field public static final int OP_AGET_BYTE = 72; // 0x48
+    field public static final int OP_AGET_CHAR = 73; // 0x49
+    field public static final int OP_AGET_OBJECT = 70; // 0x46
+    field public static final int OP_AGET_SHORT = 74; // 0x4a
+    field public static final int OP_AGET_WIDE = 69; // 0x45
+    field public static final int OP_AND_INT = 149; // 0x95
+    field public static final int OP_AND_INT_2ADDR = 181; // 0xb5
+    field public static final int OP_AND_INT_LIT16 = 213; // 0xd5
+    field public static final int OP_AND_INT_LIT8 = 221; // 0xdd
+    field public static final int OP_AND_LONG = 160; // 0xa0
+    field public static final int OP_AND_LONG_2ADDR = 192; // 0xc0
+    field public static final int OP_APUT = 75; // 0x4b
+    field public static final int OP_APUT_BOOLEAN = 78; // 0x4e
+    field public static final int OP_APUT_BYTE = 79; // 0x4f
+    field public static final int OP_APUT_CHAR = 80; // 0x50
+    field public static final int OP_APUT_OBJECT = 77; // 0x4d
+    field public static final int OP_APUT_SHORT = 81; // 0x51
+    field public static final int OP_APUT_WIDE = 76; // 0x4c
+    field public static final int OP_ARRAY_LENGTH = 33; // 0x21
+    field @Deprecated public static final int OP_BREAKPOINT = 236; // 0xec
+    field public static final int OP_CHECK_CAST = 31; // 0x1f
+    field public static final int OP_CHECK_CAST_JUMBO = 511; // 0x1ff
+    field public static final int OP_CMPG_DOUBLE = 48; // 0x30
+    field public static final int OP_CMPG_FLOAT = 46; // 0x2e
+    field public static final int OP_CMPL_DOUBLE = 47; // 0x2f
+    field public static final int OP_CMPL_FLOAT = 45; // 0x2d
+    field public static final int OP_CMP_LONG = 49; // 0x31
+    field public static final int OP_CONST = 20; // 0x14
+    field public static final int OP_CONST_16 = 19; // 0x13
+    field public static final int OP_CONST_4 = 18; // 0x12
+    field public static final int OP_CONST_CLASS = 28; // 0x1c
+    field public static final int OP_CONST_CLASS_JUMBO = 255; // 0xff
+    field public static final int OP_CONST_HIGH16 = 21; // 0x15
+    field public static final int OP_CONST_METHOD_HANDLE = 254; // 0xfe
+    field public static final int OP_CONST_METHOD_TYPE = 255; // 0xff
+    field public static final int OP_CONST_STRING = 26; // 0x1a
+    field public static final int OP_CONST_STRING_JUMBO = 27; // 0x1b
+    field public static final int OP_CONST_WIDE = 24; // 0x18
+    field public static final int OP_CONST_WIDE_16 = 22; // 0x16
+    field public static final int OP_CONST_WIDE_32 = 23; // 0x17
+    field public static final int OP_CONST_WIDE_HIGH16 = 25; // 0x19
+    field public static final int OP_DIV_DOUBLE = 174; // 0xae
+    field public static final int OP_DIV_DOUBLE_2ADDR = 206; // 0xce
+    field public static final int OP_DIV_FLOAT = 169; // 0xa9
+    field public static final int OP_DIV_FLOAT_2ADDR = 201; // 0xc9
+    field public static final int OP_DIV_INT = 147; // 0x93
+    field public static final int OP_DIV_INT_2ADDR = 179; // 0xb3
+    field public static final int OP_DIV_INT_LIT16 = 211; // 0xd3
+    field public static final int OP_DIV_INT_LIT8 = 219; // 0xdb
+    field public static final int OP_DIV_LONG = 158; // 0x9e
+    field public static final int OP_DIV_LONG_2ADDR = 190; // 0xbe
+    field public static final int OP_DOUBLE_TO_FLOAT = 140; // 0x8c
+    field public static final int OP_DOUBLE_TO_INT = 138; // 0x8a
+    field public static final int OP_DOUBLE_TO_LONG = 139; // 0x8b
+    field @Deprecated public static final int OP_EXECUTE_INLINE = 238; // 0xee
+    field @Deprecated public static final int OP_EXECUTE_INLINE_RANGE = 239; // 0xef
+    field public static final int OP_FILLED_NEW_ARRAY = 36; // 0x24
+    field public static final int OP_FILLED_NEW_ARRAY_JUMBO = 1535; // 0x5ff
+    field public static final int OP_FILLED_NEW_ARRAY_RANGE = 37; // 0x25
+    field public static final int OP_FILL_ARRAY_DATA = 38; // 0x26
+    field public static final int OP_FLOAT_TO_DOUBLE = 137; // 0x89
+    field public static final int OP_FLOAT_TO_INT = 135; // 0x87
+    field public static final int OP_FLOAT_TO_LONG = 136; // 0x88
+    field public static final int OP_GOTO = 40; // 0x28
+    field public static final int OP_GOTO_16 = 41; // 0x29
+    field public static final int OP_GOTO_32 = 42; // 0x2a
+    field public static final int OP_IF_EQ = 50; // 0x32
+    field public static final int OP_IF_EQZ = 56; // 0x38
+    field public static final int OP_IF_GE = 53; // 0x35
+    field public static final int OP_IF_GEZ = 59; // 0x3b
+    field public static final int OP_IF_GT = 54; // 0x36
+    field public static final int OP_IF_GTZ = 60; // 0x3c
+    field public static final int OP_IF_LE = 55; // 0x37
+    field public static final int OP_IF_LEZ = 61; // 0x3d
+    field public static final int OP_IF_LT = 52; // 0x34
+    field public static final int OP_IF_LTZ = 58; // 0x3a
+    field public static final int OP_IF_NE = 51; // 0x33
+    field public static final int OP_IF_NEZ = 57; // 0x39
+    field public static final int OP_IGET = 82; // 0x52
+    field public static final int OP_IGET_BOOLEAN = 85; // 0x55
+    field public static final int OP_IGET_BOOLEAN_JUMBO = 2559; // 0x9ff
+    field public static final int OP_IGET_BYTE = 86; // 0x56
+    field public static final int OP_IGET_BYTE_JUMBO = 2815; // 0xaff
+    field public static final int OP_IGET_CHAR = 87; // 0x57
+    field public static final int OP_IGET_CHAR_JUMBO = 3071; // 0xbff
+    field public static final int OP_IGET_JUMBO = 1791; // 0x6ff
+    field public static final int OP_IGET_OBJECT = 84; // 0x54
+    field public static final int OP_IGET_OBJECT_JUMBO = 2303; // 0x8ff
+    field @Deprecated public static final int OP_IGET_OBJECT_QUICK = 244; // 0xf4
+    field @Deprecated public static final int OP_IGET_QUICK = 242; // 0xf2
+    field public static final int OP_IGET_SHORT = 88; // 0x58
+    field public static final int OP_IGET_SHORT_JUMBO = 3327; // 0xcff
+    field public static final int OP_IGET_WIDE = 83; // 0x53
+    field public static final int OP_IGET_WIDE_JUMBO = 2047; // 0x7ff
+    field @Deprecated public static final int OP_IGET_WIDE_QUICK = 243; // 0xf3
+    field @Deprecated public static final int OP_IGET_WIDE_VOLATILE = 232; // 0xe8
+    field public static final int OP_INSTANCE_OF = 32; // 0x20
+    field public static final int OP_INSTANCE_OF_JUMBO = 767; // 0x2ff
+    field public static final int OP_INT_TO_BYTE = 141; // 0x8d
+    field public static final int OP_INT_TO_CHAR = 142; // 0x8e
+    field public static final int OP_INT_TO_DOUBLE = 131; // 0x83
+    field public static final int OP_INT_TO_FLOAT = 130; // 0x82
+    field public static final int OP_INT_TO_LONG = 129; // 0x81
+    field public static final int OP_INT_TO_SHORT = 143; // 0x8f
+    field public static final int OP_INVOKE_CUSTOM = 252; // 0xfc
+    field public static final int OP_INVOKE_CUSTOM_RANGE = 253; // 0xfd
+    field public static final int OP_INVOKE_DIRECT = 112; // 0x70
+    field @Deprecated public static final int OP_INVOKE_DIRECT_EMPTY = 240; // 0xf0
+    field public static final int OP_INVOKE_DIRECT_JUMBO = 9471; // 0x24ff
+    field public static final int OP_INVOKE_DIRECT_RANGE = 118; // 0x76
+    field public static final int OP_INVOKE_INTERFACE = 114; // 0x72
+    field public static final int OP_INVOKE_INTERFACE_JUMBO = 9983; // 0x26ff
+    field public static final int OP_INVOKE_INTERFACE_RANGE = 120; // 0x78
+    field public static final int OP_INVOKE_POLYMORPHIC = 250; // 0xfa
+    field public static final int OP_INVOKE_POLYMORPHIC_RANGE = 251; // 0xfb
+    field public static final int OP_INVOKE_STATIC = 113; // 0x71
+    field public static final int OP_INVOKE_STATIC_JUMBO = 9727; // 0x25ff
+    field public static final int OP_INVOKE_STATIC_RANGE = 119; // 0x77
+    field public static final int OP_INVOKE_SUPER = 111; // 0x6f
+    field public static final int OP_INVOKE_SUPER_JUMBO = 9215; // 0x23ff
+    field @Deprecated public static final int OP_INVOKE_SUPER_QUICK = 250; // 0xfa
+    field @Deprecated public static final int OP_INVOKE_SUPER_QUICK_RANGE = 251; // 0xfb
+    field public static final int OP_INVOKE_SUPER_RANGE = 117; // 0x75
+    field public static final int OP_INVOKE_VIRTUAL = 110; // 0x6e
+    field public static final int OP_INVOKE_VIRTUAL_JUMBO = 8959; // 0x22ff
+    field @Deprecated public static final int OP_INVOKE_VIRTUAL_QUICK = 248; // 0xf8
+    field @Deprecated public static final int OP_INVOKE_VIRTUAL_QUICK_RANGE = 249; // 0xf9
+    field public static final int OP_INVOKE_VIRTUAL_RANGE = 116; // 0x74
+    field public static final int OP_IPUT = 89; // 0x59
+    field public static final int OP_IPUT_BOOLEAN = 92; // 0x5c
+    field public static final int OP_IPUT_BOOLEAN_JUMBO = 4351; // 0x10ff
+    field public static final int OP_IPUT_BYTE = 93; // 0x5d
+    field public static final int OP_IPUT_BYTE_JUMBO = 4607; // 0x11ff
+    field public static final int OP_IPUT_CHAR = 94; // 0x5e
+    field public static final int OP_IPUT_CHAR_JUMBO = 4863; // 0x12ff
+    field public static final int OP_IPUT_JUMBO = 3583; // 0xdff
+    field public static final int OP_IPUT_OBJECT = 91; // 0x5b
+    field public static final int OP_IPUT_OBJECT_JUMBO = 4095; // 0xfff
+    field @Deprecated public static final int OP_IPUT_OBJECT_QUICK = 247; // 0xf7
+    field @Deprecated public static final int OP_IPUT_QUICK = 245; // 0xf5
+    field public static final int OP_IPUT_SHORT = 95; // 0x5f
+    field public static final int OP_IPUT_SHORT_JUMBO = 5119; // 0x13ff
+    field public static final int OP_IPUT_WIDE = 90; // 0x5a
+    field public static final int OP_IPUT_WIDE_JUMBO = 3839; // 0xeff
+    field @Deprecated public static final int OP_IPUT_WIDE_QUICK = 246; // 0xf6
+    field @Deprecated public static final int OP_IPUT_WIDE_VOLATILE = 233; // 0xe9
+    field public static final int OP_LONG_TO_DOUBLE = 134; // 0x86
+    field public static final int OP_LONG_TO_FLOAT = 133; // 0x85
+    field public static final int OP_LONG_TO_INT = 132; // 0x84
+    field public static final int OP_MONITOR_ENTER = 29; // 0x1d
+    field public static final int OP_MONITOR_EXIT = 30; // 0x1e
+    field public static final int OP_MOVE = 1; // 0x1
+    field public static final int OP_MOVE_16 = 3; // 0x3
+    field public static final int OP_MOVE_EXCEPTION = 13; // 0xd
+    field public static final int OP_MOVE_FROM16 = 2; // 0x2
+    field public static final int OP_MOVE_OBJECT = 7; // 0x7
+    field public static final int OP_MOVE_OBJECT_16 = 9; // 0x9
+    field public static final int OP_MOVE_OBJECT_FROM16 = 8; // 0x8
+    field public static final int OP_MOVE_RESULT = 10; // 0xa
+    field public static final int OP_MOVE_RESULT_OBJECT = 12; // 0xc
+    field public static final int OP_MOVE_RESULT_WIDE = 11; // 0xb
+    field public static final int OP_MOVE_WIDE = 4; // 0x4
+    field public static final int OP_MOVE_WIDE_16 = 6; // 0x6
+    field public static final int OP_MOVE_WIDE_FROM16 = 5; // 0x5
+    field public static final int OP_MUL_DOUBLE = 173; // 0xad
+    field public static final int OP_MUL_DOUBLE_2ADDR = 205; // 0xcd
+    field public static final int OP_MUL_FLOAT = 168; // 0xa8
+    field public static final int OP_MUL_FLOAT_2ADDR = 200; // 0xc8
+    field public static final int OP_MUL_INT = 146; // 0x92
+    field public static final int OP_MUL_INT_2ADDR = 178; // 0xb2
+    field public static final int OP_MUL_INT_LIT16 = 210; // 0xd2
+    field public static final int OP_MUL_INT_LIT8 = 218; // 0xda
+    field public static final int OP_MUL_LONG = 157; // 0x9d
+    field public static final int OP_MUL_LONG_2ADDR = 189; // 0xbd
+    field public static final int OP_NEG_DOUBLE = 128; // 0x80
+    field public static final int OP_NEG_FLOAT = 127; // 0x7f
+    field public static final int OP_NEG_INT = 123; // 0x7b
+    field public static final int OP_NEG_LONG = 125; // 0x7d
+    field public static final int OP_NEW_ARRAY = 35; // 0x23
+    field public static final int OP_NEW_ARRAY_JUMBO = 1279; // 0x4ff
+    field public static final int OP_NEW_INSTANCE = 34; // 0x22
+    field public static final int OP_NEW_INSTANCE_JUMBO = 1023; // 0x3ff
+    field public static final int OP_NOP = 0; // 0x0
+    field public static final int OP_NOT_INT = 124; // 0x7c
+    field public static final int OP_NOT_LONG = 126; // 0x7e
+    field public static final int OP_OR_INT = 150; // 0x96
+    field public static final int OP_OR_INT_2ADDR = 182; // 0xb6
+    field public static final int OP_OR_INT_LIT16 = 214; // 0xd6
+    field public static final int OP_OR_INT_LIT8 = 222; // 0xde
+    field public static final int OP_OR_LONG = 161; // 0xa1
+    field public static final int OP_OR_LONG_2ADDR = 193; // 0xc1
+    field public static final int OP_PACKED_SWITCH = 43; // 0x2b
+    field public static final int OP_REM_DOUBLE = 175; // 0xaf
+    field public static final int OP_REM_DOUBLE_2ADDR = 207; // 0xcf
+    field public static final int OP_REM_FLOAT = 170; // 0xaa
+    field public static final int OP_REM_FLOAT_2ADDR = 202; // 0xca
+    field public static final int OP_REM_INT = 148; // 0x94
+    field public static final int OP_REM_INT_2ADDR = 180; // 0xb4
+    field public static final int OP_REM_INT_LIT16 = 212; // 0xd4
+    field public static final int OP_REM_INT_LIT8 = 220; // 0xdc
+    field public static final int OP_REM_LONG = 159; // 0x9f
+    field public static final int OP_REM_LONG_2ADDR = 191; // 0xbf
+    field public static final int OP_RETURN = 15; // 0xf
+    field public static final int OP_RETURN_OBJECT = 17; // 0x11
+    field public static final int OP_RETURN_VOID = 14; // 0xe
+    field public static final int OP_RETURN_WIDE = 16; // 0x10
+    field public static final int OP_RSUB_INT = 209; // 0xd1
+    field public static final int OP_RSUB_INT_LIT8 = 217; // 0xd9
+    field public static final int OP_SGET = 96; // 0x60
+    field public static final int OP_SGET_BOOLEAN = 99; // 0x63
+    field public static final int OP_SGET_BOOLEAN_JUMBO = 6143; // 0x17ff
+    field public static final int OP_SGET_BYTE = 100; // 0x64
+    field public static final int OP_SGET_BYTE_JUMBO = 6399; // 0x18ff
+    field public static final int OP_SGET_CHAR = 101; // 0x65
+    field public static final int OP_SGET_CHAR_JUMBO = 6655; // 0x19ff
+    field public static final int OP_SGET_JUMBO = 5375; // 0x14ff
+    field public static final int OP_SGET_OBJECT = 98; // 0x62
+    field public static final int OP_SGET_OBJECT_JUMBO = 5887; // 0x16ff
+    field public static final int OP_SGET_SHORT = 102; // 0x66
+    field public static final int OP_SGET_SHORT_JUMBO = 6911; // 0x1aff
+    field public static final int OP_SGET_WIDE = 97; // 0x61
+    field public static final int OP_SGET_WIDE_JUMBO = 5631; // 0x15ff
+    field @Deprecated public static final int OP_SGET_WIDE_VOLATILE = 234; // 0xea
+    field public static final int OP_SHL_INT = 152; // 0x98
+    field public static final int OP_SHL_INT_2ADDR = 184; // 0xb8
+    field public static final int OP_SHL_INT_LIT8 = 224; // 0xe0
+    field public static final int OP_SHL_LONG = 163; // 0xa3
+    field public static final int OP_SHL_LONG_2ADDR = 195; // 0xc3
+    field public static final int OP_SHR_INT = 153; // 0x99
+    field public static final int OP_SHR_INT_2ADDR = 185; // 0xb9
+    field public static final int OP_SHR_INT_LIT8 = 225; // 0xe1
+    field public static final int OP_SHR_LONG = 164; // 0xa4
+    field public static final int OP_SHR_LONG_2ADDR = 196; // 0xc4
+    field public static final int OP_SPARSE_SWITCH = 44; // 0x2c
+    field public static final int OP_SPUT = 103; // 0x67
+    field public static final int OP_SPUT_BOOLEAN = 106; // 0x6a
+    field public static final int OP_SPUT_BOOLEAN_JUMBO = 7935; // 0x1eff
+    field public static final int OP_SPUT_BYTE = 107; // 0x6b
+    field public static final int OP_SPUT_BYTE_JUMBO = 8191; // 0x1fff
+    field public static final int OP_SPUT_CHAR = 108; // 0x6c
+    field public static final int OP_SPUT_CHAR_JUMBO = 8447; // 0x20ff
+    field public static final int OP_SPUT_JUMBO = 7167; // 0x1bff
+    field public static final int OP_SPUT_OBJECT = 105; // 0x69
+    field public static final int OP_SPUT_OBJECT_JUMBO = 7679; // 0x1dff
+    field public static final int OP_SPUT_SHORT = 109; // 0x6d
+    field public static final int OP_SPUT_SHORT_JUMBO = 8703; // 0x21ff
+    field public static final int OP_SPUT_WIDE = 104; // 0x68
+    field public static final int OP_SPUT_WIDE_JUMBO = 7423; // 0x1cff
+    field @Deprecated public static final int OP_SPUT_WIDE_VOLATILE = 235; // 0xeb
+    field public static final int OP_SUB_DOUBLE = 172; // 0xac
+    field public static final int OP_SUB_DOUBLE_2ADDR = 204; // 0xcc
+    field public static final int OP_SUB_FLOAT = 167; // 0xa7
+    field public static final int OP_SUB_FLOAT_2ADDR = 199; // 0xc7
+    field public static final int OP_SUB_INT = 145; // 0x91
+    field public static final int OP_SUB_INT_2ADDR = 177; // 0xb1
+    field public static final int OP_SUB_LONG = 156; // 0x9c
+    field public static final int OP_SUB_LONG_2ADDR = 188; // 0xbc
+    field public static final int OP_THROW = 39; // 0x27
+    field @Deprecated public static final int OP_THROW_VERIFICATION_ERROR = 237; // 0xed
+    field public static final int OP_USHR_INT = 154; // 0x9a
+    field public static final int OP_USHR_INT_2ADDR = 186; // 0xba
+    field public static final int OP_USHR_INT_LIT8 = 226; // 0xe2
+    field public static final int OP_USHR_LONG = 165; // 0xa5
+    field public static final int OP_USHR_LONG_2ADDR = 197; // 0xc5
+    field public static final int OP_XOR_INT = 151; // 0x97
+    field public static final int OP_XOR_INT_2ADDR = 183; // 0xb7
+    field public static final int OP_XOR_INT_LIT16 = 215; // 0xd7
+    field public static final int OP_XOR_INT_LIT8 = 223; // 0xdf
+    field public static final int OP_XOR_LONG = 162; // 0xa2
+    field public static final int OP_XOR_LONG_2ADDR = 194; // 0xc2
+  }
+
+}
+
+package dalvik.system {
+
+  public class BaseDexClassLoader extends java.lang.ClassLoader {
+    ctor public BaseDexClassLoader(String, java.io.File, String, ClassLoader);
+    method public String findLibrary(String);
+    method protected java.util.Enumeration<java.net.URL> findResources(String);
+  }
+
+  public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+    ctor public DelegateLastClassLoader(String, ClassLoader);
+    ctor public DelegateLastClassLoader(String, String, ClassLoader);
+    ctor public DelegateLastClassLoader(@NonNull String, @Nullable String, @Nullable ClassLoader, boolean);
+  }
+
+  public class DexClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public DexClassLoader(String, String, String, 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 String getName();
+    method @Deprecated public static boolean isDexOptNeeded(String) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated public Class loadClass(String, ClassLoader);
+    method @Deprecated public static dalvik.system.DexFile loadDex(String, String, int) throws java.io.IOException;
+  }
+
+  public final class InMemoryDexClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer[], @Nullable String, @Nullable ClassLoader);
+    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer[], @Nullable ClassLoader);
+    ctor public InMemoryDexClassLoader(@NonNull java.nio.ByteBuffer, @Nullable ClassLoader);
+  }
+
+  public class PathClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public PathClassLoader(String, ClassLoader);
+    ctor public PathClassLoader(String, String, ClassLoader);
+  }
+
+}
+
+package java.awt.font {
+
+  public final class NumericShaper implements java.io.Serializable {
+    method public static java.awt.font.NumericShaper getContextualShaper(int);
+    method public static java.awt.font.NumericShaper getContextualShaper(java.util.Set<java.awt.font.NumericShaper.Range>);
+    method public static java.awt.font.NumericShaper getContextualShaper(int, int);
+    method public static java.awt.font.NumericShaper getContextualShaper(java.util.Set<java.awt.font.NumericShaper.Range>, java.awt.font.NumericShaper.Range);
+    method public java.util.Set<java.awt.font.NumericShaper.Range> getRangeSet();
+    method public int getRanges();
+    method public static java.awt.font.NumericShaper getShaper(int);
+    method public static java.awt.font.NumericShaper getShaper(java.awt.font.NumericShaper.Range);
+    method public boolean isContextual();
+    method public void shape(char[], int, int);
+    method public void shape(char[], int, int, int);
+    method public void shape(char[], int, int, java.awt.font.NumericShaper.Range);
+    field public static final int ALL_RANGES = 524287; // 0x7ffff
+    field public static final int ARABIC = 2; // 0x2
+    field public static final int BENGALI = 16; // 0x10
+    field public static final int DEVANAGARI = 8; // 0x8
+    field public static final int EASTERN_ARABIC = 4; // 0x4
+    field public static final int ETHIOPIC = 65536; // 0x10000
+    field public static final int EUROPEAN = 1; // 0x1
+    field public static final int GUJARATI = 64; // 0x40
+    field public static final int GURMUKHI = 32; // 0x20
+    field public static final int KANNADA = 1024; // 0x400
+    field public static final int KHMER = 131072; // 0x20000
+    field public static final int LAO = 8192; // 0x2000
+    field public static final int MALAYALAM = 2048; // 0x800
+    field public static final int MONGOLIAN = 262144; // 0x40000
+    field public static final int MYANMAR = 32768; // 0x8000
+    field public static final int ORIYA = 128; // 0x80
+    field public static final int TAMIL = 256; // 0x100
+    field public static final int TELUGU = 512; // 0x200
+    field public static final int THAI = 4096; // 0x1000
+    field public static final int TIBETAN = 16384; // 0x4000
+  }
+
+  public enum NumericShaper.Range {
+    enum_constant public static final java.awt.font.NumericShaper.Range ARABIC;
+    enum_constant public static final java.awt.font.NumericShaper.Range BALINESE;
+    enum_constant public static final java.awt.font.NumericShaper.Range BENGALI;
+    enum_constant public static final java.awt.font.NumericShaper.Range CHAM;
+    enum_constant public static final java.awt.font.NumericShaper.Range DEVANAGARI;
+    enum_constant public static final java.awt.font.NumericShaper.Range EASTERN_ARABIC;
+    enum_constant public static final java.awt.font.NumericShaper.Range ETHIOPIC;
+    enum_constant public static final java.awt.font.NumericShaper.Range EUROPEAN;
+    enum_constant public static final java.awt.font.NumericShaper.Range GUJARATI;
+    enum_constant public static final java.awt.font.NumericShaper.Range GURMUKHI;
+    enum_constant public static final java.awt.font.NumericShaper.Range JAVANESE;
+    enum_constant public static final java.awt.font.NumericShaper.Range KANNADA;
+    enum_constant public static final java.awt.font.NumericShaper.Range KAYAH_LI;
+    enum_constant public static final java.awt.font.NumericShaper.Range KHMER;
+    enum_constant public static final java.awt.font.NumericShaper.Range LAO;
+    enum_constant public static final java.awt.font.NumericShaper.Range LEPCHA;
+    enum_constant public static final java.awt.font.NumericShaper.Range LIMBU;
+    enum_constant public static final java.awt.font.NumericShaper.Range MALAYALAM;
+    enum_constant public static final java.awt.font.NumericShaper.Range MEETEI_MAYEK;
+    enum_constant public static final java.awt.font.NumericShaper.Range MONGOLIAN;
+    enum_constant public static final java.awt.font.NumericShaper.Range MYANMAR;
+    enum_constant public static final java.awt.font.NumericShaper.Range MYANMAR_SHAN;
+    enum_constant public static final java.awt.font.NumericShaper.Range NEW_TAI_LUE;
+    enum_constant public static final java.awt.font.NumericShaper.Range NKO;
+    enum_constant public static final java.awt.font.NumericShaper.Range OL_CHIKI;
+    enum_constant public static final java.awt.font.NumericShaper.Range ORIYA;
+    enum_constant public static final java.awt.font.NumericShaper.Range SAURASHTRA;
+    enum_constant public static final java.awt.font.NumericShaper.Range SUNDANESE;
+    enum_constant public static final java.awt.font.NumericShaper.Range TAI_THAM_HORA;
+    enum_constant public static final java.awt.font.NumericShaper.Range TAI_THAM_THAM;
+    enum_constant public static final java.awt.font.NumericShaper.Range TAMIL;
+    enum_constant public static final java.awt.font.NumericShaper.Range TELUGU;
+    enum_constant public static final java.awt.font.NumericShaper.Range THAI;
+    enum_constant public static final java.awt.font.NumericShaper.Range TIBETAN;
+    enum_constant public static final java.awt.font.NumericShaper.Range VAI;
+  }
+
+  public final class TextAttribute extends java.text.AttributedCharacterIterator.Attribute {
+    ctor protected TextAttribute(String);
+    field public static final java.awt.font.TextAttribute BACKGROUND;
+    field public static final java.awt.font.TextAttribute BIDI_EMBEDDING;
+    field public static final java.awt.font.TextAttribute CHAR_REPLACEMENT;
+    field public static final java.awt.font.TextAttribute FAMILY;
+    field public static final java.awt.font.TextAttribute FONT;
+    field public static final java.awt.font.TextAttribute FOREGROUND;
+    field public static final java.awt.font.TextAttribute INPUT_METHOD_HIGHLIGHT;
+    field public static final java.awt.font.TextAttribute INPUT_METHOD_UNDERLINE;
+    field public static final java.awt.font.TextAttribute JUSTIFICATION;
+    field public static final Float JUSTIFICATION_FULL;
+    field public static final Float JUSTIFICATION_NONE;
+    field public static final java.awt.font.TextAttribute KERNING;
+    field public static final Integer KERNING_ON;
+    field public static final java.awt.font.TextAttribute LIGATURES;
+    field public static final Integer LIGATURES_ON;
+    field public static final java.awt.font.TextAttribute NUMERIC_SHAPING;
+    field public static final java.awt.font.TextAttribute POSTURE;
+    field public static final Float POSTURE_OBLIQUE;
+    field public static final Float POSTURE_REGULAR;
+    field public static final java.awt.font.TextAttribute RUN_DIRECTION;
+    field public static final Boolean RUN_DIRECTION_LTR;
+    field public static final Boolean RUN_DIRECTION_RTL;
+    field public static final java.awt.font.TextAttribute SIZE;
+    field public static final java.awt.font.TextAttribute STRIKETHROUGH;
+    field public static final Boolean STRIKETHROUGH_ON;
+    field public static final java.awt.font.TextAttribute SUPERSCRIPT;
+    field public static final Integer SUPERSCRIPT_SUB;
+    field public static final Integer SUPERSCRIPT_SUPER;
+    field public static final java.awt.font.TextAttribute SWAP_COLORS;
+    field public static final Boolean SWAP_COLORS_ON;
+    field public static final java.awt.font.TextAttribute TRACKING;
+    field public static final Float TRACKING_LOOSE;
+    field public static final Float TRACKING_TIGHT;
+    field public static final java.awt.font.TextAttribute TRANSFORM;
+    field public static final java.awt.font.TextAttribute UNDERLINE;
+    field public static final Integer UNDERLINE_LOW_DASHED;
+    field public static final Integer UNDERLINE_LOW_DOTTED;
+    field public static final Integer UNDERLINE_LOW_GRAY;
+    field public static final Integer UNDERLINE_LOW_ONE_PIXEL;
+    field public static final Integer UNDERLINE_LOW_TWO_PIXEL;
+    field public static final Integer UNDERLINE_ON;
+    field public static final java.awt.font.TextAttribute WEIGHT;
+    field public static final Float WEIGHT_BOLD;
+    field public static final Float WEIGHT_DEMIBOLD;
+    field public static final Float WEIGHT_DEMILIGHT;
+    field public static final Float WEIGHT_EXTRABOLD;
+    field public static final Float WEIGHT_EXTRA_LIGHT;
+    field public static final Float WEIGHT_HEAVY;
+    field public static final Float WEIGHT_LIGHT;
+    field public static final Float WEIGHT_MEDIUM;
+    field public static final Float WEIGHT_REGULAR;
+    field public static final Float WEIGHT_SEMIBOLD;
+    field public static final Float WEIGHT_ULTRABOLD;
+    field public static final java.awt.font.TextAttribute WIDTH;
+    field public static final Float WIDTH_CONDENSED;
+    field public static final Float WIDTH_EXTENDED;
+    field public static final Float WIDTH_REGULAR;
+    field public static final Float WIDTH_SEMI_CONDENSED;
+    field public static final Float WIDTH_SEMI_EXTENDED;
+  }
+
+}
+
+package java.beans {
+
+  public class IndexedPropertyChangeEvent extends java.beans.PropertyChangeEvent {
+    ctor public IndexedPropertyChangeEvent(Object, String, Object, Object, int);
+    method public int getIndex();
+  }
+
+  public class PropertyChangeEvent extends java.util.EventObject {
+    ctor public PropertyChangeEvent(Object, String, Object, Object);
+    method public Object getNewValue();
+    method public Object getOldValue();
+    method public Object getPropagationId();
+    method public String getPropertyName();
+    method public void setPropagationId(Object);
+  }
+
+  public interface PropertyChangeListener extends java.util.EventListener {
+    method public void propertyChange(java.beans.PropertyChangeEvent);
+  }
+
+  public class PropertyChangeListenerProxy extends java.util.EventListenerProxy<java.beans.PropertyChangeListener> implements java.beans.PropertyChangeListener {
+    ctor public PropertyChangeListenerProxy(String, java.beans.PropertyChangeListener);
+    method public String getPropertyName();
+    method public void propertyChange(java.beans.PropertyChangeEvent);
+  }
+
+  public class PropertyChangeSupport implements java.io.Serializable {
+    ctor public PropertyChangeSupport(Object);
+    method public void addPropertyChangeListener(java.beans.PropertyChangeListener);
+    method public void addPropertyChangeListener(String, java.beans.PropertyChangeListener);
+    method public void fireIndexedPropertyChange(String, int, Object, Object);
+    method public void fireIndexedPropertyChange(String, int, int, int);
+    method public void fireIndexedPropertyChange(String, int, boolean, boolean);
+    method public void firePropertyChange(String, Object, Object);
+    method public void firePropertyChange(String, int, int);
+    method public void firePropertyChange(String, boolean, boolean);
+    method public void firePropertyChange(java.beans.PropertyChangeEvent);
+    method public java.beans.PropertyChangeListener[] getPropertyChangeListeners();
+    method public java.beans.PropertyChangeListener[] getPropertyChangeListeners(String);
+    method public boolean hasListeners(String);
+    method public void removePropertyChangeListener(java.beans.PropertyChangeListener);
+    method public void removePropertyChangeListener(String, java.beans.PropertyChangeListener);
+  }
+
+}
+
+package java.io {
+
+  public class BufferedInputStream extends java.io.FilterInputStream {
+    ctor public BufferedInputStream(java.io.InputStream);
+    ctor public BufferedInputStream(java.io.InputStream, int);
+    field protected volatile byte[] buf;
+    field protected int count;
+    field protected int marklimit;
+    field protected int markpos;
+    field protected int pos;
+  }
+
+  public class BufferedOutputStream extends java.io.FilterOutputStream {
+    ctor public BufferedOutputStream(java.io.OutputStream);
+    ctor public BufferedOutputStream(java.io.OutputStream, int);
+    field protected byte[] buf;
+    field protected int count;
+  }
+
+  public class BufferedReader extends java.io.Reader {
+    ctor public BufferedReader(java.io.Reader, int);
+    ctor public BufferedReader(java.io.Reader);
+    method public void close() throws java.io.IOException;
+    method public java.util.stream.Stream<java.lang.String> lines();
+    method public int read(char[], int, int) throws java.io.IOException;
+    method public String readLine() throws java.io.IOException;
+  }
+
+  public class BufferedWriter extends java.io.Writer {
+    ctor public BufferedWriter(java.io.Writer);
+    ctor public BufferedWriter(java.io.Writer, int);
+    method public void close() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public void newLine() throws java.io.IOException;
+    method public void write(char[], int, int) throws java.io.IOException;
+  }
+
+  public class ByteArrayInputStream extends java.io.InputStream {
+    ctor public ByteArrayInputStream(byte[]);
+    ctor public ByteArrayInputStream(byte[], int, int);
+    method public int available();
+    method public int read();
+    method public int read(byte[], int, int);
+    method public void reset();
+    method public long skip(long);
+    field protected byte[] buf;
+    field protected int count;
+    field protected int mark;
+    field protected int pos;
+  }
+
+  public class ByteArrayOutputStream extends java.io.OutputStream {
+    ctor public ByteArrayOutputStream();
+    ctor public ByteArrayOutputStream(int);
+    method public void reset();
+    method public int size();
+    method @NonNull public byte[] toByteArray();
+    method @NonNull public String toString(@NonNull String) throws java.io.UnsupportedEncodingException;
+    method @Deprecated @NonNull public String toString(int);
+    method public void write(int);
+    method public void write(@NonNull byte[], int, int);
+    method public void writeTo(@NonNull java.io.OutputStream) throws java.io.IOException;
+    field @NonNull protected byte[] buf;
+    field protected int count;
+  }
+
+  public class CharArrayReader extends java.io.Reader {
+    ctor public CharArrayReader(char[]);
+    ctor public CharArrayReader(char[], int, int);
+    method public void close();
+    method public int read(char[], int, int) throws java.io.IOException;
+    field protected char[] buf;
+    field protected int count;
+    field protected int markedPos;
+    field protected int pos;
+  }
+
+  public class CharArrayWriter extends java.io.Writer {
+    ctor public CharArrayWriter();
+    ctor public CharArrayWriter(int);
+    method public java.io.CharArrayWriter append(CharSequence);
+    method public java.io.CharArrayWriter append(CharSequence, int, int);
+    method public java.io.CharArrayWriter append(char);
+    method public void close();
+    method public void flush();
+    method public void reset();
+    method public int size();
+    method public char[] toCharArray();
+    method public void write(int);
+    method public void write(char[], int, int);
+    method public void write(String, int, int);
+    method public void writeTo(java.io.Writer) throws java.io.IOException;
+    field protected char[] buf;
+    field protected int count;
+  }
+
+  public class CharConversionException extends java.io.IOException {
+    ctor public CharConversionException();
+    ctor public CharConversionException(String);
+  }
+
+  public interface Closeable extends java.lang.AutoCloseable {
+    method public void close() throws java.io.IOException;
+  }
+
+  public final class Console implements java.io.Flushable {
+    method public void flush();
+    method public java.io.Console format(String, java.lang.Object...);
+    method public java.io.Console printf(String, java.lang.Object...);
+    method public String readLine(String, java.lang.Object...);
+    method public String readLine();
+    method public char[] readPassword(String, java.lang.Object...);
+    method public char[] readPassword();
+    method public java.io.Reader reader();
+    method public java.io.PrintWriter writer();
+  }
+
+  public interface DataInput {
+    method public boolean readBoolean() throws java.io.IOException;
+    method public byte readByte() throws java.io.IOException;
+    method public char readChar() throws java.io.IOException;
+    method public double readDouble() throws java.io.IOException;
+    method public float readFloat() throws java.io.IOException;
+    method public void readFully(byte[]) throws java.io.IOException;
+    method public void readFully(byte[], int, int) throws java.io.IOException;
+    method public int readInt() throws java.io.IOException;
+    method public String readLine() throws java.io.IOException;
+    method public long readLong() throws java.io.IOException;
+    method public short readShort() throws java.io.IOException;
+    method public String readUTF() throws java.io.IOException;
+    method public int readUnsignedByte() throws java.io.IOException;
+    method public int readUnsignedShort() throws java.io.IOException;
+    method public int skipBytes(int) throws java.io.IOException;
+  }
+
+  public class DataInputStream extends java.io.FilterInputStream implements java.io.DataInput {
+    ctor public DataInputStream(java.io.InputStream);
+    method public final int read(byte[]) throws java.io.IOException;
+    method public final int read(byte[], int, int) throws java.io.IOException;
+    method public final boolean readBoolean() throws java.io.IOException;
+    method public final byte readByte() throws java.io.IOException;
+    method public final char readChar() throws java.io.IOException;
+    method public final double readDouble() throws java.io.IOException;
+    method public final float readFloat() throws java.io.IOException;
+    method public final void readFully(byte[]) throws java.io.IOException;
+    method public final void readFully(byte[], int, int) throws java.io.IOException;
+    method public final int readInt() throws java.io.IOException;
+    method @Deprecated public final String readLine() throws java.io.IOException;
+    method public final long readLong() throws java.io.IOException;
+    method public final short readShort() throws java.io.IOException;
+    method public final String readUTF() throws java.io.IOException;
+    method public static final String readUTF(java.io.DataInput) throws java.io.IOException;
+    method public final int readUnsignedByte() throws java.io.IOException;
+    method public final int readUnsignedShort() throws java.io.IOException;
+    method public final int skipBytes(int) throws java.io.IOException;
+  }
+
+  public interface DataOutput {
+    method public void write(int) throws java.io.IOException;
+    method public void write(byte[]) throws java.io.IOException;
+    method public void write(byte[], int, int) throws java.io.IOException;
+    method public void writeBoolean(boolean) throws java.io.IOException;
+    method public void writeByte(int) throws java.io.IOException;
+    method public void writeBytes(String) throws java.io.IOException;
+    method public void writeChar(int) throws java.io.IOException;
+    method public void writeChars(String) throws java.io.IOException;
+    method public void writeDouble(double) throws java.io.IOException;
+    method public void writeFloat(float) throws java.io.IOException;
+    method public void writeInt(int) throws java.io.IOException;
+    method public void writeLong(long) throws java.io.IOException;
+    method public void writeShort(int) throws java.io.IOException;
+    method public void writeUTF(String) throws java.io.IOException;
+  }
+
+  public class DataOutputStream extends java.io.FilterOutputStream implements java.io.DataOutput {
+    ctor public DataOutputStream(java.io.OutputStream);
+    method public final int size();
+    method public final void writeBoolean(boolean) throws java.io.IOException;
+    method public final void writeByte(int) throws java.io.IOException;
+    method public final void writeBytes(String) throws java.io.IOException;
+    method public final void writeChar(int) throws java.io.IOException;
+    method public final void writeChars(String) throws java.io.IOException;
+    method public final void writeDouble(double) throws java.io.IOException;
+    method public final void writeFloat(float) throws java.io.IOException;
+    method public final void writeInt(int) throws java.io.IOException;
+    method public final void writeLong(long) throws java.io.IOException;
+    method public final void writeShort(int) throws java.io.IOException;
+    method public final void writeUTF(String) throws java.io.IOException;
+    field protected int written;
+  }
+
+  public class EOFException extends java.io.IOException {
+    ctor public EOFException();
+    ctor public EOFException(String);
+  }
+
+  public interface Externalizable extends java.io.Serializable {
+    method public void readExternal(java.io.ObjectInput) throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public void writeExternal(java.io.ObjectOutput) throws java.io.IOException;
+  }
+
+  public class File implements java.lang.Comparable<java.io.File> java.io.Serializable {
+    ctor public File(@NonNull String);
+    ctor public File(@Nullable String, @NonNull String);
+    ctor public File(@Nullable java.io.File, @NonNull String);
+    ctor public File(@NonNull java.net.URI);
+    method public boolean canExecute();
+    method public boolean canRead();
+    method public boolean canWrite();
+    method public int compareTo(@NonNull java.io.File);
+    method public boolean createNewFile() throws java.io.IOException;
+    method @NonNull public static java.io.File createTempFile(@NonNull String, @Nullable String, @Nullable java.io.File) throws java.io.IOException;
+    method @NonNull public static java.io.File createTempFile(@NonNull String, @Nullable String) throws java.io.IOException;
+    method public boolean delete();
+    method public void deleteOnExit();
+    method public boolean exists();
+    method @NonNull public java.io.File getAbsoluteFile();
+    method @NonNull public String getAbsolutePath();
+    method @NonNull public java.io.File getCanonicalFile() throws java.io.IOException;
+    method @NonNull public String getCanonicalPath() throws java.io.IOException;
+    method public long getFreeSpace();
+    method @NonNull public String getName();
+    method @Nullable public String getParent();
+    method @Nullable public java.io.File getParentFile();
+    method @NonNull public String getPath();
+    method public long getTotalSpace();
+    method public long getUsableSpace();
+    method public boolean isAbsolute();
+    method public boolean isDirectory();
+    method public boolean isFile();
+    method public boolean isHidden();
+    method public long lastModified();
+    method public long length();
+    method @Nullable public String[] list();
+    method @Nullable public String[] list(@Nullable java.io.FilenameFilter);
+    method @Nullable public java.io.File[] listFiles();
+    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FilenameFilter);
+    method @Nullable public java.io.File[] listFiles(@Nullable java.io.FileFilter);
+    method @NonNull public static java.io.File[] listRoots();
+    method public boolean mkdir();
+    method public boolean mkdirs();
+    method public boolean renameTo(@NonNull java.io.File);
+    method public boolean setExecutable(boolean, boolean);
+    method public boolean setExecutable(boolean);
+    method public boolean setLastModified(long);
+    method public boolean setReadOnly();
+    method public boolean setReadable(boolean, boolean);
+    method public boolean setReadable(boolean);
+    method public boolean setWritable(boolean, boolean);
+    method public boolean setWritable(boolean);
+    method @NonNull public java.nio.file.Path toPath();
+    method @NonNull public java.net.URI toURI();
+    method @Deprecated @NonNull public java.net.URL toURL() throws java.net.MalformedURLException;
+    field @NonNull public static final String pathSeparator;
+    field public static final char pathSeparatorChar;
+    field @NonNull public static final String separator;
+    field public static final char separatorChar;
+  }
+
+  public final class FileDescriptor {
+    ctor public FileDescriptor();
+    method public void sync() throws java.io.SyncFailedException;
+    method public boolean valid();
+    field public static final java.io.FileDescriptor err;
+    field public static final java.io.FileDescriptor in;
+    field public static final java.io.FileDescriptor out;
+  }
+
+  @java.lang.FunctionalInterface public interface FileFilter {
+    method public boolean accept(java.io.File);
+  }
+
+  public class FileInputStream extends java.io.InputStream {
+    ctor public FileInputStream(String) throws java.io.FileNotFoundException;
+    ctor public FileInputStream(java.io.File) throws java.io.FileNotFoundException;
+    ctor public FileInputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
+    method public java.nio.channels.FileChannel getChannel();
+    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
+    method public int read() throws java.io.IOException;
+  }
+
+  public class FileNotFoundException extends java.io.IOException {
+    ctor public FileNotFoundException();
+    ctor public FileNotFoundException(String);
+  }
+
+  public class FileOutputStream extends java.io.OutputStream {
+    ctor public FileOutputStream(String) throws java.io.FileNotFoundException;
+    ctor public FileOutputStream(String, boolean) throws java.io.FileNotFoundException;
+    ctor public FileOutputStream(java.io.File) throws java.io.FileNotFoundException;
+    ctor public FileOutputStream(java.io.File, boolean) throws java.io.FileNotFoundException;
+    ctor public FileOutputStream(java.io.FileDescriptor);
+    method protected void finalize() throws java.io.IOException;
+    method public java.nio.channels.FileChannel getChannel();
+    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
+    method public void write(int) throws java.io.IOException;
+  }
+
+  public final class FilePermission extends java.security.Permission implements java.io.Serializable {
+    ctor public FilePermission(String, String);
+    method public String getActions();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public class FileReader extends java.io.InputStreamReader {
+    ctor public FileReader(String) throws java.io.FileNotFoundException;
+    ctor public FileReader(java.io.File) throws java.io.FileNotFoundException;
+    ctor public FileReader(java.io.FileDescriptor);
+  }
+
+  public class FileWriter extends java.io.OutputStreamWriter {
+    ctor public FileWriter(String) throws java.io.IOException;
+    ctor public FileWriter(String, boolean) throws java.io.IOException;
+    ctor public FileWriter(java.io.File) throws java.io.IOException;
+    ctor public FileWriter(java.io.File, boolean) throws java.io.IOException;
+    ctor public FileWriter(java.io.FileDescriptor);
+  }
+
+  @java.lang.FunctionalInterface public interface FilenameFilter {
+    method public boolean accept(java.io.File, String);
+  }
+
+  public class FilterInputStream extends java.io.InputStream {
+    ctor protected FilterInputStream(java.io.InputStream);
+    method public int read() throws java.io.IOException;
+    field protected volatile java.io.InputStream in;
+  }
+
+  public class FilterOutputStream extends java.io.OutputStream {
+    ctor public FilterOutputStream(java.io.OutputStream);
+    method public void write(int) throws java.io.IOException;
+    field protected java.io.OutputStream out;
+  }
+
+  public abstract class FilterReader extends java.io.Reader {
+    ctor protected FilterReader(java.io.Reader);
+    method public void close() throws java.io.IOException;
+    method public int read(char[], int, int) throws java.io.IOException;
+    field protected java.io.Reader in;
+  }
+
+  public abstract class FilterWriter extends java.io.Writer {
+    ctor protected FilterWriter(java.io.Writer);
+    method public void close() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public void write(char[], int, int) throws java.io.IOException;
+    field protected java.io.Writer out;
+  }
+
+  public interface Flushable {
+    method public void flush() throws java.io.IOException;
+  }
+
+  public class IOError extends java.lang.Error {
+    ctor public IOError(Throwable);
+  }
+
+  public class IOException extends java.lang.Exception {
+    ctor public IOException();
+    ctor public IOException(String);
+    ctor public IOException(String, Throwable);
+    ctor public IOException(Throwable);
+  }
+
+  public abstract class InputStream implements java.io.Closeable {
+    ctor public InputStream();
+    method public int available() throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public void mark(int);
+    method public boolean markSupported();
+    method public abstract int read() throws java.io.IOException;
+    method public int read(byte[]) throws java.io.IOException;
+    method public int read(byte[], int, int) throws java.io.IOException;
+    method public void reset() throws java.io.IOException;
+    method public long skip(long) throws java.io.IOException;
+  }
+
+  public class InputStreamReader extends java.io.Reader {
+    ctor public InputStreamReader(java.io.InputStream);
+    ctor public InputStreamReader(java.io.InputStream, String) throws java.io.UnsupportedEncodingException;
+    ctor public InputStreamReader(java.io.InputStream, java.nio.charset.Charset);
+    ctor public InputStreamReader(java.io.InputStream, java.nio.charset.CharsetDecoder);
+    method public void close() throws java.io.IOException;
+    method public String getEncoding();
+    method public int read(char[], int, int) throws java.io.IOException;
+  }
+
+  public class InterruptedIOException extends java.io.IOException {
+    ctor public InterruptedIOException();
+    ctor public InterruptedIOException(String);
+    field public int bytesTransferred;
+  }
+
+  public class InvalidClassException extends java.io.ObjectStreamException {
+    ctor public InvalidClassException(String);
+    ctor public InvalidClassException(String, String);
+    field public String classname;
+  }
+
+  public class InvalidObjectException extends java.io.ObjectStreamException {
+    ctor public InvalidObjectException(String);
+  }
+
+  @Deprecated public class LineNumberInputStream extends java.io.FilterInputStream {
+    ctor @Deprecated public LineNumberInputStream(java.io.InputStream);
+    method @Deprecated public int getLineNumber();
+    method @Deprecated public void setLineNumber(int);
+  }
+
+  public class LineNumberReader extends java.io.BufferedReader {
+    ctor public LineNumberReader(java.io.Reader);
+    ctor public LineNumberReader(java.io.Reader, int);
+    method public int getLineNumber();
+    method public void setLineNumber(int);
+  }
+
+  public class NotActiveException extends java.io.ObjectStreamException {
+    ctor public NotActiveException(String);
+    ctor public NotActiveException();
+  }
+
+  public class NotSerializableException extends java.io.ObjectStreamException {
+    ctor public NotSerializableException(String);
+    ctor public NotSerializableException();
+  }
+
+  public interface ObjectInput extends java.io.DataInput java.lang.AutoCloseable {
+    method public int available() throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public int read() throws java.io.IOException;
+    method public int read(byte[]) throws java.io.IOException;
+    method public int read(byte[], int, int) throws java.io.IOException;
+    method public Object readObject() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public long skip(long) throws java.io.IOException;
+  }
+
+  public class ObjectInputStream extends java.io.InputStream implements java.io.ObjectInput java.io.ObjectStreamConstants {
+    ctor public ObjectInputStream(java.io.InputStream) throws java.io.IOException;
+    ctor protected ObjectInputStream() throws java.io.IOException, java.lang.SecurityException;
+    method public void defaultReadObject() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method protected boolean enableResolveObject(boolean) throws java.lang.SecurityException;
+    method public int read() throws java.io.IOException;
+    method public boolean readBoolean() throws java.io.IOException;
+    method public byte readByte() throws java.io.IOException;
+    method public char readChar() throws java.io.IOException;
+    method protected java.io.ObjectStreamClass readClassDescriptor() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public double readDouble() throws java.io.IOException;
+    method public java.io.ObjectInputStream.GetField readFields() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public float readFloat() throws java.io.IOException;
+    method public void readFully(byte[]) throws java.io.IOException;
+    method public void readFully(byte[], int, int) throws java.io.IOException;
+    method public int readInt() throws java.io.IOException;
+    method @Deprecated public String readLine() throws java.io.IOException;
+    method public long readLong() throws java.io.IOException;
+    method public final Object readObject() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method protected Object readObjectOverride() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public short readShort() throws java.io.IOException;
+    method protected void readStreamHeader() throws java.io.IOException, java.io.StreamCorruptedException;
+    method public String readUTF() throws java.io.IOException;
+    method public Object readUnshared() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public int readUnsignedByte() throws java.io.IOException;
+    method public int readUnsignedShort() throws java.io.IOException;
+    method public void registerValidation(java.io.ObjectInputValidation, int) throws java.io.InvalidObjectException, java.io.NotActiveException;
+    method protected Class<?> resolveClass(java.io.ObjectStreamClass) throws java.lang.ClassNotFoundException, java.io.IOException;
+    method protected Object resolveObject(Object) throws java.io.IOException;
+    method protected Class<?> resolveProxyClass(String[]) throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public int skipBytes(int) throws java.io.IOException;
+  }
+
+  public abstract static class ObjectInputStream.GetField {
+    ctor public ObjectInputStream.GetField();
+    method public abstract boolean defaulted(String) throws java.io.IOException;
+    method public abstract boolean get(String, boolean) throws java.io.IOException;
+    method public abstract byte get(String, byte) throws java.io.IOException;
+    method public abstract char get(String, char) throws java.io.IOException;
+    method public abstract short get(String, short) throws java.io.IOException;
+    method public abstract int get(String, int) throws java.io.IOException;
+    method public abstract long get(String, long) throws java.io.IOException;
+    method public abstract float get(String, float) throws java.io.IOException;
+    method public abstract double get(String, double) throws java.io.IOException;
+    method public abstract Object get(String, Object) throws java.io.IOException;
+    method public abstract java.io.ObjectStreamClass getObjectStreamClass();
+  }
+
+  public interface ObjectInputValidation {
+    method public void validateObject() throws java.io.InvalidObjectException;
+  }
+
+  public interface ObjectOutput extends java.io.DataOutput java.lang.AutoCloseable {
+    method public void close() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public void writeObject(Object) throws java.io.IOException;
+  }
+
+  public class ObjectOutputStream extends java.io.OutputStream implements java.io.ObjectOutput java.io.ObjectStreamConstants {
+    ctor public ObjectOutputStream(java.io.OutputStream) throws java.io.IOException;
+    ctor protected ObjectOutputStream() throws java.io.IOException, java.lang.SecurityException;
+    method protected void annotateClass(Class<?>) throws java.io.IOException;
+    method protected void annotateProxyClass(Class<?>) throws java.io.IOException;
+    method public void defaultWriteObject() throws java.io.IOException;
+    method protected void drain() throws java.io.IOException;
+    method protected boolean enableReplaceObject(boolean) throws java.lang.SecurityException;
+    method public java.io.ObjectOutputStream.PutField putFields() throws java.io.IOException;
+    method protected Object replaceObject(Object) throws java.io.IOException;
+    method public void reset() throws java.io.IOException;
+    method public void useProtocolVersion(int) throws java.io.IOException;
+    method public void write(int) throws java.io.IOException;
+    method public void writeBoolean(boolean) throws java.io.IOException;
+    method public void writeByte(int) throws java.io.IOException;
+    method public void writeBytes(String) throws java.io.IOException;
+    method public void writeChar(int) throws java.io.IOException;
+    method public void writeChars(String) throws java.io.IOException;
+    method protected void writeClassDescriptor(java.io.ObjectStreamClass) throws java.io.IOException;
+    method public void writeDouble(double) throws java.io.IOException;
+    method public void writeFields() throws java.io.IOException;
+    method public void writeFloat(float) throws java.io.IOException;
+    method public void writeInt(int) throws java.io.IOException;
+    method public void writeLong(long) throws java.io.IOException;
+    method public final void writeObject(Object) throws java.io.IOException;
+    method protected void writeObjectOverride(Object) throws java.io.IOException;
+    method public void writeShort(int) throws java.io.IOException;
+    method protected void writeStreamHeader() throws java.io.IOException;
+    method public void writeUTF(String) throws java.io.IOException;
+    method public void writeUnshared(Object) throws java.io.IOException;
+  }
+
+  public abstract static class ObjectOutputStream.PutField {
+    ctor public ObjectOutputStream.PutField();
+    method public abstract void put(String, boolean);
+    method public abstract void put(String, byte);
+    method public abstract void put(String, char);
+    method public abstract void put(String, short);
+    method public abstract void put(String, int);
+    method public abstract void put(String, long);
+    method public abstract void put(String, float);
+    method public abstract void put(String, double);
+    method public abstract void put(String, Object);
+    method @Deprecated public abstract void write(java.io.ObjectOutput) throws java.io.IOException;
+  }
+
+  public class ObjectStreamClass implements java.io.Serializable {
+    method public Class<?> forClass();
+    method public java.io.ObjectStreamField getField(String);
+    method public java.io.ObjectStreamField[] getFields();
+    method public String getName();
+    method public long getSerialVersionUID();
+    method public static java.io.ObjectStreamClass lookup(Class<?>);
+    method public static java.io.ObjectStreamClass lookupAny(Class<?>);
+    field public static final java.io.ObjectStreamField[] NO_FIELDS;
+  }
+
+  public interface ObjectStreamConstants {
+    field public static final int PROTOCOL_VERSION_1 = 1; // 0x1
+    field public static final int PROTOCOL_VERSION_2 = 2; // 0x2
+    field public static final byte SC_BLOCK_DATA = 8; // 0x8
+    field public static final byte SC_ENUM = 16; // 0x10
+    field public static final byte SC_EXTERNALIZABLE = 4; // 0x4
+    field public static final byte SC_SERIALIZABLE = 2; // 0x2
+    field public static final byte SC_WRITE_METHOD = 1; // 0x1
+    field public static final short STREAM_MAGIC = -21267; // 0xffffaced
+    field public static final short STREAM_VERSION = 5; // 0x5
+    field public static final java.io.SerializablePermission SUBCLASS_IMPLEMENTATION_PERMISSION;
+    field public static final java.io.SerializablePermission SUBSTITUTION_PERMISSION;
+    field public static final byte TC_ARRAY = 117; // 0x75
+    field public static final byte TC_BASE = 112; // 0x70
+    field public static final byte TC_BLOCKDATA = 119; // 0x77
+    field public static final byte TC_BLOCKDATALONG = 122; // 0x7a
+    field public static final byte TC_CLASS = 118; // 0x76
+    field public static final byte TC_CLASSDESC = 114; // 0x72
+    field public static final byte TC_ENDBLOCKDATA = 120; // 0x78
+    field public static final byte TC_ENUM = 126; // 0x7e
+    field public static final byte TC_EXCEPTION = 123; // 0x7b
+    field public static final byte TC_LONGSTRING = 124; // 0x7c
+    field public static final byte TC_MAX = 126; // 0x7e
+    field public static final byte TC_NULL = 112; // 0x70
+    field public static final byte TC_OBJECT = 115; // 0x73
+    field public static final byte TC_PROXYCLASSDESC = 125; // 0x7d
+    field public static final byte TC_REFERENCE = 113; // 0x71
+    field public static final byte TC_RESET = 121; // 0x79
+    field public static final byte TC_STRING = 116; // 0x74
+    field public static final int baseWireHandle = 8257536; // 0x7e0000
+  }
+
+  public abstract class ObjectStreamException extends java.io.IOException {
+    ctor protected ObjectStreamException(String);
+    ctor protected ObjectStreamException();
+  }
+
+  public class ObjectStreamField implements java.lang.Comparable<java.lang.Object> {
+    ctor public ObjectStreamField(String, Class<?>);
+    ctor public ObjectStreamField(String, Class<?>, boolean);
+    method public int compareTo(Object);
+    method public String getName();
+    method public int getOffset();
+    method public Class<?> getType();
+    method public char getTypeCode();
+    method public String getTypeString();
+    method public boolean isPrimitive();
+    method public boolean isUnshared();
+    method protected void setOffset(int);
+  }
+
+  public class OptionalDataException extends java.io.ObjectStreamException {
+    field public boolean eof;
+    field public int length;
+  }
+
+  public abstract class OutputStream implements java.io.Closeable java.io.Flushable {
+    ctor public OutputStream();
+    method public void close() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public abstract void write(int) throws java.io.IOException;
+    method public void write(byte[]) throws java.io.IOException;
+    method public void write(byte[], int, int) throws java.io.IOException;
+  }
+
+  public class OutputStreamWriter extends java.io.Writer {
+    ctor public OutputStreamWriter(java.io.OutputStream, String) throws java.io.UnsupportedEncodingException;
+    ctor public OutputStreamWriter(java.io.OutputStream);
+    ctor public OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset);
+    ctor public OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder);
+    method public void close() throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public String getEncoding();
+    method public void write(char[], int, int) throws java.io.IOException;
+  }
+
+  public class PipedInputStream extends java.io.InputStream {
+    ctor public PipedInputStream(java.io.PipedOutputStream) throws java.io.IOException;
+    ctor public PipedInputStream(java.io.PipedOutputStream, int) throws java.io.IOException;
+    ctor public PipedInputStream();
+    ctor public PipedInputStream(int);
+    method public void connect(java.io.PipedOutputStream) throws java.io.IOException;
+    method public int read() throws java.io.IOException;
+    method protected void receive(int) throws java.io.IOException;
+    field protected static final int PIPE_SIZE = 1024; // 0x400
+    field protected byte[] buffer;
+    field protected int in;
+    field protected int out;
+  }
+
+  public class PipedOutputStream extends java.io.OutputStream {
+    ctor public PipedOutputStream(java.io.PipedInputStream) throws java.io.IOException;
+    ctor public PipedOutputStream();
+    method public void connect(java.io.PipedInputStream) throws java.io.IOException;
+    method public void write(int) throws java.io.IOException;
+  }
+
+  public class PipedReader extends java.io.Reader {
+    ctor public PipedReader(java.io.PipedWriter) throws java.io.IOException;
+    ctor public PipedReader(java.io.PipedWriter, int) throws java.io.IOException;
+    ctor public PipedReader();
+    ctor public PipedReader(int);
+    method public void close() throws java.io.IOException;
+    method public void connect(java.io.PipedWriter) throws java.io.IOException;
+    method public int read(char[], int, int) throws java.io.IOException;
+  }
+
+  public class PipedWriter extends java.io.Writer {
+    ctor public PipedWriter(java.io.PipedReader) throws java.io.IOException;
+    ctor public PipedWriter();
+    method public void close() throws java.io.IOException;
+    method public void connect(java.io.PipedReader) throws java.io.IOException;
+    method public void flush() throws java.io.IOException;
+    method public void write(char[], int, int) throws java.io.IOException;
+  }
+
+  public class PrintStream extends java.io.FilterOutputStream implements java.lang.Appendable java.io.Closeable {
+    ctor public PrintStream(java.io.OutputStream);
+    ctor public PrintStream(java.io.OutputStream, boolean);
+    ctor public PrintStream(java.io.OutputStream, boolean, String) throws java.io.UnsupportedEncodingException;
+    ctor public PrintStream(String) throws java.io.FileNotFoundException;
+    ctor public PrintStream(String, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public PrintStream(java.io.File) throws java.io.FileNotFoundException;
+    ctor public PrintStream(java.io.File, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    method public java.io.PrintStream append(CharSequence);
+    method public java.io.PrintStream append(CharSequence, int, int);
+    method public java.io.PrintStream append(char);
+    method public boolean checkError();
+    method protected void clearError();
+    method public void close();
+    method public void flush();
+    method public java.io.PrintStream format(String, java.lang.Object...);
+    method public java.io.PrintStream format(java.util.Locale, String, java.lang.Object...);
+    method public void print(boolean);
+    method public void print(char);
+    method public void print(int);
+    method public void print(long);
+    method public void print(float);
+    method public void print(double);
+    method public void print(char[]);
+    method public void print(String);
+    method public void print(Object);
+    method public java.io.PrintStream printf(String, java.lang.Object...);
+    method public java.io.PrintStream printf(java.util.Locale, String, java.lang.Object...);
+    method public void println();
+    method public void println(boolean);
+    method public void println(char);
+    method public void println(int);
+    method public void println(long);
+    method public void println(float);
+    method public void println(double);
+    method public void println(char[]);
+    method public void println(String);
+    method public void println(Object);
+    method protected void setError();
+    method public void write(int);
+    method public void write(byte[], int, int);
+  }
+
+  public class PrintWriter extends java.io.Writer {
+    ctor public PrintWriter(@NonNull java.io.Writer);
+    ctor public PrintWriter(@NonNull java.io.Writer, boolean);
+    ctor public PrintWriter(@NonNull java.io.OutputStream);
+    ctor public PrintWriter(@NonNull java.io.OutputStream, boolean);
+    ctor public PrintWriter(@NonNull String) throws java.io.FileNotFoundException;
+    ctor public PrintWriter(@NonNull String, @NonNull String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public PrintWriter(@NonNull java.io.File) throws java.io.FileNotFoundException;
+    ctor public PrintWriter(@NonNull java.io.File, @NonNull String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    method @NonNull public java.io.PrintWriter append(@Nullable CharSequence);
+    method @NonNull public java.io.PrintWriter append(@Nullable CharSequence, int, int);
+    method @NonNull public java.io.PrintWriter append(char);
+    method public boolean checkError();
+    method protected void clearError();
+    method public void close();
+    method public void flush();
+    method @NonNull public java.io.PrintWriter format(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public java.io.PrintWriter format(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
+    method public void print(boolean);
+    method public void print(char);
+    method public void print(int);
+    method public void print(long);
+    method public void print(float);
+    method public void print(double);
+    method public void print(char[]);
+    method public void print(@Nullable String);
+    method public void print(@Nullable Object);
+    method @NonNull public java.io.PrintWriter printf(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public java.io.PrintWriter printf(@Nullable java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
+    method public void println();
+    method public void println(boolean);
+    method public void println(char);
+    method public void println(int);
+    method public void println(long);
+    method public void println(float);
+    method public void println(double);
+    method public void println(char[]);
+    method public void println(@Nullable String);
+    method public void println(@Nullable Object);
+    method protected void setError();
+    method public void write(int);
+    method public void write(char[], int, int);
+    method public void write(char[]);
+    method public void write(@NonNull String, int, int);
+    method public void write(@NonNull String);
+    field protected java.io.Writer out;
+  }
+
+  public class PushbackInputStream extends java.io.FilterInputStream {
+    ctor public PushbackInputStream(java.io.InputStream, int);
+    ctor public PushbackInputStream(java.io.InputStream);
+    method public void unread(int) throws java.io.IOException;
+    method public void unread(byte[], int, int) throws java.io.IOException;
+    method public void unread(byte[]) throws java.io.IOException;
+    field protected byte[] buf;
+    field protected int pos;
+  }
+
+  public class PushbackReader extends java.io.FilterReader {
+    ctor public PushbackReader(java.io.Reader, int);
+    ctor public PushbackReader(java.io.Reader);
+    method public void unread(int) throws java.io.IOException;
+    method public void unread(char[], int, int) throws java.io.IOException;
+    method public void unread(char[]) throws java.io.IOException;
+  }
+
+  public class RandomAccessFile implements java.io.Closeable java.io.DataInput java.io.DataOutput {
+    ctor public RandomAccessFile(String, String) throws java.io.FileNotFoundException;
+    ctor public RandomAccessFile(java.io.File, String) throws java.io.FileNotFoundException;
+    method public void close() throws java.io.IOException;
+    method public final java.nio.channels.FileChannel getChannel();
+    method public final java.io.FileDescriptor getFD() throws java.io.IOException;
+    method public long getFilePointer() throws java.io.IOException;
+    method public long length() throws java.io.IOException;
+    method public int read() throws java.io.IOException;
+    method public int read(byte[], int, int) throws java.io.IOException;
+    method public int read(byte[]) throws java.io.IOException;
+    method public final boolean readBoolean() throws java.io.IOException;
+    method public final byte readByte() throws java.io.IOException;
+    method public final char readChar() throws java.io.IOException;
+    method public final double readDouble() throws java.io.IOException;
+    method public final float readFloat() throws java.io.IOException;
+    method public final void readFully(byte[]) throws java.io.IOException;
+    method public final void readFully(byte[], int, int) throws java.io.IOException;
+    method public final int readInt() throws java.io.IOException;
+    method public final String readLine() throws java.io.IOException;
+    method public final long readLong() throws java.io.IOException;
+    method public final short readShort() throws java.io.IOException;
+    method public final String readUTF() throws java.io.IOException;
+    method public final int readUnsignedByte() throws java.io.IOException;
+    method public final int readUnsignedShort() throws java.io.IOException;
+    method public void seek(long) throws java.io.IOException;
+    method public void setLength(long) throws java.io.IOException;
+    method public int skipBytes(int) throws java.io.IOException;
+    method public void write(int) throws java.io.IOException;
+    method public void write(byte[]) throws java.io.IOException;
+    method public void write(byte[], int, int) throws java.io.IOException;
+    method public final void writeBoolean(boolean) throws java.io.IOException;
+    method public final void writeByte(int) throws java.io.IOException;
+    method public final void writeBytes(String) throws java.io.IOException;
+    method public final void writeChar(int) throws java.io.IOException;
+    method public final void writeChars(String) throws java.io.IOException;
+    method public final void writeDouble(double) throws java.io.IOException;
+    method public final void writeFloat(float) throws java.io.IOException;
+    method public final void writeInt(int) throws java.io.IOException;
+    method public final void writeLong(long) throws java.io.IOException;
+    method public final void writeShort(int) throws java.io.IOException;
+    method public final void writeUTF(String) throws java.io.IOException;
+  }
+
+  public abstract class Reader implements java.io.Closeable java.lang.Readable {
+    ctor protected Reader();
+    ctor protected Reader(Object);
+    method public void mark(int) throws java.io.IOException;
+    method public boolean markSupported();
+    method public int read(java.nio.CharBuffer) throws java.io.IOException;
+    method public int read() throws java.io.IOException;
+    method public int read(char[]) throws java.io.IOException;
+    method public abstract int read(char[], int, int) throws java.io.IOException;
+    method public boolean ready() throws java.io.IOException;
+    method public void reset() throws java.io.IOException;
+    method public long skip(long) throws java.io.IOException;
+    field protected Object lock;
+  }
+
+  public class SequenceInputStream extends java.io.InputStream {
+    ctor public SequenceInputStream(java.util.Enumeration<? extends java.io.InputStream>);
+    ctor public SequenceInputStream(java.io.InputStream, java.io.InputStream);
+    method public int read() throws java.io.IOException;
+  }
+
+  public interface Serializable {
+  }
+
+  public final class SerializablePermission extends java.security.BasicPermission {
+    ctor public SerializablePermission(String);
+    ctor public SerializablePermission(String, String);
+  }
+
+  public class StreamCorruptedException extends java.io.ObjectStreamException {
+    ctor public StreamCorruptedException(String);
+    ctor public StreamCorruptedException();
+  }
+
+  public class StreamTokenizer {
+    ctor @Deprecated public StreamTokenizer(java.io.InputStream);
+    ctor public StreamTokenizer(java.io.Reader);
+    method public void commentChar(int);
+    method public void eolIsSignificant(boolean);
+    method public int lineno();
+    method public void lowerCaseMode(boolean);
+    method public int nextToken() throws java.io.IOException;
+    method public void ordinaryChar(int);
+    method public void ordinaryChars(int, int);
+    method public void parseNumbers();
+    method public void pushBack();
+    method public void quoteChar(int);
+    method public void resetSyntax();
+    method public void slashSlashComments(boolean);
+    method public void slashStarComments(boolean);
+    method public void whitespaceChars(int, int);
+    method public void wordChars(int, int);
+    field public static final int TT_EOF = -1; // 0xffffffff
+    field public static final int TT_EOL = 10; // 0xa
+    field public static final int TT_NUMBER = -2; // 0xfffffffe
+    field public static final int TT_WORD = -3; // 0xfffffffd
+    field public double nval;
+    field public String sval;
+    field public int ttype;
+  }
+
+  @Deprecated public class StringBufferInputStream extends java.io.InputStream {
+    ctor @Deprecated public StringBufferInputStream(String);
+    method @Deprecated public int available();
+    method @Deprecated public int read();
+    method @Deprecated public int read(byte[], int, int);
+    method @Deprecated public void reset();
+    method @Deprecated public long skip(long);
+    field @Deprecated protected String buffer;
+    field @Deprecated protected int count;
+    field @Deprecated protected int pos;
+  }
+
+  public class StringReader extends java.io.Reader {
+    ctor public StringReader(String);
+    method public void close();
+    method public int read(char[], int, int) throws java.io.IOException;
+  }
+
+  public class StringWriter extends java.io.Writer {
+    ctor public StringWriter();
+    ctor public StringWriter(int);
+    method public java.io.StringWriter append(CharSequence);
+    method public java.io.StringWriter append(CharSequence, int, int);
+    method public java.io.StringWriter append(char);
+    method public void close() throws java.io.IOException;
+    method public void flush();
+    method public StringBuffer getBuffer();
+    method public void write(int);
+    method public void write(char[], int, int);
+    method public void write(String);
+    method public void write(String, int, int);
+  }
+
+  public class SyncFailedException extends java.io.IOException {
+    ctor public SyncFailedException(String);
+  }
+
+  public class UTFDataFormatException extends java.io.IOException {
+    ctor public UTFDataFormatException();
+    ctor public UTFDataFormatException(String);
+  }
+
+  public class UncheckedIOException extends java.lang.RuntimeException {
+    ctor public UncheckedIOException(String, java.io.IOException);
+    ctor public UncheckedIOException(java.io.IOException);
+    method public java.io.IOException getCause();
+  }
+
+  public class UnsupportedEncodingException extends java.io.IOException {
+    ctor public UnsupportedEncodingException();
+    ctor public UnsupportedEncodingException(String);
+  }
+
+  public class WriteAbortedException extends java.io.ObjectStreamException {
+    ctor public WriteAbortedException(String, Exception);
+    field public Exception detail;
+  }
+
+  public abstract class Writer implements java.lang.Appendable java.io.Closeable java.io.Flushable {
+    ctor protected Writer();
+    ctor protected Writer(Object);
+    method public java.io.Writer append(CharSequence) throws java.io.IOException;
+    method public java.io.Writer append(CharSequence, int, int) throws java.io.IOException;
+    method public java.io.Writer append(char) throws java.io.IOException;
+    method public void write(int) throws java.io.IOException;
+    method public void write(char[]) throws java.io.IOException;
+    method public abstract void write(char[], int, int) throws java.io.IOException;
+    method public void write(String) throws java.io.IOException;
+    method public void write(String, int, int) throws java.io.IOException;
+    field protected Object lock;
+  }
+
+}
+
+package java.lang {
+
+  public class AbstractMethodError extends java.lang.IncompatibleClassChangeError {
+    ctor public AbstractMethodError();
+    ctor public AbstractMethodError(String);
+  }
+
+  public interface Appendable {
+    method @NonNull public Appendable append(@Nullable CharSequence) throws java.io.IOException;
+    method @NonNull public Appendable append(@Nullable CharSequence, int, int) throws java.io.IOException;
+    method @NonNull public Appendable append(char) throws java.io.IOException;
+  }
+
+  public class ArithmeticException extends java.lang.RuntimeException {
+    ctor public ArithmeticException();
+    ctor public ArithmeticException(String);
+  }
+
+  public class ArrayIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
+    ctor public ArrayIndexOutOfBoundsException();
+    ctor public ArrayIndexOutOfBoundsException(int);
+    ctor public ArrayIndexOutOfBoundsException(String);
+  }
+
+  public class ArrayStoreException extends java.lang.RuntimeException {
+    ctor public ArrayStoreException();
+    ctor public ArrayStoreException(String);
+  }
+
+  public class AssertionError extends java.lang.Error {
+    ctor public AssertionError();
+    ctor public AssertionError(Object);
+    ctor public AssertionError(boolean);
+    ctor public AssertionError(char);
+    ctor public AssertionError(int);
+    ctor public AssertionError(long);
+    ctor public AssertionError(float);
+    ctor public AssertionError(double);
+    ctor public AssertionError(String, Throwable);
+  }
+
+  public interface AutoCloseable {
+    method public void close() throws java.lang.Exception;
+  }
+
+  public final class Boolean implements java.lang.Comparable<java.lang.Boolean> java.io.Serializable {
+    ctor public Boolean(boolean);
+    ctor public Boolean(@Nullable String);
+    method public boolean booleanValue();
+    method public static int compare(boolean, boolean);
+    method public int compareTo(@NonNull Boolean);
+    method public static boolean getBoolean(@NonNull String);
+    method public static int hashCode(boolean);
+    method public static boolean logicalAnd(boolean, boolean);
+    method public static boolean logicalOr(boolean, boolean);
+    method public static boolean logicalXor(boolean, boolean);
+    method public static boolean parseBoolean(@Nullable String);
+    method @NonNull public static String toString(boolean);
+    method @NonNull public static Boolean valueOf(boolean);
+    method @NonNull public static Boolean valueOf(@Nullable String);
+    field public static final Boolean FALSE;
+    field public static final Boolean TRUE;
+    field public static final Class<java.lang.Boolean> TYPE;
+  }
+
+  public class BootstrapMethodError extends java.lang.LinkageError {
+    ctor public BootstrapMethodError();
+    ctor public BootstrapMethodError(String);
+    ctor public BootstrapMethodError(String, Throwable);
+    ctor public BootstrapMethodError(Throwable);
+  }
+
+  public final class Byte extends java.lang.Number implements java.lang.Comparable<java.lang.Byte> {
+    ctor @Deprecated public Byte(byte);
+    ctor @Deprecated public Byte(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int compare(byte, byte);
+    method public int compareTo(@NonNull Byte);
+    method public static int compareUnsigned(byte, byte);
+    method @NonNull public static Byte decode(@NonNull String) throws java.lang.NumberFormatException;
+    method public double doubleValue();
+    method public float floatValue();
+    method public static int hashCode(byte);
+    method public int intValue();
+    method public long longValue();
+    method public static byte parseByte(@NonNull String, int) throws java.lang.NumberFormatException;
+    method public static byte parseByte(@NonNull String) throws java.lang.NumberFormatException;
+    method @NonNull public static String toString(byte);
+    method public static int toUnsignedInt(byte);
+    method public static long toUnsignedLong(byte);
+    method @NonNull public static Byte valueOf(byte);
+    method @NonNull public static Byte valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
+    method @NonNull public static Byte valueOf(@NonNull String) throws java.lang.NumberFormatException;
+    field public static final int BYTES = 1; // 0x1
+    field public static final byte MAX_VALUE = 127; // 0x7f
+    field public static final byte MIN_VALUE = -128; // 0xffffff80
+    field public static final int SIZE = 8; // 0x8
+    field public static final Class<java.lang.Byte> TYPE;
+  }
+
+  public interface CharSequence {
+    method public char charAt(int);
+    method @NonNull public default java.util.stream.IntStream chars();
+    method @NonNull public default java.util.stream.IntStream codePoints();
+    method public int length();
+    method @NonNull public CharSequence subSequence(int, int);
+    method @NonNull public String toString();
+  }
+
+  public final class Character implements java.lang.Comparable<java.lang.Character> java.io.Serializable {
+    ctor public Character(char);
+    method public static int charCount(int);
+    method public char charValue();
+    method public static int codePointAt(@NonNull CharSequence, int);
+    method public static int codePointAt(char[], int);
+    method public static int codePointAt(char[], int, int);
+    method public static int codePointBefore(@NonNull CharSequence, int);
+    method public static int codePointBefore(char[], int);
+    method public static int codePointBefore(char[], int, int);
+    method public static int codePointCount(@NonNull CharSequence, int, int);
+    method public static int codePointCount(char[], int, int);
+    method public static int compare(char, char);
+    method public int compareTo(@NonNull Character);
+    method public static int digit(char, int);
+    method public static int digit(int, int);
+    method public static char forDigit(int, int);
+    method public static byte getDirectionality(char);
+    method public static byte getDirectionality(int);
+    method @Nullable public static String getName(int);
+    method public static int getNumericValue(char);
+    method public static int getNumericValue(int);
+    method public static int getType(char);
+    method public static int getType(int);
+    method public static int hashCode(char);
+    method public static char highSurrogate(int);
+    method public static boolean isAlphabetic(int);
+    method public static boolean isBmpCodePoint(int);
+    method public static boolean isDefined(char);
+    method public static boolean isDefined(int);
+    method public static boolean isDigit(char);
+    method public static boolean isDigit(int);
+    method public static boolean isHighSurrogate(char);
+    method public static boolean isISOControl(char);
+    method public static boolean isISOControl(int);
+    method public static boolean isIdentifierIgnorable(char);
+    method public static boolean isIdentifierIgnorable(int);
+    method public static boolean isIdeographic(int);
+    method public static boolean isJavaIdentifierPart(char);
+    method public static boolean isJavaIdentifierPart(int);
+    method public static boolean isJavaIdentifierStart(char);
+    method public static boolean isJavaIdentifierStart(int);
+    method @Deprecated public static boolean isJavaLetter(char);
+    method @Deprecated public static boolean isJavaLetterOrDigit(char);
+    method public static boolean isLetter(char);
+    method public static boolean isLetter(int);
+    method public static boolean isLetterOrDigit(char);
+    method public static boolean isLetterOrDigit(int);
+    method public static boolean isLowSurrogate(char);
+    method public static boolean isLowerCase(char);
+    method public static boolean isLowerCase(int);
+    method public static boolean isMirrored(char);
+    method public static boolean isMirrored(int);
+    method @Deprecated public static boolean isSpace(char);
+    method public static boolean isSpaceChar(char);
+    method public static boolean isSpaceChar(int);
+    method public static boolean isSupplementaryCodePoint(int);
+    method public static boolean isSurrogate(char);
+    method public static boolean isSurrogatePair(char, char);
+    method public static boolean isTitleCase(char);
+    method public static boolean isTitleCase(int);
+    method public static boolean isUnicodeIdentifierPart(char);
+    method public static boolean isUnicodeIdentifierPart(int);
+    method public static boolean isUnicodeIdentifierStart(char);
+    method public static boolean isUnicodeIdentifierStart(int);
+    method public static boolean isUpperCase(char);
+    method public static boolean isUpperCase(int);
+    method public static boolean isValidCodePoint(int);
+    method public static boolean isWhitespace(char);
+    method public static boolean isWhitespace(int);
+    method public static char lowSurrogate(int);
+    method public static int offsetByCodePoints(@NonNull CharSequence, int, int);
+    method public static int offsetByCodePoints(char[], int, int, int, int);
+    method public static char reverseBytes(char);
+    method public static int toChars(int, char[], int);
+    method public static char[] toChars(int);
+    method public static int toCodePoint(char, char);
+    method public static char toLowerCase(char);
+    method public static int toLowerCase(int);
+    method @NonNull public static String toString(char);
+    method public static char toTitleCase(char);
+    method public static int toTitleCase(int);
+    method public static char toUpperCase(char);
+    method public static int toUpperCase(int);
+    method @NonNull public static Character valueOf(char);
+    field public static final int BYTES = 2; // 0x2
+    field public static final byte COMBINING_SPACING_MARK = 8; // 0x8
+    field public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17
+    field public static final byte CONTROL = 15; // 0xf
+    field public static final byte CURRENCY_SYMBOL = 26; // 0x1a
+    field public static final byte DASH_PUNCTUATION = 20; // 0x14
+    field public static final byte DECIMAL_DIGIT_NUMBER = 9; // 0x9
+    field public static final byte DIRECTIONALITY_ARABIC_NUMBER = 6; // 0x6
+    field public static final byte DIRECTIONALITY_BOUNDARY_NEUTRAL = 9; // 0x9
+    field public static final byte DIRECTIONALITY_COMMON_NUMBER_SEPARATOR = 7; // 0x7
+    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER = 3; // 0x3
+    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR = 4; // 0x4
+    field public static final byte DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR = 5; // 0x5
+    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT = 0; // 0x0
+    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING = 14; // 0xe
+    field public static final byte DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE = 15; // 0xf
+    field public static final byte DIRECTIONALITY_NONSPACING_MARK = 8; // 0x8
+    field public static final byte DIRECTIONALITY_OTHER_NEUTRALS = 13; // 0xd
+    field public static final byte DIRECTIONALITY_PARAGRAPH_SEPARATOR = 10; // 0xa
+    field public static final byte DIRECTIONALITY_POP_DIRECTIONAL_FORMAT = 18; // 0x12
+    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT = 1; // 0x1
+    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC = 2; // 0x2
+    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING = 16; // 0x10
+    field public static final byte DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE = 17; // 0x11
+    field public static final byte DIRECTIONALITY_SEGMENT_SEPARATOR = 11; // 0xb
+    field public static final byte DIRECTIONALITY_UNDEFINED = -1; // 0xffffffff
+    field public static final byte DIRECTIONALITY_WHITESPACE = 12; // 0xc
+    field public static final byte ENCLOSING_MARK = 7; // 0x7
+    field public static final byte END_PUNCTUATION = 22; // 0x16
+    field public static final byte FINAL_QUOTE_PUNCTUATION = 30; // 0x1e
+    field public static final byte FORMAT = 16; // 0x10
+    field public static final byte INITIAL_QUOTE_PUNCTUATION = 29; // 0x1d
+    field public static final byte LETTER_NUMBER = 10; // 0xa
+    field public static final byte LINE_SEPARATOR = 13; // 0xd
+    field public static final byte LOWERCASE_LETTER = 2; // 0x2
+    field public static final byte MATH_SYMBOL = 25; // 0x19
+    field public static final int MAX_CODE_POINT = 1114111; // 0x10ffff
+    field public static final char MAX_HIGH_SURROGATE = 56319; // 0xdbff '\udbff'
+    field public static final char MAX_LOW_SURROGATE = 57343; // 0xdfff '\udfff'
+    field public static final int MAX_RADIX = 36; // 0x24
+    field public static final char MAX_SURROGATE = 57343; // 0xdfff '\udfff'
+    field public static final char MAX_VALUE = 65535; // 0xffff '\uffff'
+    field public static final int MIN_CODE_POINT = 0; // 0x0
+    field public static final char MIN_HIGH_SURROGATE = 55296; // 0xd800 '\ud800'
+    field public static final char MIN_LOW_SURROGATE = 56320; // 0xdc00 '\udc00'
+    field public static final int MIN_RADIX = 2; // 0x2
+    field public static final int MIN_SUPPLEMENTARY_CODE_POINT = 65536; // 0x10000
+    field public static final char MIN_SURROGATE = 55296; // 0xd800 '\ud800'
+    field public static final char MIN_VALUE = 0; // 0x0000 '\u0000'
+    field public static final byte MODIFIER_LETTER = 4; // 0x4
+    field public static final byte MODIFIER_SYMBOL = 27; // 0x1b
+    field public static final byte NON_SPACING_MARK = 6; // 0x6
+    field public static final byte OTHER_LETTER = 5; // 0x5
+    field public static final byte OTHER_NUMBER = 11; // 0xb
+    field public static final byte OTHER_PUNCTUATION = 24; // 0x18
+    field public static final byte OTHER_SYMBOL = 28; // 0x1c
+    field public static final byte PARAGRAPH_SEPARATOR = 14; // 0xe
+    field public static final byte PRIVATE_USE = 18; // 0x12
+    field public static final int SIZE = 16; // 0x10
+    field public static final byte SPACE_SEPARATOR = 12; // 0xc
+    field public static final byte START_PUNCTUATION = 21; // 0x15
+    field public static final byte SURROGATE = 19; // 0x13
+    field public static final byte TITLECASE_LETTER = 3; // 0x3
+    field public static final Class<java.lang.Character> TYPE;
+    field public static final byte UNASSIGNED = 0; // 0x0
+    field public static final byte UPPERCASE_LETTER = 1; // 0x1
+  }
+
+  public static class Character.Subset {
+    ctor protected Character.Subset(@NonNull String);
+    method public final boolean equals(@Nullable Object);
+    method public final int hashCode();
+    method @NonNull public final String toString();
+  }
+
+  public static final class Character.UnicodeBlock extends java.lang.Character.Subset {
+    method @NonNull public static java.lang.Character.UnicodeBlock forName(@NonNull String);
+    method @Nullable public static java.lang.Character.UnicodeBlock of(char);
+    method @Nullable public static java.lang.Character.UnicodeBlock of(int);
+    field public static final java.lang.Character.UnicodeBlock AEGEAN_NUMBERS;
+    field public static final java.lang.Character.UnicodeBlock ALCHEMICAL_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock ALPHABETIC_PRESENTATION_FORMS;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_MUSICAL_NOTATION;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_GREEK_NUMBERS;
+    field public static final java.lang.Character.UnicodeBlock ANCIENT_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock ARABIC;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_MATHEMATICAL_ALPHABETIC_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_A;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_PRESENTATION_FORMS_B;
+    field public static final java.lang.Character.UnicodeBlock ARABIC_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock ARMENIAN;
+    field public static final java.lang.Character.UnicodeBlock ARROWS;
+    field public static final java.lang.Character.UnicodeBlock AVESTAN;
+    field public static final java.lang.Character.UnicodeBlock BALINESE;
+    field public static final java.lang.Character.UnicodeBlock BAMUM;
+    field public static final java.lang.Character.UnicodeBlock BAMUM_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock BASIC_LATIN;
+    field public static final java.lang.Character.UnicodeBlock BATAK;
+    field public static final java.lang.Character.UnicodeBlock BENGALI;
+    field public static final java.lang.Character.UnicodeBlock BLOCK_ELEMENTS;
+    field public static final java.lang.Character.UnicodeBlock BOPOMOFO;
+    field public static final java.lang.Character.UnicodeBlock BOPOMOFO_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock BOX_DRAWING;
+    field public static final java.lang.Character.UnicodeBlock BRAHMI;
+    field public static final java.lang.Character.UnicodeBlock BRAILLE_PATTERNS;
+    field public static final java.lang.Character.UnicodeBlock BUGINESE;
+    field public static final java.lang.Character.UnicodeBlock BUHID;
+    field public static final java.lang.Character.UnicodeBlock BYZANTINE_MUSICAL_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock CARIAN;
+    field public static final java.lang.Character.UnicodeBlock CHAKMA;
+    field public static final java.lang.Character.UnicodeBlock CHAM;
+    field public static final java.lang.Character.UnicodeBlock CHEROKEE;
+    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY;
+    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_FORMS;
+    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS;
+    field public static final java.lang.Character.UnicodeBlock CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock CJK_RADICALS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock CJK_STROKES;
+    field public static final java.lang.Character.UnicodeBlock CJK_SYMBOLS_AND_PUNCTUATION;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C;
+    field public static final java.lang.Character.UnicodeBlock CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D;
+    field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS;
+    field public static final java.lang.Character.UnicodeBlock COMBINING_DIACRITICAL_MARKS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock COMBINING_HALF_MARKS;
+    field public static final java.lang.Character.UnicodeBlock COMBINING_MARKS_FOR_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock COMMON_INDIC_NUMBER_FORMS;
+    field public static final java.lang.Character.UnicodeBlock CONTROL_PICTURES;
+    field public static final java.lang.Character.UnicodeBlock COPTIC;
+    field public static final java.lang.Character.UnicodeBlock COUNTING_ROD_NUMERALS;
+    field public static final java.lang.Character.UnicodeBlock CUNEIFORM;
+    field public static final java.lang.Character.UnicodeBlock CUNEIFORM_NUMBERS_AND_PUNCTUATION;
+    field public static final java.lang.Character.UnicodeBlock CURRENCY_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock CYPRIOT_SYLLABARY;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC_EXTENDED_B;
+    field public static final java.lang.Character.UnicodeBlock CYRILLIC_SUPPLEMENTARY;
+    field public static final java.lang.Character.UnicodeBlock DESERET;
+    field public static final java.lang.Character.UnicodeBlock DEVANAGARI;
+    field public static final java.lang.Character.UnicodeBlock DEVANAGARI_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock DINGBATS;
+    field public static final java.lang.Character.UnicodeBlock DOMINO_TILES;
+    field public static final java.lang.Character.UnicodeBlock EGYPTIAN_HIEROGLYPHS;
+    field public static final java.lang.Character.UnicodeBlock EMOTICONS;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERICS;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_ALPHANUMERIC_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_CJK_LETTERS_AND_MONTHS;
+    field public static final java.lang.Character.UnicodeBlock ENCLOSED_IDEOGRAPHIC_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock ETHIOPIC_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock GENERAL_PUNCTUATION;
+    field public static final java.lang.Character.UnicodeBlock GEOMETRIC_SHAPES;
+    field public static final java.lang.Character.UnicodeBlock GEORGIAN;
+    field public static final java.lang.Character.UnicodeBlock GEORGIAN_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock GLAGOLITIC;
+    field public static final java.lang.Character.UnicodeBlock GOTHIC;
+    field public static final java.lang.Character.UnicodeBlock GREEK;
+    field public static final java.lang.Character.UnicodeBlock GREEK_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock GUJARATI;
+    field public static final java.lang.Character.UnicodeBlock GURMUKHI;
+    field public static final java.lang.Character.UnicodeBlock HALFWIDTH_AND_FULLWIDTH_FORMS;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_COMPATIBILITY_JAMO;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_JAMO_EXTENDED_B;
+    field public static final java.lang.Character.UnicodeBlock HANGUL_SYLLABLES;
+    field public static final java.lang.Character.UnicodeBlock HANUNOO;
+    field public static final java.lang.Character.UnicodeBlock HEBREW;
+    field public static final java.lang.Character.UnicodeBlock HIGH_PRIVATE_USE_SURROGATES;
+    field public static final java.lang.Character.UnicodeBlock HIGH_SURROGATES;
+    field public static final java.lang.Character.UnicodeBlock HIRAGANA;
+    field public static final java.lang.Character.UnicodeBlock IDEOGRAPHIC_DESCRIPTION_CHARACTERS;
+    field public static final java.lang.Character.UnicodeBlock IMPERIAL_ARAMAIC;
+    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PAHLAVI;
+    field public static final java.lang.Character.UnicodeBlock INSCRIPTIONAL_PARTHIAN;
+    field public static final java.lang.Character.UnicodeBlock IPA_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock JAVANESE;
+    field public static final java.lang.Character.UnicodeBlock KAITHI;
+    field public static final java.lang.Character.UnicodeBlock KANA_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock KANBUN;
+    field public static final java.lang.Character.UnicodeBlock KANGXI_RADICALS;
+    field public static final java.lang.Character.UnicodeBlock KANNADA;
+    field public static final java.lang.Character.UnicodeBlock KATAKANA;
+    field public static final java.lang.Character.UnicodeBlock KATAKANA_PHONETIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock KAYAH_LI;
+    field public static final java.lang.Character.UnicodeBlock KHAROSHTHI;
+    field public static final java.lang.Character.UnicodeBlock KHMER;
+    field public static final java.lang.Character.UnicodeBlock KHMER_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock LAO;
+    field public static final java.lang.Character.UnicodeBlock LATIN_1_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_ADDITIONAL;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_B;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_C;
+    field public static final java.lang.Character.UnicodeBlock LATIN_EXTENDED_D;
+    field public static final java.lang.Character.UnicodeBlock LEPCHA;
+    field public static final java.lang.Character.UnicodeBlock LETTERLIKE_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock LIMBU;
+    field public static final java.lang.Character.UnicodeBlock LINEAR_B_IDEOGRAMS;
+    field public static final java.lang.Character.UnicodeBlock LINEAR_B_SYLLABARY;
+    field public static final java.lang.Character.UnicodeBlock LISU;
+    field public static final java.lang.Character.UnicodeBlock LOW_SURROGATES;
+    field public static final java.lang.Character.UnicodeBlock LYCIAN;
+    field public static final java.lang.Character.UnicodeBlock LYDIAN;
+    field public static final java.lang.Character.UnicodeBlock MAHJONG_TILES;
+    field public static final java.lang.Character.UnicodeBlock MALAYALAM;
+    field public static final java.lang.Character.UnicodeBlock MANDAIC;
+    field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_ALPHANUMERIC_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock MATHEMATICAL_OPERATORS;
+    field public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK;
+    field public static final java.lang.Character.UnicodeBlock MEETEI_MAYEK_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock MEROITIC_CURSIVE;
+    field public static final java.lang.Character.UnicodeBlock MEROITIC_HIEROGLYPHS;
+    field public static final java.lang.Character.UnicodeBlock MIAO;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_ARROWS;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS;
+    field public static final java.lang.Character.UnicodeBlock MISCELLANEOUS_TECHNICAL;
+    field public static final java.lang.Character.UnicodeBlock MODIFIER_TONE_LETTERS;
+    field public static final java.lang.Character.UnicodeBlock MONGOLIAN;
+    field public static final java.lang.Character.UnicodeBlock MUSICAL_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock MYANMAR;
+    field public static final java.lang.Character.UnicodeBlock MYANMAR_EXTENDED_A;
+    field public static final java.lang.Character.UnicodeBlock NEW_TAI_LUE;
+    field public static final java.lang.Character.UnicodeBlock NKO;
+    field public static final java.lang.Character.UnicodeBlock NUMBER_FORMS;
+    field public static final java.lang.Character.UnicodeBlock OGHAM;
+    field public static final java.lang.Character.UnicodeBlock OLD_ITALIC;
+    field public static final java.lang.Character.UnicodeBlock OLD_PERSIAN;
+    field public static final java.lang.Character.UnicodeBlock OLD_SOUTH_ARABIAN;
+    field public static final java.lang.Character.UnicodeBlock OLD_TURKIC;
+    field public static final java.lang.Character.UnicodeBlock OL_CHIKI;
+    field public static final java.lang.Character.UnicodeBlock OPTICAL_CHARACTER_RECOGNITION;
+    field public static final java.lang.Character.UnicodeBlock ORIYA;
+    field public static final java.lang.Character.UnicodeBlock OSMANYA;
+    field public static final java.lang.Character.UnicodeBlock PHAGS_PA;
+    field public static final java.lang.Character.UnicodeBlock PHAISTOS_DISC;
+    field public static final java.lang.Character.UnicodeBlock PHOENICIAN;
+    field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock PHONETIC_EXTENSIONS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock PLAYING_CARDS;
+    field public static final java.lang.Character.UnicodeBlock PRIVATE_USE_AREA;
+    field public static final java.lang.Character.UnicodeBlock REJANG;
+    field public static final java.lang.Character.UnicodeBlock RUMI_NUMERAL_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock RUNIC;
+    field public static final java.lang.Character.UnicodeBlock SAMARITAN;
+    field public static final java.lang.Character.UnicodeBlock SAURASHTRA;
+    field public static final java.lang.Character.UnicodeBlock SHARADA;
+    field public static final java.lang.Character.UnicodeBlock SHAVIAN;
+    field public static final java.lang.Character.UnicodeBlock SINHALA;
+    field public static final java.lang.Character.UnicodeBlock SMALL_FORM_VARIANTS;
+    field public static final java.lang.Character.UnicodeBlock SORA_SOMPENG;
+    field public static final java.lang.Character.UnicodeBlock SPACING_MODIFIER_LETTERS;
+    field public static final java.lang.Character.UnicodeBlock SPECIALS;
+    field public static final java.lang.Character.UnicodeBlock SUNDANESE;
+    field public static final java.lang.Character.UnicodeBlock SUNDANESE_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock SUPERSCRIPTS_AND_SUBSCRIPTS;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_A;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_ARROWS_B;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_MATHEMATICAL_OPERATORS;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTAL_PUNCTUATION;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_A;
+    field public static final java.lang.Character.UnicodeBlock SUPPLEMENTARY_PRIVATE_USE_AREA_B;
+    field @Deprecated public static final java.lang.Character.UnicodeBlock SURROGATES_AREA;
+    field public static final java.lang.Character.UnicodeBlock SYLOTI_NAGRI;
+    field public static final java.lang.Character.UnicodeBlock SYRIAC;
+    field public static final java.lang.Character.UnicodeBlock TAGALOG;
+    field public static final java.lang.Character.UnicodeBlock TAGBANWA;
+    field public static final java.lang.Character.UnicodeBlock TAGS;
+    field public static final java.lang.Character.UnicodeBlock TAI_LE;
+    field public static final java.lang.Character.UnicodeBlock TAI_THAM;
+    field public static final java.lang.Character.UnicodeBlock TAI_VIET;
+    field public static final java.lang.Character.UnicodeBlock TAI_XUAN_JING_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock TAKRI;
+    field public static final java.lang.Character.UnicodeBlock TAMIL;
+    field public static final java.lang.Character.UnicodeBlock TELUGU;
+    field public static final java.lang.Character.UnicodeBlock THAANA;
+    field public static final java.lang.Character.UnicodeBlock THAI;
+    field public static final java.lang.Character.UnicodeBlock TIBETAN;
+    field public static final java.lang.Character.UnicodeBlock TIFINAGH;
+    field public static final java.lang.Character.UnicodeBlock TRANSPORT_AND_MAP_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock UGARITIC;
+    field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS;
+    field public static final java.lang.Character.UnicodeBlock UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS_EXTENDED;
+    field public static final java.lang.Character.UnicodeBlock VAI;
+    field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS;
+    field public static final java.lang.Character.UnicodeBlock VARIATION_SELECTORS_SUPPLEMENT;
+    field public static final java.lang.Character.UnicodeBlock VEDIC_EXTENSIONS;
+    field public static final java.lang.Character.UnicodeBlock VERTICAL_FORMS;
+    field public static final java.lang.Character.UnicodeBlock YIJING_HEXAGRAM_SYMBOLS;
+    field public static final java.lang.Character.UnicodeBlock YI_RADICALS;
+    field public static final java.lang.Character.UnicodeBlock YI_SYLLABLES;
+  }
+
+  public enum Character.UnicodeScript {
+    method @NonNull public static java.lang.Character.UnicodeScript forName(@NonNull String);
+    method @NonNull public static java.lang.Character.UnicodeScript of(int);
+    enum_constant public static final java.lang.Character.UnicodeScript ARABIC;
+    enum_constant public static final java.lang.Character.UnicodeScript ARMENIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript AVESTAN;
+    enum_constant public static final java.lang.Character.UnicodeScript BALINESE;
+    enum_constant public static final java.lang.Character.UnicodeScript BAMUM;
+    enum_constant public static final java.lang.Character.UnicodeScript BATAK;
+    enum_constant public static final java.lang.Character.UnicodeScript BENGALI;
+    enum_constant public static final java.lang.Character.UnicodeScript BOPOMOFO;
+    enum_constant public static final java.lang.Character.UnicodeScript BRAHMI;
+    enum_constant public static final java.lang.Character.UnicodeScript BRAILLE;
+    enum_constant public static final java.lang.Character.UnicodeScript BUGINESE;
+    enum_constant public static final java.lang.Character.UnicodeScript BUHID;
+    enum_constant public static final java.lang.Character.UnicodeScript CANADIAN_ABORIGINAL;
+    enum_constant public static final java.lang.Character.UnicodeScript CARIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript CHAKMA;
+    enum_constant public static final java.lang.Character.UnicodeScript CHAM;
+    enum_constant public static final java.lang.Character.UnicodeScript CHEROKEE;
+    enum_constant public static final java.lang.Character.UnicodeScript COMMON;
+    enum_constant public static final java.lang.Character.UnicodeScript COPTIC;
+    enum_constant public static final java.lang.Character.UnicodeScript CUNEIFORM;
+    enum_constant public static final java.lang.Character.UnicodeScript CYPRIOT;
+    enum_constant public static final java.lang.Character.UnicodeScript CYRILLIC;
+    enum_constant public static final java.lang.Character.UnicodeScript DESERET;
+    enum_constant public static final java.lang.Character.UnicodeScript DEVANAGARI;
+    enum_constant public static final java.lang.Character.UnicodeScript EGYPTIAN_HIEROGLYPHS;
+    enum_constant public static final java.lang.Character.UnicodeScript ETHIOPIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GEORGIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript GLAGOLITIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GOTHIC;
+    enum_constant public static final java.lang.Character.UnicodeScript GREEK;
+    enum_constant public static final java.lang.Character.UnicodeScript GUJARATI;
+    enum_constant public static final java.lang.Character.UnicodeScript GURMUKHI;
+    enum_constant public static final java.lang.Character.UnicodeScript HAN;
+    enum_constant public static final java.lang.Character.UnicodeScript HANGUL;
+    enum_constant public static final java.lang.Character.UnicodeScript HANUNOO;
+    enum_constant public static final java.lang.Character.UnicodeScript HEBREW;
+    enum_constant public static final java.lang.Character.UnicodeScript HIRAGANA;
+    enum_constant public static final java.lang.Character.UnicodeScript IMPERIAL_ARAMAIC;
+    enum_constant public static final java.lang.Character.UnicodeScript INHERITED;
+    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PAHLAVI;
+    enum_constant public static final java.lang.Character.UnicodeScript INSCRIPTIONAL_PARTHIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript JAVANESE;
+    enum_constant public static final java.lang.Character.UnicodeScript KAITHI;
+    enum_constant public static final java.lang.Character.UnicodeScript KANNADA;
+    enum_constant public static final java.lang.Character.UnicodeScript KATAKANA;
+    enum_constant public static final java.lang.Character.UnicodeScript KAYAH_LI;
+    enum_constant public static final java.lang.Character.UnicodeScript KHAROSHTHI;
+    enum_constant public static final java.lang.Character.UnicodeScript KHMER;
+    enum_constant public static final java.lang.Character.UnicodeScript LAO;
+    enum_constant public static final java.lang.Character.UnicodeScript LATIN;
+    enum_constant public static final java.lang.Character.UnicodeScript LEPCHA;
+    enum_constant public static final java.lang.Character.UnicodeScript LIMBU;
+    enum_constant public static final java.lang.Character.UnicodeScript LINEAR_B;
+    enum_constant public static final java.lang.Character.UnicodeScript LISU;
+    enum_constant public static final java.lang.Character.UnicodeScript LYCIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript LYDIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript MALAYALAM;
+    enum_constant public static final java.lang.Character.UnicodeScript MANDAIC;
+    enum_constant public static final java.lang.Character.UnicodeScript MEETEI_MAYEK;
+    enum_constant public static final java.lang.Character.UnicodeScript MEROITIC_CURSIVE;
+    enum_constant public static final java.lang.Character.UnicodeScript MEROITIC_HIEROGLYPHS;
+    enum_constant public static final java.lang.Character.UnicodeScript MIAO;
+    enum_constant public static final java.lang.Character.UnicodeScript MONGOLIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript MYANMAR;
+    enum_constant public static final java.lang.Character.UnicodeScript NEW_TAI_LUE;
+    enum_constant public static final java.lang.Character.UnicodeScript NKO;
+    enum_constant public static final java.lang.Character.UnicodeScript OGHAM;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_ITALIC;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_PERSIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_SOUTH_ARABIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript OLD_TURKIC;
+    enum_constant public static final java.lang.Character.UnicodeScript OL_CHIKI;
+    enum_constant public static final java.lang.Character.UnicodeScript ORIYA;
+    enum_constant public static final java.lang.Character.UnicodeScript OSMANYA;
+    enum_constant public static final java.lang.Character.UnicodeScript PHAGS_PA;
+    enum_constant public static final java.lang.Character.UnicodeScript PHOENICIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript REJANG;
+    enum_constant public static final java.lang.Character.UnicodeScript RUNIC;
+    enum_constant public static final java.lang.Character.UnicodeScript SAMARITAN;
+    enum_constant public static final java.lang.Character.UnicodeScript SAURASHTRA;
+    enum_constant public static final java.lang.Character.UnicodeScript SHARADA;
+    enum_constant public static final java.lang.Character.UnicodeScript SHAVIAN;
+    enum_constant public static final java.lang.Character.UnicodeScript SINHALA;
+    enum_constant public static final java.lang.Character.UnicodeScript SORA_SOMPENG;
+    enum_constant public static final java.lang.Character.UnicodeScript SUNDANESE;
+    enum_constant public static final java.lang.Character.UnicodeScript SYLOTI_NAGRI;
+    enum_constant public static final java.lang.Character.UnicodeScript SYRIAC;
+    enum_constant public static final java.lang.Character.UnicodeScript TAGALOG;
+    enum_constant public static final java.lang.Character.UnicodeScript TAGBANWA;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_LE;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_THAM;
+    enum_constant public static final java.lang.Character.UnicodeScript TAI_VIET;
+    enum_constant public static final java.lang.Character.UnicodeScript TAKRI;
+    enum_constant public static final java.lang.Character.UnicodeScript TAMIL;
+    enum_constant public static final java.lang.Character.UnicodeScript TELUGU;
+    enum_constant public static final java.lang.Character.UnicodeScript THAANA;
+    enum_constant public static final java.lang.Character.UnicodeScript THAI;
+    enum_constant public static final java.lang.Character.UnicodeScript TIBETAN;
+    enum_constant public static final java.lang.Character.UnicodeScript TIFINAGH;
+    enum_constant public static final java.lang.Character.UnicodeScript UGARITIC;
+    enum_constant public static final java.lang.Character.UnicodeScript UNKNOWN;
+    enum_constant public static final java.lang.Character.UnicodeScript VAI;
+    enum_constant public static final java.lang.Character.UnicodeScript YI;
+  }
+
+  public final class Class<T> implements java.lang.reflect.AnnotatedElement java.lang.reflect.GenericDeclaration java.io.Serializable java.lang.reflect.Type {
+    method @NonNull public <U> Class<? extends U> asSubclass(@NonNull Class<U>);
+    method @Nullable public T cast(@Nullable Object);
+    method public boolean desiredAssertionStatus();
+    method @NonNull public static Class<?> forName(@NonNull String) throws java.lang.ClassNotFoundException;
+    method @NonNull public static Class<?> forName(@NonNull String, boolean, @Nullable ClassLoader) throws java.lang.ClassNotFoundException;
+    method @Nullable public <A extends java.lang.annotation.Annotation> A getAnnotation(@NonNull Class<A>);
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(@NonNull Class<A>);
+    method @Nullable public String getCanonicalName();
+    method @Nullable public ClassLoader getClassLoader();
+    method @NonNull public Class<?>[] getClasses();
+    method @Nullable public Class<?> getComponentType();
+    method @NonNull public java.lang.reflect.Constructor<T> getConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Constructor<?>[] getConstructors() throws java.lang.SecurityException;
+    method @Nullable public <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(@NonNull Class<A>);
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public Class<?>[] getDeclaredClasses();
+    method @NonNull public java.lang.reflect.Constructor<T> getDeclaredConstructor(@Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Constructor<?>[] getDeclaredConstructors() throws java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Field getDeclaredField(@NonNull String) throws java.lang.NoSuchFieldException;
+    method @NonNull public java.lang.reflect.Field[] getDeclaredFields();
+    method @NonNull public java.lang.reflect.Method getDeclaredMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Method[] getDeclaredMethods() throws java.lang.SecurityException;
+    method @Nullable public Class<?> getDeclaringClass();
+    method @Nullable public Class<?> getEnclosingClass();
+    method @Nullable public java.lang.reflect.Constructor<?> getEnclosingConstructor();
+    method @Nullable public java.lang.reflect.Method getEnclosingMethod();
+    method @Nullable public T[] getEnumConstants();
+    method @NonNull public java.lang.reflect.Field getField(@NonNull String) throws java.lang.NoSuchFieldException;
+    method @NonNull public java.lang.reflect.Field[] getFields() throws java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Type[] getGenericInterfaces();
+    method @Nullable public java.lang.reflect.Type getGenericSuperclass();
+    method @NonNull public Class<?>[] getInterfaces();
+    method @NonNull public java.lang.reflect.Method getMethod(@NonNull String, @Nullable Class<?>...) throws java.lang.NoSuchMethodException, java.lang.SecurityException;
+    method @NonNull public java.lang.reflect.Method[] getMethods() throws java.lang.SecurityException;
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method @Nullable public Package getPackage();
+    method @NonNull public String getPackageName();
+    method @Nullable public java.security.ProtectionDomain getProtectionDomain();
+    method @Nullable public java.net.URL getResource(@NonNull String);
+    method @Nullable public java.io.InputStream getResourceAsStream(@NonNull String);
+    method @Nullable public Object[] getSigners();
+    method @NonNull public String getSimpleName();
+    method @Nullable public Class<? super T> getSuperclass();
+    method @NonNull public java.lang.reflect.TypeVariable<java.lang.Class<T>>[] getTypeParameters();
+    method public boolean isAnnotation();
+    method public boolean isAnonymousClass();
+    method public boolean isArray();
+    method public boolean isAssignableFrom(@NonNull Class<?>);
+    method public boolean isEnum();
+    method public boolean isInstance(@Nullable Object);
+    method public boolean isInterface();
+    method public boolean isLocalClass();
+    method public boolean isMemberClass();
+    method public boolean isPrimitive();
+    method public boolean isSynthetic();
+    method @NonNull public T newInstance() throws java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method @NonNull public String toGenericString();
+  }
+
+  public class ClassCastException extends java.lang.RuntimeException {
+    ctor public ClassCastException();
+    ctor public ClassCastException(String);
+  }
+
+  public class ClassCircularityError extends java.lang.LinkageError {
+    ctor public ClassCircularityError();
+    ctor public ClassCircularityError(String);
+  }
+
+  public class ClassFormatError extends java.lang.LinkageError {
+    ctor public ClassFormatError();
+    ctor public ClassFormatError(String);
+  }
+
+  public abstract class ClassLoader {
+    ctor protected ClassLoader(ClassLoader);
+    ctor protected ClassLoader();
+    method public void clearAssertionStatus();
+    method @Deprecated protected final Class<?> defineClass(byte[], int, int) throws java.lang.ClassFormatError;
+    method protected final Class<?> defineClass(String, byte[], int, int) throws java.lang.ClassFormatError;
+    method protected final Class<?> defineClass(String, byte[], int, int, java.security.ProtectionDomain) throws java.lang.ClassFormatError;
+    method protected final Class<?> defineClass(String, java.nio.ByteBuffer, java.security.ProtectionDomain) throws java.lang.ClassFormatError;
+    method protected Package definePackage(String, String, String, String, String, String, String, java.net.URL) throws java.lang.IllegalArgumentException;
+    method protected Class<?> findClass(String) throws java.lang.ClassNotFoundException;
+    method protected String findLibrary(String);
+    method protected final Class<?> findLoadedClass(String);
+    method protected java.net.URL findResource(String);
+    method protected java.util.Enumeration<java.net.URL> findResources(String) throws java.io.IOException;
+    method protected final Class<?> findSystemClass(String) throws java.lang.ClassNotFoundException;
+    method protected Package getPackage(String);
+    method protected Package[] getPackages();
+    method public final ClassLoader getParent();
+    method public java.net.URL getResource(String);
+    method public java.io.InputStream getResourceAsStream(String);
+    method public java.util.Enumeration<java.net.URL> getResources(String) throws java.io.IOException;
+    method public static ClassLoader getSystemClassLoader();
+    method public static java.net.URL getSystemResource(String);
+    method public static java.io.InputStream getSystemResourceAsStream(String);
+    method public static java.util.Enumeration<java.net.URL> getSystemResources(String) throws java.io.IOException;
+    method public Class<?> loadClass(String) throws java.lang.ClassNotFoundException;
+    method protected Class<?> loadClass(String, boolean) throws java.lang.ClassNotFoundException;
+    method protected static boolean registerAsParallelCapable();
+    method protected final void resolveClass(Class<?>);
+    method public void setClassAssertionStatus(String, boolean);
+    method public void setDefaultAssertionStatus(boolean);
+    method public void setPackageAssertionStatus(String, boolean);
+    method protected final void setSigners(Class<?>, Object[]);
+  }
+
+  public class ClassNotFoundException extends java.lang.ReflectiveOperationException {
+    ctor public ClassNotFoundException();
+    ctor public ClassNotFoundException(String);
+    ctor public ClassNotFoundException(String, Throwable);
+    method public Throwable getException();
+  }
+
+  public class CloneNotSupportedException extends java.lang.Exception {
+    ctor public CloneNotSupportedException();
+    ctor public CloneNotSupportedException(String);
+  }
+
+  public interface Cloneable {
+  }
+
+  public interface Comparable<T> {
+    method public int compareTo(T);
+  }
+
+  public final class Compiler {
+    method public static Object command(Object);
+    method public static boolean compileClass(Class<?>);
+    method public static boolean compileClasses(String);
+    method public static void disable();
+    method public static void enable();
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.LOCAL_VARIABLE, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PACKAGE, java.lang.annotation.ElementType.MODULE, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE}) public @interface Deprecated {
+    method public abstract boolean forRemoval() default false;
+    method public abstract String since() default "";
+  }
+
+  public final class Double extends java.lang.Number implements java.lang.Comparable<java.lang.Double> {
+    ctor public Double(double);
+    ctor public Double(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int compare(double, double);
+    method public int compareTo(@NonNull Double);
+    method public static long doubleToLongBits(double);
+    method public static long doubleToRawLongBits(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public static int hashCode(double);
+    method public int intValue();
+    method public static boolean isFinite(double);
+    method public static boolean isInfinite(double);
+    method public boolean isInfinite();
+    method public static boolean isNaN(double);
+    method public boolean isNaN();
+    method public static double longBitsToDouble(long);
+    method public long longValue();
+    method public static double max(double, double);
+    method public static double min(double, double);
+    method public static double parseDouble(@NonNull String) throws java.lang.NumberFormatException;
+    method public static double sum(double, double);
+    method @NonNull public static String toHexString(double);
+    method @NonNull public static String toString(double);
+    method @NonNull public static Double valueOf(@NonNull String) throws java.lang.NumberFormatException;
+    method @NonNull public static Double valueOf(double);
+    field public static final int BYTES = 8; // 0x8
+    field public static final int MAX_EXPONENT = 1023; // 0x3ff
+    field public static final double MAX_VALUE = 1.7976931348623157E308;
+    field public static final int MIN_EXPONENT = -1022; // 0xfffffc02
+    field public static final double MIN_NORMAL = 2.2250738585072014E-308;
+    field public static final double MIN_VALUE = 4.9E-324;
+    field public static final double NEGATIVE_INFINITY = (-1.0/0.0);
+    field public static final double NaN = (0.0/0.0);
+    field public static final double POSITIVE_INFINITY = (1.0/0.0);
+    field public static final int SIZE = 64; // 0x40
+    field public static final Class<java.lang.Double> TYPE;
+  }
+
+  public abstract class Enum<E extends java.lang.Enum<E>> implements java.lang.Comparable<E> java.io.Serializable {
+    ctor protected Enum(@NonNull String, int);
+    method @NonNull protected final Object clone() throws java.lang.CloneNotSupportedException;
+    method public final int compareTo(E);
+    method public final boolean equals(@Nullable Object);
+    method protected final void finalize();
+    method @NonNull public final Class<E> getDeclaringClass();
+    method public final int hashCode();
+    method @NonNull public final String name();
+    method public final int ordinal();
+    method @NonNull public static <T extends java.lang.Enum<T>> T valueOf(@NonNull Class<T>, @NonNull String);
+  }
+
+  public class EnumConstantNotPresentException extends java.lang.RuntimeException {
+    ctor public EnumConstantNotPresentException(Class<? extends java.lang.Enum>, String);
+    method public String constantName();
+    method public Class<? extends java.lang.Enum> enumType();
+  }
+
+  public class Error extends java.lang.Throwable {
+    ctor public Error();
+    ctor public Error(String);
+    ctor public Error(String, Throwable);
+    ctor public Error(Throwable);
+    ctor protected Error(String, Throwable, boolean, boolean);
+  }
+
+  public class Exception extends java.lang.Throwable {
+    ctor public Exception();
+    ctor public Exception(String);
+    ctor public Exception(String, Throwable);
+    ctor public Exception(Throwable);
+    ctor protected Exception(String, Throwable, boolean, boolean);
+  }
+
+  public class ExceptionInInitializerError extends java.lang.LinkageError {
+    ctor public ExceptionInInitializerError();
+    ctor public ExceptionInInitializerError(Throwable);
+    ctor public ExceptionInInitializerError(String);
+    method public Throwable getException();
+  }
+
+  public final class Float extends java.lang.Number implements java.lang.Comparable<java.lang.Float> {
+    ctor public Float(float);
+    ctor public Float(double);
+    ctor public Float(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int compare(float, float);
+    method public int compareTo(@NonNull Float);
+    method public double doubleValue();
+    method public static int floatToIntBits(float);
+    method public static int floatToRawIntBits(float);
+    method public float floatValue();
+    method public static int hashCode(float);
+    method public static float intBitsToFloat(int);
+    method public int intValue();
+    method public static boolean isFinite(float);
+    method public static boolean isInfinite(float);
+    method public boolean isInfinite();
+    method public static boolean isNaN(float);
+    method public boolean isNaN();
+    method public long longValue();
+    method public static float max(float, float);
+    method public static float min(float, float);
+    method public static float parseFloat(@NonNull String) throws java.lang.NumberFormatException;
+    method public static float sum(float, float);
+    method @NonNull public static String toHexString(float);
+    method @NonNull public static String toString(float);
+    method @NonNull public static Float valueOf(@NonNull String) throws java.lang.NumberFormatException;
+    method @NonNull public static Float valueOf(float);
+    field public static final int BYTES = 4; // 0x4
+    field public static final int MAX_EXPONENT = 127; // 0x7f
+    field public static final float MAX_VALUE = 3.4028235E38f;
+    field public static final int MIN_EXPONENT = -126; // 0xffffff82
+    field public static final float MIN_NORMAL = 1.17549435E-38f;
+    field public static final float MIN_VALUE = 1.4E-45f;
+    field public static final float NEGATIVE_INFINITY = (-1.0f/0.0f);
+    field public static final float NaN = (0.0f/0.0f);
+    field public static final float POSITIVE_INFINITY = (1.0f/0.0f);
+    field public static final int SIZE = 32; // 0x20
+    field public static final Class<java.lang.Float> TYPE;
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.TYPE) public @interface FunctionalInterface {
+  }
+
+  public class IllegalAccessError extends java.lang.IncompatibleClassChangeError {
+    ctor public IllegalAccessError();
+    ctor public IllegalAccessError(String);
+  }
+
+  public class IllegalAccessException extends java.lang.ReflectiveOperationException {
+    ctor public IllegalAccessException();
+    ctor public IllegalAccessException(String);
+  }
+
+  public class IllegalArgumentException extends java.lang.RuntimeException {
+    ctor public IllegalArgumentException();
+    ctor public IllegalArgumentException(String);
+    ctor public IllegalArgumentException(String, Throwable);
+    ctor public IllegalArgumentException(Throwable);
+  }
+
+  public class IllegalMonitorStateException extends java.lang.RuntimeException {
+    ctor public IllegalMonitorStateException();
+    ctor public IllegalMonitorStateException(String);
+  }
+
+  public class IllegalStateException extends java.lang.RuntimeException {
+    ctor public IllegalStateException();
+    ctor public IllegalStateException(String);
+    ctor public IllegalStateException(String, Throwable);
+    ctor public IllegalStateException(Throwable);
+  }
+
+  public class IllegalThreadStateException extends java.lang.IllegalArgumentException {
+    ctor public IllegalThreadStateException();
+    ctor public IllegalThreadStateException(String);
+  }
+
+  public class IncompatibleClassChangeError extends java.lang.LinkageError {
+    ctor public IncompatibleClassChangeError();
+    ctor public IncompatibleClassChangeError(String);
+  }
+
+  public class IndexOutOfBoundsException extends java.lang.RuntimeException {
+    ctor public IndexOutOfBoundsException();
+    ctor public IndexOutOfBoundsException(String);
+  }
+
+  public class InheritableThreadLocal<T> extends java.lang.ThreadLocal<T> {
+    ctor public InheritableThreadLocal();
+    method protected T childValue(T);
+  }
+
+  public class InstantiationError extends java.lang.IncompatibleClassChangeError {
+    ctor public InstantiationError();
+    ctor public InstantiationError(String);
+  }
+
+  public class InstantiationException extends java.lang.ReflectiveOperationException {
+    ctor public InstantiationException();
+    ctor public InstantiationException(String);
+  }
+
+  public final class Integer extends java.lang.Number implements java.lang.Comparable<java.lang.Integer> {
+    ctor public Integer(int);
+    ctor public Integer(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int bitCount(int);
+    method public static int compare(int, int);
+    method public int compareTo(@NonNull Integer);
+    method public static int compareUnsigned(int, int);
+    method @NonNull public static Integer decode(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int divideUnsigned(int, int);
+    method public double doubleValue();
+    method public float floatValue();
+    method @Nullable public static Integer getInteger(@NonNull String);
+    method @Nullable public static Integer getInteger(@NonNull String, int);
+    method @Nullable public static Integer getInteger(@NonNull String, @Nullable Integer);
+    method public static int hashCode(int);
+    method public static int highestOneBit(int);
+    method public int intValue();
+    method public long longValue();
+    method public static int lowestOneBit(int);
+    method public static int max(int, int);
+    method public static int min(int, int);
+    method public static int numberOfLeadingZeros(int);
+    method public static int numberOfTrailingZeros(int);
+    method public static int parseInt(@NonNull String, int) throws java.lang.NumberFormatException;
+    method public static int parseInt(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int parseUnsignedInt(@NonNull String, int) throws java.lang.NumberFormatException;
+    method public static int parseUnsignedInt(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int remainderUnsigned(int, int);
+    method public static int reverse(int);
+    method public static int reverseBytes(int);
+    method public static int rotateLeft(int, int);
+    method public static int rotateRight(int, int);
+    method public static int signum(int);
+    method public static int sum(int, int);
+    method @NonNull public static String toBinaryString(int);
+    method @NonNull public static String toHexString(int);
+    method @NonNull public static String toOctalString(int);
+    method @NonNull public static String toString(int, int);
+    method @NonNull public static String toString(int);
+    method public static long toUnsignedLong(int);
+    method @NonNull public static String toUnsignedString(int, int);
+    method @NonNull public static String toUnsignedString(int);
+    method @NonNull public static Integer valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
+    method @NonNull public static Integer valueOf(@NonNull String) throws java.lang.NumberFormatException;
+    method @NonNull public static Integer valueOf(int);
+    field public static final int BYTES = 4; // 0x4
+    field public static final int MAX_VALUE = 2147483647; // 0x7fffffff
+    field public static final int MIN_VALUE = -2147483648; // 0x80000000
+    field public static final int SIZE = 32; // 0x20
+    field public static final Class<java.lang.Integer> TYPE;
+  }
+
+  public class InternalError extends java.lang.VirtualMachineError {
+    ctor public InternalError();
+    ctor public InternalError(String);
+    ctor public InternalError(String, Throwable);
+    ctor public InternalError(Throwable);
+  }
+
+  public class InterruptedException extends java.lang.Exception {
+    ctor public InterruptedException();
+    ctor public InterruptedException(String);
+  }
+
+  public interface Iterable<T> {
+    method public default void forEach(@NonNull java.util.function.Consumer<? super T>);
+    method @NonNull public java.util.Iterator<T> iterator();
+    method @NonNull public default java.util.Spliterator<T> spliterator();
+  }
+
+  public class LinkageError extends java.lang.Error {
+    ctor public LinkageError();
+    ctor public LinkageError(String);
+    ctor public LinkageError(String, Throwable);
+  }
+
+  public final class Long extends java.lang.Number implements java.lang.Comparable<java.lang.Long> {
+    ctor public Long(long);
+    ctor public Long(@NonNull String) throws java.lang.NumberFormatException;
+    method public static int bitCount(long);
+    method public static int compare(long, long);
+    method public int compareTo(@NonNull Long);
+    method public static int compareUnsigned(long, long);
+    method @NonNull public static Long decode(@NonNull String) throws java.lang.NumberFormatException;
+    method public static long divideUnsigned(long, long);
+    method public double doubleValue();
+    method public float floatValue();
+    method @Nullable public static Long getLong(@NonNull String);
+    method @Nullable public static Long getLong(@NonNull String, long);
+    method @Nullable public static Long getLong(@NonNull String, @Nullable Long);
+    method public static int hashCode(long);
+    method public static long highestOneBit(long);
+    method public int intValue();
+    method public long longValue();
+    method public static long lowestOneBit(long);
+    method public static long max(long, long);
+    method public static long min(long, long);
+    method public static int numberOfLeadingZeros(long);
+    method public static int numberOfTrailingZeros(long);
+    method public static long parseLong(@NonNull String, int) throws java.lang.NumberFormatException;
+    method public static long parseLong(@NonNull String) throws java.lang.NumberFormatException;
+    method public static long parseUnsignedLong(@NonNull String, int) throws java.lang.NumberFormatException;
+    method public static long parseUnsignedLong(@NonNull String) throws java.lang.NumberFormatException;
+    method public static long remainderUnsigned(long, long);
+    method public static long reverse(long);
+    method public static long reverseBytes(long);
+    method public static long rotateLeft(long, int);
+    method public static long rotateRight(long, int);
+    method public static int signum(long);
+    method public static long sum(long, long);
+    method @NonNull public static String toBinaryString(long);
+    method @NonNull public static String toHexString(long);
+    method @NonNull public static String toOctalString(long);
+    method @NonNull public static String toString(long, int);
+    method @NonNull public static String toString(long);
+    method @NonNull public static String toUnsignedString(long, int);
+    method @NonNull public static String toUnsignedString(long);
+    method @NonNull public static Long valueOf(@NonNull String, int) throws java.lang.NumberFormatException;
+    method @NonNull public static Long valueOf(@NonNull String) throws java.lang.NumberFormatException;
+    method @NonNull public static Long valueOf(long);
+    field public static final int BYTES = 8; // 0x8
+    field public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL
+    field public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L
+    field public static final int SIZE = 64; // 0x40
+    field public static final Class<java.lang.Long> TYPE;
+  }
+
+  public final class Math {
+    method public static double IEEEremainder(double, double);
+    method public static int abs(int);
+    method public static long abs(long);
+    method public static float abs(float);
+    method public static double abs(double);
+    method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static double asin(double);
+    method public static double atan(double);
+    method public static double atan2(double, double);
+    method public static double cbrt(double);
+    method public static double ceil(double);
+    method public static double copySign(double, double);
+    method public static float copySign(float, float);
+    method public static double cos(double);
+    method public static double cosh(double);
+    method public static int decrementExact(int);
+    method public static long decrementExact(long);
+    method public static double exp(double);
+    method public static double expm1(double);
+    method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static int floorMod(long, int);
+    method public static long floorMod(long, long);
+    method public static int getExponent(float);
+    method public static int getExponent(double);
+    method public static double hypot(double, double);
+    method public static int incrementExact(int);
+    method public static long incrementExact(long);
+    method public static double log(double);
+    method public static double log10(double);
+    method public static double log1p(double);
+    method public static int max(int, int);
+    method public static long max(long, long);
+    method public static float max(float, float);
+    method public static double max(double, double);
+    method public static int min(int, int);
+    method public static long min(long, long);
+    method public static float min(float, float);
+    method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, int);
+    method public static long multiplyExact(long, long);
+    method public static long multiplyFull(int, int);
+    method public static long multiplyHigh(long, long);
+    method public static int negateExact(int);
+    method public static long negateExact(long);
+    method public static double nextAfter(double, double);
+    method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
+    method public static double nextUp(double);
+    method public static float nextUp(float);
+    method public static double pow(double, double);
+    method public static double random();
+    method public static double rint(double);
+    method public static int round(float);
+    method public static long round(double);
+    method public static double scalb(double, int);
+    method public static float scalb(float, int);
+    method public static double signum(double);
+    method public static float signum(float);
+    method public static double sin(double);
+    method public static double sinh(double);
+    method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static double tan(double);
+    method public static double tanh(double);
+    method public static double toDegrees(double);
+    method public static int toIntExact(long);
+    method public static double toRadians(double);
+    method public static double ulp(double);
+    method public static float ulp(float);
+    field public static final double E = 2.718281828459045;
+    field public static final double PI = 3.141592653589793;
+  }
+
+  public class NegativeArraySizeException extends java.lang.RuntimeException {
+    ctor public NegativeArraySizeException();
+    ctor public NegativeArraySizeException(String);
+  }
+
+  public class NoClassDefFoundError extends java.lang.LinkageError {
+    ctor public NoClassDefFoundError();
+    ctor public NoClassDefFoundError(String);
+  }
+
+  public class NoSuchFieldError extends java.lang.IncompatibleClassChangeError {
+    ctor public NoSuchFieldError();
+    ctor public NoSuchFieldError(String);
+  }
+
+  public class NoSuchFieldException extends java.lang.ReflectiveOperationException {
+    ctor public NoSuchFieldException();
+    ctor public NoSuchFieldException(String);
+  }
+
+  public class NoSuchMethodError extends java.lang.IncompatibleClassChangeError {
+    ctor public NoSuchMethodError();
+    ctor public NoSuchMethodError(String);
+  }
+
+  public class NoSuchMethodException extends java.lang.ReflectiveOperationException {
+    ctor public NoSuchMethodException();
+    ctor public NoSuchMethodException(String);
+  }
+
+  public class NullPointerException extends java.lang.RuntimeException {
+    ctor public NullPointerException();
+    ctor public NullPointerException(String);
+  }
+
+  public abstract class Number implements java.io.Serializable {
+    ctor public Number();
+    method public byte byteValue();
+    method public abstract double doubleValue();
+    method public abstract float floatValue();
+    method public abstract int intValue();
+    method public abstract long longValue();
+    method public short shortValue();
+  }
+
+  public class NumberFormatException extends java.lang.IllegalArgumentException {
+    ctor public NumberFormatException();
+    ctor public NumberFormatException(String);
+  }
+
+  public class Object {
+    ctor public Object();
+    method @NonNull protected Object clone() throws java.lang.CloneNotSupportedException;
+    method public boolean equals(@Nullable Object);
+    method protected void finalize() throws java.lang.Throwable;
+    method @NonNull public final Class<?> getClass();
+    method public int hashCode();
+    method public final void notify();
+    method public final void notifyAll();
+    method @NonNull public String toString();
+    method public final void wait(long) throws java.lang.InterruptedException;
+    method public final void wait(long, int) throws java.lang.InterruptedException;
+    method public final void wait() throws java.lang.InterruptedException;
+  }
+
+  public class OutOfMemoryError extends java.lang.VirtualMachineError {
+    ctor public OutOfMemoryError();
+    ctor public OutOfMemoryError(String);
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) public @interface Override {
+  }
+
+  public class Package implements java.lang.reflect.AnnotatedElement {
+    method public <A extends java.lang.annotation.Annotation> A getAnnotation(Class<A>);
+    method public java.lang.annotation.Annotation[] getAnnotations();
+    method public <A extends java.lang.annotation.Annotation> A[] getAnnotationsByType(Class<A>);
+    method public <A extends java.lang.annotation.Annotation> A getDeclaredAnnotation(Class<A>);
+    method public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method public <A extends java.lang.annotation.Annotation> A[] getDeclaredAnnotationsByType(Class<A>);
+    method public String getImplementationTitle();
+    method public String getImplementationVendor();
+    method public String getImplementationVersion();
+    method public String getName();
+    method public static Package getPackage(String);
+    method public static Package[] getPackages();
+    method public String getSpecificationTitle();
+    method public String getSpecificationVendor();
+    method public String getSpecificationVersion();
+    method public boolean isCompatibleWith(String) throws java.lang.NumberFormatException;
+    method public boolean isSealed();
+    method public boolean isSealed(java.net.URL);
+  }
+
+  public abstract class Process {
+    ctor public Process();
+    method public abstract void destroy();
+    method public Process destroyForcibly();
+    method public abstract int exitValue();
+    method public abstract java.io.InputStream getErrorStream();
+    method public abstract java.io.InputStream getInputStream();
+    method public abstract java.io.OutputStream getOutputStream();
+    method public boolean isAlive();
+    method public abstract int waitFor() throws java.lang.InterruptedException;
+    method public boolean waitFor(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+  public final class ProcessBuilder {
+    ctor public ProcessBuilder(java.util.List<java.lang.String>);
+    ctor public ProcessBuilder(java.lang.String...);
+    method public ProcessBuilder command(java.util.List<java.lang.String>);
+    method public ProcessBuilder command(java.lang.String...);
+    method public java.util.List<java.lang.String> command();
+    method public java.io.File directory();
+    method public ProcessBuilder directory(java.io.File);
+    method public java.util.Map<java.lang.String,java.lang.String> environment();
+    method public ProcessBuilder inheritIO();
+    method public ProcessBuilder redirectError(java.lang.ProcessBuilder.Redirect);
+    method public ProcessBuilder redirectError(java.io.File);
+    method public java.lang.ProcessBuilder.Redirect redirectError();
+    method public boolean redirectErrorStream();
+    method public ProcessBuilder redirectErrorStream(boolean);
+    method public ProcessBuilder redirectInput(java.lang.ProcessBuilder.Redirect);
+    method public ProcessBuilder redirectInput(java.io.File);
+    method public java.lang.ProcessBuilder.Redirect redirectInput();
+    method public ProcessBuilder redirectOutput(java.lang.ProcessBuilder.Redirect);
+    method public ProcessBuilder redirectOutput(java.io.File);
+    method public java.lang.ProcessBuilder.Redirect redirectOutput();
+    method public Process start() throws java.io.IOException;
+  }
+
+  public abstract static class ProcessBuilder.Redirect {
+    method public static java.lang.ProcessBuilder.Redirect appendTo(java.io.File);
+    method public java.io.File file();
+    method public static java.lang.ProcessBuilder.Redirect from(java.io.File);
+    method public static java.lang.ProcessBuilder.Redirect to(java.io.File);
+    method public abstract java.lang.ProcessBuilder.Redirect.Type type();
+    field public static final java.lang.ProcessBuilder.Redirect INHERIT;
+    field public static final java.lang.ProcessBuilder.Redirect PIPE;
+  }
+
+  public enum ProcessBuilder.Redirect.Type {
+    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type APPEND;
+    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type INHERIT;
+    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type PIPE;
+    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type READ;
+    enum_constant public static final java.lang.ProcessBuilder.Redirect.Type WRITE;
+  }
+
+  public interface Readable {
+    method public int read(java.nio.CharBuffer) throws java.io.IOException;
+  }
+
+  public class ReflectiveOperationException extends java.lang.Exception {
+    ctor public ReflectiveOperationException();
+    ctor public ReflectiveOperationException(String);
+    ctor public ReflectiveOperationException(String, Throwable);
+    ctor public ReflectiveOperationException(Throwable);
+  }
+
+  @java.lang.FunctionalInterface public interface Runnable {
+    method public void run();
+  }
+
+  public class Runtime {
+    method public void addShutdownHook(Thread);
+    method public int availableProcessors();
+    method public Process exec(String) throws java.io.IOException;
+    method public Process exec(String, String[]) throws java.io.IOException;
+    method public Process exec(String, String[], java.io.File) throws java.io.IOException;
+    method public Process exec(String[]) throws java.io.IOException;
+    method public Process exec(String[], String[]) throws java.io.IOException;
+    method public Process exec(String[], String[], java.io.File) throws java.io.IOException;
+    method public void exit(int);
+    method public long freeMemory();
+    method public void gc();
+    method @Deprecated public java.io.InputStream getLocalizedInputStream(java.io.InputStream);
+    method @Deprecated public java.io.OutputStream getLocalizedOutputStream(java.io.OutputStream);
+    method public static Runtime getRuntime();
+    method public void halt(int);
+    method public void load(String);
+    method public void loadLibrary(String);
+    method public long maxMemory();
+    method public boolean removeShutdownHook(Thread);
+    method public void runFinalization();
+    method @Deprecated public static void runFinalizersOnExit(boolean);
+    method public long totalMemory();
+    method public void traceInstructions(boolean);
+    method public void traceMethodCalls(boolean);
+  }
+
+  public class RuntimeException extends java.lang.Exception {
+    ctor public RuntimeException();
+    ctor public RuntimeException(String);
+    ctor public RuntimeException(String, Throwable);
+    ctor public RuntimeException(Throwable);
+    ctor protected RuntimeException(String, Throwable, boolean, boolean);
+  }
+
+  public final class RuntimePermission extends java.security.BasicPermission {
+    ctor public RuntimePermission(String);
+    ctor public RuntimePermission(String, String);
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.METHOD}) public @interface SafeVarargs {
+  }
+
+  public class SecurityException extends java.lang.RuntimeException {
+    ctor public SecurityException();
+    ctor public SecurityException(String);
+    ctor public SecurityException(String, Throwable);
+    ctor public SecurityException(Throwable);
+  }
+
+  public class SecurityManager {
+    ctor public SecurityManager();
+    method public void checkAccept(String, int);
+    method public void checkAccess(Thread);
+    method public void checkAccess(ThreadGroup);
+    method public void checkAwtEventQueueAccess();
+    method public void checkConnect(String, int);
+    method public void checkConnect(String, int, Object);
+    method public void checkCreateClassLoader();
+    method public void checkDelete(String);
+    method public void checkExec(String);
+    method public void checkExit(int);
+    method public void checkLink(String);
+    method public void checkListen(int);
+    method public void checkMemberAccess(Class<?>, int);
+    method public void checkMulticast(java.net.InetAddress);
+    method @Deprecated public void checkMulticast(java.net.InetAddress, byte);
+    method public void checkPackageAccess(String);
+    method public void checkPackageDefinition(String);
+    method public void checkPermission(java.security.Permission);
+    method public void checkPermission(java.security.Permission, Object);
+    method public void checkPrintJobAccess();
+    method public void checkPropertiesAccess();
+    method public void checkPropertyAccess(String);
+    method public void checkRead(java.io.FileDescriptor);
+    method public void checkRead(String);
+    method public void checkRead(String, Object);
+    method public void checkSecurityAccess(String);
+    method public void checkSetFactory();
+    method public void checkSystemClipboardAccess();
+    method public boolean checkTopLevelWindow(Object);
+    method public void checkWrite(java.io.FileDescriptor);
+    method public void checkWrite(String);
+    method @Deprecated protected int classDepth(String);
+    method @Deprecated protected int classLoaderDepth();
+    method @Deprecated protected ClassLoader currentClassLoader();
+    method @Deprecated protected Class<?> currentLoadedClass();
+    method protected Class[] getClassContext();
+    method @Deprecated public boolean getInCheck();
+    method public Object getSecurityContext();
+    method public ThreadGroup getThreadGroup();
+    method @Deprecated protected boolean inClass(String);
+    method @Deprecated protected boolean inClassLoader();
+    field @Deprecated protected boolean inCheck;
+  }
+
+  public final class Short extends java.lang.Number implements java.lang.Comparable<java.lang.Short> {
+    ctor @Deprecated public Short(short);
+    ctor @Deprecated public Short(String) throws java.lang.NumberFormatException;
+    method public static int compare(short, short);
+    method public int compareTo(Short);
+    method public static int compareUnsigned(short, short);
+    method public static Short decode(String) throws java.lang.NumberFormatException;
+    method public double doubleValue();
+    method public float floatValue();
+    method public static int hashCode(short);
+    method public int intValue();
+    method public long longValue();
+    method public static short parseShort(String, int) throws java.lang.NumberFormatException;
+    method public static short parseShort(String) throws java.lang.NumberFormatException;
+    method public static short reverseBytes(short);
+    method public static String toString(short);
+    method public static int toUnsignedInt(short);
+    method public static long toUnsignedLong(short);
+    method public static Short valueOf(String, int) throws java.lang.NumberFormatException;
+    method public static Short valueOf(String) throws java.lang.NumberFormatException;
+    method public static Short valueOf(short);
+    field public static final int BYTES = 2; // 0x2
+    field public static final short MAX_VALUE = 32767; // 0x7fff
+    field public static final short MIN_VALUE = -32768; // 0xffff8000
+    field public static final int SIZE = 16; // 0x10
+    field public static final Class<java.lang.Short> TYPE;
+  }
+
+  public class StackOverflowError extends java.lang.VirtualMachineError {
+    ctor public StackOverflowError();
+    ctor public StackOverflowError(String);
+  }
+
+  public final class StackTraceElement implements java.io.Serializable {
+    ctor public StackTraceElement(String, String, String, int);
+    method public String getClassName();
+    method public String getFileName();
+    method public int getLineNumber();
+    method public String getMethodName();
+    method public boolean isNativeMethod();
+  }
+
+  public final class StrictMath {
+    method public static double IEEEremainder(double, double);
+    method public static int abs(int);
+    method public static long abs(long);
+    method public static float abs(float);
+    method public static double abs(double);
+    method public static double acos(double);
+    method public static int addExact(int, int);
+    method public static long addExact(long, long);
+    method public static double asin(double);
+    method public static double atan(double);
+    method public static double atan2(double, double);
+    method public static double cbrt(double);
+    method public static double ceil(double);
+    method public static double copySign(double, double);
+    method public static float copySign(float, float);
+    method public static double cos(double);
+    method public static double cosh(double);
+    method public static double exp(double);
+    method public static double expm1(double);
+    method public static double floor(double);
+    method public static int floorDiv(int, int);
+    method public static long floorDiv(long, int);
+    method public static long floorDiv(long, long);
+    method public static int floorMod(int, int);
+    method public static int floorMod(long, int);
+    method public static long floorMod(long, long);
+    method public static int getExponent(float);
+    method public static int getExponent(double);
+    method public static double hypot(double, double);
+    method public static double log(double);
+    method public static double log10(double);
+    method public static double log1p(double);
+    method public static int max(int, int);
+    method public static long max(long, long);
+    method public static float max(float, float);
+    method public static double max(double, double);
+    method public static int min(int, int);
+    method public static long min(long, long);
+    method public static float min(float, float);
+    method public static double min(double, double);
+    method public static int multiplyExact(int, int);
+    method public static long multiplyExact(long, int);
+    method public static long multiplyExact(long, long);
+    method public static long multiplyFull(int, int);
+    method public static long multiplyHigh(long, long);
+    method public static double nextAfter(double, double);
+    method public static float nextAfter(float, double);
+    method public static double nextDown(double);
+    method public static float nextDown(float);
+    method public static double nextUp(double);
+    method public static float nextUp(float);
+    method public static double pow(double, double);
+    method public static double random();
+    method public static double rint(double);
+    method public static int round(float);
+    method public static long round(double);
+    method public static double scalb(double, int);
+    method public static float scalb(float, int);
+    method public static double signum(double);
+    method public static float signum(float);
+    method public static double sin(double);
+    method public static double sinh(double);
+    method public static double sqrt(double);
+    method public static int subtractExact(int, int);
+    method public static long subtractExact(long, long);
+    method public static double tan(double);
+    method public static double tanh(double);
+    method public static double toDegrees(double);
+    method public static int toIntExact(long);
+    method public static double toRadians(double);
+    method public static double ulp(double);
+    method public static float ulp(float);
+    field public static final double E = 2.718281828459045;
+    field public static final double PI = 3.141592653589793;
+  }
+
+  public final class String implements java.lang.CharSequence java.lang.Comparable<java.lang.String> java.io.Serializable {
+    ctor public String();
+    ctor public String(@NonNull String);
+    ctor public String(char[]);
+    ctor public String(char[], int, int);
+    ctor public String(int[], int, int);
+    ctor @Deprecated public String(byte[], int, int, int);
+    ctor @Deprecated public String(byte[], int);
+    ctor public String(byte[], int, int, @NonNull String) throws java.io.UnsupportedEncodingException;
+    ctor public String(byte[], int, int, @NonNull java.nio.charset.Charset);
+    ctor public String(byte[], @NonNull String) throws java.io.UnsupportedEncodingException;
+    ctor public String(byte[], @NonNull java.nio.charset.Charset);
+    ctor public String(byte[], int, int);
+    ctor public String(byte[]);
+    ctor public String(@NonNull StringBuffer);
+    ctor public String(@NonNull StringBuilder);
+    method public char charAt(int);
+    method public int codePointAt(int);
+    method public int codePointBefore(int);
+    method public int codePointCount(int, int);
+    method public int compareTo(@NonNull String);
+    method public int compareToIgnoreCase(@NonNull String);
+    method @NonNull public String concat(@NonNull String);
+    method public boolean contains(@NonNull CharSequence);
+    method public boolean contentEquals(@NonNull StringBuffer);
+    method public boolean contentEquals(@NonNull CharSequence);
+    method @NonNull public static String copyValueOf(char[], int, int);
+    method @NonNull public static String copyValueOf(char[]);
+    method public boolean endsWith(@NonNull String);
+    method public boolean equalsIgnoreCase(@Nullable String);
+    method @NonNull public static String format(@NonNull String, @NonNull java.lang.Object...);
+    method @NonNull public static String format(@NonNull java.util.Locale, @NonNull String, @NonNull java.lang.Object...);
+    method @Deprecated public void getBytes(int, int, byte[], int);
+    method public byte[] getBytes(@NonNull String) throws java.io.UnsupportedEncodingException;
+    method public byte[] getBytes(@NonNull java.nio.charset.Charset);
+    method public byte[] getBytes();
+    method public void getChars(int, int, char[], int);
+    method public int indexOf(int);
+    method public int indexOf(int, int);
+    method public int indexOf(@NonNull String);
+    method public int indexOf(@NonNull String, int);
+    method @NonNull public String intern();
+    method public boolean isEmpty();
+    method @NonNull public static String join(@NonNull CharSequence, @Nullable java.lang.CharSequence...);
+    method @NonNull public static String join(@NonNull CharSequence, @NonNull Iterable<? extends java.lang.CharSequence>);
+    method public int lastIndexOf(int);
+    method public int lastIndexOf(int, int);
+    method public int lastIndexOf(@NonNull String);
+    method public int lastIndexOf(@NonNull String, int);
+    method public int length();
+    method public boolean matches(@NonNull String);
+    method public int offsetByCodePoints(int, int);
+    method public boolean regionMatches(int, @NonNull String, int, int);
+    method public boolean regionMatches(boolean, int, @NonNull String, int, int);
+    method @NonNull public String replace(char, char);
+    method @NonNull public String replace(@NonNull CharSequence, @NonNull CharSequence);
+    method @NonNull public String replaceAll(@NonNull String, @NonNull String);
+    method @NonNull public String replaceFirst(@NonNull String, @NonNull String);
+    method @NonNull public String[] split(@NonNull String, int);
+    method @NonNull public String[] split(@NonNull String);
+    method public boolean startsWith(@NonNull String, int);
+    method public boolean startsWith(@NonNull String);
+    method @NonNull public CharSequence subSequence(int, int);
+    method @NonNull public String substring(int);
+    method @NonNull public String substring(int, int);
+    method public char[] toCharArray();
+    method @NonNull public String toLowerCase(@NonNull java.util.Locale);
+    method @NonNull public String toLowerCase();
+    method @NonNull public String toUpperCase(@NonNull java.util.Locale);
+    method @NonNull public String toUpperCase();
+    method @NonNull public String trim();
+    method @NonNull public static String valueOf(@Nullable Object);
+    method @NonNull public static String valueOf(char[]);
+    method @NonNull public static String valueOf(char[], int, int);
+    method @NonNull public static String valueOf(boolean);
+    method @NonNull public static String valueOf(char);
+    method @NonNull public static String valueOf(int);
+    method @NonNull public static String valueOf(long);
+    method @NonNull public static String valueOf(float);
+    method @NonNull public static String valueOf(double);
+    field public static final java.util.Comparator<java.lang.String> CASE_INSENSITIVE_ORDER;
+  }
+
+  public final class StringBuffer implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
+    ctor public StringBuffer();
+    ctor public StringBuffer(int);
+    ctor public StringBuffer(@NonNull String);
+    ctor public StringBuffer(@NonNull CharSequence);
+    method @NonNull public StringBuffer append(@Nullable Object);
+    method @NonNull public StringBuffer append(@Nullable String);
+    method @NonNull public StringBuffer append(@Nullable StringBuffer);
+    method @NonNull public StringBuffer append(@Nullable CharSequence);
+    method @NonNull public StringBuffer append(@Nullable CharSequence, int, int);
+    method @NonNull public StringBuffer append(char[]);
+    method @NonNull public StringBuffer append(char[], int, int);
+    method @NonNull public StringBuffer append(boolean);
+    method @NonNull public StringBuffer append(char);
+    method @NonNull public StringBuffer append(int);
+    method @NonNull public StringBuffer append(long);
+    method @NonNull public StringBuffer append(float);
+    method @NonNull public StringBuffer append(double);
+    method @NonNull public StringBuffer appendCodePoint(int);
+    method public int capacity();
+    method public char charAt(int);
+    method public int codePointAt(int);
+    method public int codePointBefore(int);
+    method public int codePointCount(int, int);
+    method @NonNull public StringBuffer delete(int, int);
+    method @NonNull public StringBuffer deleteCharAt(int);
+    method public void ensureCapacity(int);
+    method public void getChars(int, int, char[], int);
+    method public int indexOf(@NonNull String);
+    method public int indexOf(@NonNull String, int);
+    method @NonNull public StringBuffer insert(int, char[], int, int);
+    method @NonNull public StringBuffer insert(int, @Nullable Object);
+    method @NonNull public StringBuffer insert(int, @Nullable String);
+    method @NonNull public StringBuffer insert(int, char[]);
+    method @NonNull public StringBuffer insert(int, @Nullable CharSequence);
+    method @NonNull public StringBuffer insert(int, @Nullable CharSequence, int, int);
+    method @NonNull public StringBuffer insert(int, boolean);
+    method @NonNull public StringBuffer insert(int, char);
+    method @NonNull public StringBuffer insert(int, int);
+    method @NonNull public StringBuffer insert(int, long);
+    method @NonNull public StringBuffer insert(int, float);
+    method @NonNull public StringBuffer insert(int, double);
+    method public int lastIndexOf(@NonNull String);
+    method public int lastIndexOf(@NonNull String, int);
+    method public int length();
+    method public int offsetByCodePoints(int, int);
+    method @NonNull public StringBuffer replace(int, int, @NonNull String);
+    method @NonNull public StringBuffer reverse();
+    method public void setCharAt(int, char);
+    method public void setLength(int);
+    method @NonNull public CharSequence subSequence(int, int);
+    method @NonNull public String substring(int);
+    method @NonNull public String substring(int, int);
+    method public void trimToSize();
+  }
+
+  public final class StringBuilder implements java.lang.Appendable java.lang.CharSequence java.io.Serializable {
+    ctor public StringBuilder();
+    ctor public StringBuilder(int);
+    ctor public StringBuilder(@NonNull String);
+    ctor public StringBuilder(@NonNull CharSequence);
+    method @NonNull public StringBuilder append(@Nullable Object);
+    method @NonNull public StringBuilder append(@Nullable String);
+    method @NonNull public StringBuilder append(@Nullable StringBuffer);
+    method @NonNull public StringBuilder append(@Nullable CharSequence);
+    method @NonNull public StringBuilder append(@Nullable CharSequence, int, int);
+    method @NonNull public StringBuilder append(char[]);
+    method @NonNull public StringBuilder append(char[], int, int);
+    method @NonNull public StringBuilder append(boolean);
+    method @NonNull public StringBuilder append(char);
+    method @NonNull public StringBuilder append(int);
+    method @NonNull public StringBuilder append(long);
+    method @NonNull public StringBuilder append(float);
+    method @NonNull public StringBuilder append(double);
+    method @NonNull public StringBuilder appendCodePoint(int);
+    method public int capacity();
+    method public char charAt(int);
+    method public int codePointAt(int);
+    method public int codePointBefore(int);
+    method public int codePointCount(int, int);
+    method @NonNull public StringBuilder delete(int, int);
+    method @NonNull public StringBuilder deleteCharAt(int);
+    method public void ensureCapacity(int);
+    method public void getChars(int, int, char[], int);
+    method public int indexOf(@NonNull String);
+    method public int indexOf(@NonNull String, int);
+    method @NonNull public StringBuilder insert(int, char[], int, int);
+    method @NonNull public StringBuilder insert(int, @Nullable Object);
+    method @NonNull public StringBuilder insert(int, @Nullable String);
+    method @NonNull public StringBuilder insert(int, char[]);
+    method @NonNull public StringBuilder insert(int, @Nullable CharSequence);
+    method @NonNull public StringBuilder insert(int, @Nullable CharSequence, int, int);
+    method @NonNull public StringBuilder insert(int, boolean);
+    method @NonNull public StringBuilder insert(int, char);
+    method @NonNull public StringBuilder insert(int, int);
+    method @NonNull public StringBuilder insert(int, long);
+    method @NonNull public StringBuilder insert(int, float);
+    method @NonNull public StringBuilder insert(int, double);
+    method public int lastIndexOf(@NonNull String);
+    method public int lastIndexOf(@NonNull String, int);
+    method public int length();
+    method public int offsetByCodePoints(int, int);
+    method @NonNull public StringBuilder replace(int, int, @NonNull String);
+    method @NonNull public StringBuilder reverse();
+    method public void setCharAt(int, char);
+    method public void setLength(int);
+    method @NonNull public CharSequence subSequence(int, int);
+    method @NonNull public String substring(int);
+    method @NonNull public String substring(int, int);
+    method public void trimToSize();
+  }
+
+  public class StringIndexOutOfBoundsException extends java.lang.IndexOutOfBoundsException {
+    ctor public StringIndexOutOfBoundsException();
+    ctor public StringIndexOutOfBoundsException(String);
+    ctor public StringIndexOutOfBoundsException(int);
+  }
+
+  @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.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) public @interface SuppressWarnings {
+    method public abstract String[] value();
+  }
+
+  public final class System {
+    method public static void arraycopy(@NonNull Object, int, @NonNull Object, int, int);
+    method @Nullable public static String clearProperty(@NonNull String);
+    method @Nullable public static java.io.Console console();
+    method public static long currentTimeMillis();
+    method public static void exit(int);
+    method public static void gc();
+    method @NonNull public static java.util.Properties getProperties();
+    method @Nullable public static String getProperty(@NonNull String);
+    method @Nullable public static String getProperty(@NonNull String, @Nullable String);
+    method @Nullable public static SecurityManager getSecurityManager();
+    method @Nullable public static String getenv(@NonNull String);
+    method @NonNull public static java.util.Map<java.lang.String,java.lang.String> getenv();
+    method public static int identityHashCode(@Nullable Object);
+    method @Nullable public static java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
+    method @NonNull public static String lineSeparator();
+    method public static void load(@NonNull String);
+    method public static void loadLibrary(@NonNull String);
+    method @NonNull public static String mapLibraryName(@NonNull String);
+    method public static long nanoTime();
+    method public static void runFinalization();
+    method @Deprecated public static void runFinalizersOnExit(boolean);
+    method public static void setErr(@Nullable java.io.PrintStream);
+    method public static void setIn(@Nullable java.io.InputStream);
+    method public static void setOut(@Nullable java.io.PrintStream);
+    method public static void setProperties(@Nullable java.util.Properties);
+    method @Nullable public static String setProperty(@NonNull String, @Nullable String);
+    method public static void setSecurityManager(@Nullable SecurityManager);
+    field public static final java.io.PrintStream err;
+    field public static final java.io.InputStream in;
+    field public static final java.io.PrintStream out;
+  }
+
+  public class Thread implements java.lang.Runnable {
+    ctor public Thread();
+    ctor public Thread(@Nullable Runnable);
+    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable);
+    ctor public Thread(@NonNull String);
+    ctor public Thread(@Nullable ThreadGroup, @NonNull String);
+    ctor public Thread(@Nullable Runnable, @NonNull String);
+    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable, @NonNull String);
+    ctor public Thread(@Nullable ThreadGroup, @Nullable Runnable, @NonNull String, long);
+    method public static int activeCount();
+    method public final void checkAccess();
+    method @Deprecated public int countStackFrames();
+    method @NonNull public static Thread currentThread();
+    method @Deprecated public void destroy();
+    method public static void dumpStack();
+    method public static int enumerate(Thread[]);
+    method @NonNull public static java.util.Map<java.lang.Thread,java.lang.StackTraceElement[]> getAllStackTraces();
+    method @Nullable public ClassLoader getContextClassLoader();
+    method @Nullable public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler();
+    method public long getId();
+    method @NonNull public final String getName();
+    method public final int getPriority();
+    method @NonNull public StackTraceElement[] getStackTrace();
+    method @NonNull public java.lang.Thread.State getState();
+    method @Nullable public final ThreadGroup getThreadGroup();
+    method @Nullable public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
+    method public static boolean holdsLock(@NonNull Object);
+    method public void interrupt();
+    method public static boolean interrupted();
+    method public final boolean isAlive();
+    method public final boolean isDaemon();
+    method public boolean isInterrupted();
+    method public final void join(long) throws java.lang.InterruptedException;
+    method public final void join(long, int) throws java.lang.InterruptedException;
+    method public final void join() throws java.lang.InterruptedException;
+    method @Deprecated public final void resume();
+    method public void run();
+    method public void setContextClassLoader(@Nullable ClassLoader);
+    method public final void setDaemon(boolean);
+    method public static void setDefaultUncaughtExceptionHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
+    method public final void setName(@NonNull String);
+    method public final void setPriority(int);
+    method public void setUncaughtExceptionHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
+    method public static void sleep(long) throws java.lang.InterruptedException;
+    method public static void sleep(long, int) throws java.lang.InterruptedException;
+    method public void start();
+    method @Deprecated public final void stop();
+    method @Deprecated public final void stop(@Nullable Throwable);
+    method @Deprecated public final void suspend();
+    method public static void yield();
+    field public static final int MAX_PRIORITY = 10; // 0xa
+    field public static final int MIN_PRIORITY = 1; // 0x1
+    field public static final int NORM_PRIORITY = 5; // 0x5
+  }
+
+  public enum Thread.State {
+    enum_constant public static final java.lang.Thread.State BLOCKED;
+    enum_constant public static final java.lang.Thread.State NEW;
+    enum_constant public static final java.lang.Thread.State RUNNABLE;
+    enum_constant public static final java.lang.Thread.State TERMINATED;
+    enum_constant public static final java.lang.Thread.State TIMED_WAITING;
+    enum_constant public static final java.lang.Thread.State WAITING;
+  }
+
+  @java.lang.FunctionalInterface public static interface Thread.UncaughtExceptionHandler {
+    method public void uncaughtException(@NonNull Thread, @NonNull Throwable);
+  }
+
+  public class ThreadDeath extends java.lang.Error {
+    ctor public ThreadDeath();
+  }
+
+  public class ThreadGroup implements java.lang.Thread.UncaughtExceptionHandler {
+    ctor public ThreadGroup(String);
+    ctor public ThreadGroup(ThreadGroup, String);
+    method public int activeCount();
+    method public int activeGroupCount();
+    method @Deprecated public boolean allowThreadSuspension(boolean);
+    method public final void checkAccess();
+    method public final void destroy();
+    method public int enumerate(Thread[]);
+    method public int enumerate(Thread[], boolean);
+    method public int enumerate(ThreadGroup[]);
+    method public int enumerate(ThreadGroup[], boolean);
+    method public final int getMaxPriority();
+    method public final String getName();
+    method public final ThreadGroup getParent();
+    method public final void interrupt();
+    method public final boolean isDaemon();
+    method public boolean isDestroyed();
+    method public void list();
+    method public final boolean parentOf(ThreadGroup);
+    method @Deprecated public final void resume();
+    method public final void setDaemon(boolean);
+    method public final void setMaxPriority(int);
+    method @Deprecated public final void stop();
+    method @Deprecated public final void suspend();
+    method public void uncaughtException(Thread, Throwable);
+  }
+
+  public class ThreadLocal<T> {
+    ctor public ThreadLocal();
+    method @Nullable public T get();
+    method @Nullable protected T initialValue();
+    method public void remove();
+    method public void set(T);
+    method @NonNull public static <S> ThreadLocal<S> withInitial(@NonNull java.util.function.Supplier<? extends S>);
+  }
+
+  public class Throwable implements java.io.Serializable {
+    ctor public Throwable();
+    ctor public Throwable(@Nullable String);
+    ctor public Throwable(@Nullable String, @Nullable Throwable);
+    ctor public Throwable(@Nullable Throwable);
+    ctor protected Throwable(@Nullable String, @Nullable Throwable, boolean, boolean);
+    method public final void addSuppressed(@NonNull Throwable);
+    method @NonNull public Throwable fillInStackTrace();
+    method @Nullable public Throwable getCause();
+    method @Nullable public String getLocalizedMessage();
+    method @Nullable public String getMessage();
+    method @NonNull public StackTraceElement[] getStackTrace();
+    method @NonNull public final Throwable[] getSuppressed();
+    method @NonNull public Throwable initCause(@Nullable Throwable);
+    method public void printStackTrace();
+    method public void printStackTrace(@NonNull java.io.PrintStream);
+    method public void printStackTrace(@NonNull java.io.PrintWriter);
+    method public void setStackTrace(@NonNull StackTraceElement[]);
+  }
+
+  public class TypeNotPresentException extends java.lang.RuntimeException {
+    ctor public TypeNotPresentException(String, Throwable);
+    method public String typeName();
+  }
+
+  public class UnknownError extends java.lang.VirtualMachineError {
+    ctor public UnknownError();
+    ctor public UnknownError(String);
+  }
+
+  public class UnsatisfiedLinkError extends java.lang.LinkageError {
+    ctor public UnsatisfiedLinkError();
+    ctor public UnsatisfiedLinkError(String);
+  }
+
+  public class UnsupportedClassVersionError extends java.lang.ClassFormatError {
+    ctor public UnsupportedClassVersionError();
+    ctor public UnsupportedClassVersionError(String);
+  }
+
+  public class UnsupportedOperationException extends java.lang.RuntimeException {
+    ctor public UnsupportedOperationException();
+    ctor public UnsupportedOperationException(String);
+    ctor public UnsupportedOperationException(String, Throwable);
+    ctor public UnsupportedOperationException(Throwable);
+  }
+
+  public class VerifyError extends java.lang.LinkageError {
+    ctor public VerifyError();
+    ctor public VerifyError(String);
+  }
+
+  public abstract class VirtualMachineError extends java.lang.Error {
+    ctor public VirtualMachineError();
+    ctor public VirtualMachineError(String);
+    ctor public VirtualMachineError(String, Throwable);
+    ctor public VirtualMachineError(Throwable);
+  }
+
+  public final class Void {
+    field public static final Class<java.lang.Void> TYPE;
+  }
+
+}
+
+package java.lang.annotation {
+
+  public interface Annotation {
+    method public Class<? extends java.lang.annotation.Annotation> annotationType();
+    method public boolean equals(Object);
+    method public int hashCode();
+    method public String toString();
+  }
+
+  public class AnnotationFormatError extends java.lang.Error {
+    ctor public AnnotationFormatError(String);
+    ctor public AnnotationFormatError(String, Throwable);
+    ctor public AnnotationFormatError(Throwable);
+  }
+
+  public class AnnotationTypeMismatchException extends java.lang.RuntimeException {
+    ctor public AnnotationTypeMismatchException(java.lang.reflect.Method, String);
+    method public java.lang.reflect.Method element();
+    method public String foundType();
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Documented {
+  }
+
+  public enum ElementType {
+    enum_constant public static final java.lang.annotation.ElementType ANNOTATION_TYPE;
+    enum_constant public static final java.lang.annotation.ElementType CONSTRUCTOR;
+    enum_constant public static final java.lang.annotation.ElementType FIELD;
+    enum_constant public static final java.lang.annotation.ElementType LOCAL_VARIABLE;
+    enum_constant public static final java.lang.annotation.ElementType METHOD;
+    enum_constant public static final java.lang.annotation.ElementType MODULE;
+    enum_constant public static final java.lang.annotation.ElementType PACKAGE;
+    enum_constant public static final java.lang.annotation.ElementType PARAMETER;
+    enum_constant public static final java.lang.annotation.ElementType TYPE;
+    enum_constant public static final java.lang.annotation.ElementType TYPE_PARAMETER;
+    enum_constant public static final java.lang.annotation.ElementType TYPE_USE;
+  }
+
+  public class IncompleteAnnotationException extends java.lang.RuntimeException {
+    ctor public IncompleteAnnotationException(Class<? extends java.lang.annotation.Annotation>, String);
+    method public Class<? extends java.lang.annotation.Annotation> annotationType();
+    method public String elementName();
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Inherited {
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target(java.lang.annotation.ElementType.FIELD) public @interface Native {
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Repeatable {
+    method public abstract Class<? extends java.lang.annotation.Annotation> value();
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Retention {
+    method public abstract java.lang.annotation.RetentionPolicy value();
+  }
+
+  public enum RetentionPolicy {
+    enum_constant public static final java.lang.annotation.RetentionPolicy CLASS;
+    enum_constant public static final java.lang.annotation.RetentionPolicy RUNTIME;
+    enum_constant public static final java.lang.annotation.RetentionPolicy SOURCE;
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target(java.lang.annotation.ElementType.ANNOTATION_TYPE) public @interface Target {
+    method public abstract java.lang.annotation.ElementType[] value();
+  }
+
+}
+
+package java.lang.invoke {
+
+  public abstract class CallSite {
+    method public abstract java.lang.invoke.MethodHandle dynamicInvoker();
+    method public abstract java.lang.invoke.MethodHandle getTarget();
+    method public abstract void setTarget(java.lang.invoke.MethodHandle);
+    method public java.lang.invoke.MethodType type();
+  }
+
+  public class ConstantCallSite extends java.lang.invoke.CallSite {
+    ctor public ConstantCallSite(java.lang.invoke.MethodHandle);
+    ctor protected ConstantCallSite(java.lang.invoke.MethodType, java.lang.invoke.MethodHandle) throws java.lang.Throwable;
+    method public final java.lang.invoke.MethodHandle dynamicInvoker();
+    method public final java.lang.invoke.MethodHandle getTarget();
+    method public final void setTarget(java.lang.invoke.MethodHandle);
+  }
+
+  public class LambdaConversionException extends java.lang.Exception {
+    ctor public LambdaConversionException();
+    ctor public LambdaConversionException(String);
+    ctor public LambdaConversionException(String, Throwable);
+    ctor public LambdaConversionException(Throwable);
+    ctor public LambdaConversionException(String, Throwable, boolean, boolean);
+  }
+
+  public abstract class MethodHandle {
+    method public java.lang.invoke.MethodHandle asCollector(Class<?>, int);
+    method public java.lang.invoke.MethodHandle asFixedArity();
+    method public java.lang.invoke.MethodHandle asSpreader(Class<?>, int);
+    method public java.lang.invoke.MethodHandle asType(java.lang.invoke.MethodType);
+    method public java.lang.invoke.MethodHandle asVarargsCollector(Class<?>);
+    method public java.lang.invoke.MethodHandle bindTo(Object);
+    method public final Object invoke(java.lang.Object...) throws java.lang.Throwable;
+    method public final Object invokeExact(java.lang.Object...) throws java.lang.Throwable;
+    method public Object invokeWithArguments(java.lang.Object...) throws java.lang.Throwable;
+    method public Object invokeWithArguments(java.util.List<?>) throws java.lang.Throwable;
+    method public boolean isVarargsCollector();
+    method public java.lang.invoke.MethodType type();
+  }
+
+  public interface MethodHandleInfo {
+    method public Class<?> getDeclaringClass();
+    method public java.lang.invoke.MethodType getMethodType();
+    method public int getModifiers();
+    method public String getName();
+    method public int getReferenceKind();
+    method public default boolean isVarArgs();
+    method @Deprecated public static boolean refKindIsField(int);
+    method @Deprecated public static boolean refKindIsValid(int);
+    method @Deprecated public static String refKindName(int);
+    method public static String referenceKindToString(int);
+    method public <T extends java.lang.reflect.Member> T reflectAs(Class<T>, java.lang.invoke.MethodHandles.Lookup);
+    method public static String toString(int, Class<?>, String, java.lang.invoke.MethodType);
+    field public static final int REF_getField = 1; // 0x1
+    field public static final int REF_getStatic = 2; // 0x2
+    field public static final int REF_invokeInterface = 9; // 0x9
+    field public static final int REF_invokeSpecial = 7; // 0x7
+    field public static final int REF_invokeStatic = 6; // 0x6
+    field public static final int REF_invokeVirtual = 5; // 0x5
+    field public static final int REF_newInvokeSpecial = 8; // 0x8
+    field public static final int REF_putField = 3; // 0x3
+    field public static final int REF_putStatic = 4; // 0x4
+  }
+
+  public class MethodHandles {
+    method public static java.lang.invoke.MethodHandle arrayElementGetter(Class<?>) throws java.lang.IllegalArgumentException;
+    method public static java.lang.invoke.MethodHandle arrayElementSetter(Class<?>) throws java.lang.IllegalArgumentException;
+    method public static java.lang.invoke.MethodHandle catchException(java.lang.invoke.MethodHandle, Class<? extends java.lang.Throwable>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle collectArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle constant(Class<?>, Object);
+    method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, java.util.List<java.lang.Class<?>>);
+    method public static java.lang.invoke.MethodHandle dropArguments(java.lang.invoke.MethodHandle, int, Class<?>...);
+    method public static java.lang.invoke.MethodHandle exactInvoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle explicitCastArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandle filterArguments(java.lang.invoke.MethodHandle, int, java.lang.invoke.MethodHandle...);
+    method public static java.lang.invoke.MethodHandle filterReturnValue(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle foldArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle identity(Class<?>);
+    method public static java.lang.invoke.MethodHandle insertArguments(java.lang.invoke.MethodHandle, int, java.lang.Object...);
+    method public static java.lang.invoke.MethodHandle invoker(java.lang.invoke.MethodType);
+    method public static java.lang.invoke.MethodHandles.Lookup lookup();
+    method public static java.lang.invoke.MethodHandle permuteArguments(java.lang.invoke.MethodHandle, java.lang.invoke.MethodType, int...);
+    method public static java.lang.invoke.MethodHandles.Lookup publicLookup();
+    method public static <T extends java.lang.reflect.Member> T reflectAs(Class<T>, java.lang.invoke.MethodHandle);
+    method public static java.lang.invoke.MethodHandle spreadInvoker(java.lang.invoke.MethodType, int);
+    method public static java.lang.invoke.MethodHandle throwException(Class<?>, Class<? extends java.lang.Throwable>);
+  }
+
+  public static final class MethodHandles.Lookup {
+    method public java.lang.invoke.MethodHandle bind(Object, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
+    method public java.lang.invoke.MethodHandle findConstructor(Class<?>, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
+    method public java.lang.invoke.MethodHandle findGetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
+    method public java.lang.invoke.MethodHandle findSetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
+    method public java.lang.invoke.MethodHandle findSpecial(Class<?>, String, java.lang.invoke.MethodType, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
+    method public java.lang.invoke.MethodHandle findStatic(Class<?>, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
+    method public java.lang.invoke.MethodHandle findStaticGetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
+    method public java.lang.invoke.MethodHandle findStaticSetter(Class<?>, String, Class<?>) throws java.lang.IllegalAccessException, java.lang.NoSuchFieldException;
+    method public java.lang.invoke.MethodHandle findVirtual(Class<?>, String, java.lang.invoke.MethodType) throws java.lang.IllegalAccessException, java.lang.NoSuchMethodException;
+    method public java.lang.invoke.MethodHandles.Lookup in(Class<?>);
+    method public Class<?> lookupClass();
+    method public int lookupModes();
+    method public java.lang.invoke.MethodHandleInfo revealDirect(java.lang.invoke.MethodHandle);
+    method public java.lang.invoke.MethodHandle unreflect(java.lang.reflect.Method) throws java.lang.IllegalAccessException;
+    method public java.lang.invoke.MethodHandle unreflectConstructor(java.lang.reflect.Constructor<?>) throws java.lang.IllegalAccessException;
+    method public java.lang.invoke.MethodHandle unreflectGetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
+    method public java.lang.invoke.MethodHandle unreflectSetter(java.lang.reflect.Field) throws java.lang.IllegalAccessException;
+    method public java.lang.invoke.MethodHandle unreflectSpecial(java.lang.reflect.Method, Class<?>) throws java.lang.IllegalAccessException;
+    field public static final int PACKAGE = 8; // 0x8
+    field public static final int PRIVATE = 2; // 0x2
+    field public static final int PROTECTED = 4; // 0x4
+    field public static final int PUBLIC = 1; // 0x1
+  }
+
+  public final class MethodType implements java.io.Serializable {
+    method public java.lang.invoke.MethodType appendParameterTypes(Class<?>...);
+    method public java.lang.invoke.MethodType appendParameterTypes(java.util.List<java.lang.Class<?>>);
+    method public java.lang.invoke.MethodType changeParameterType(int, Class<?>);
+    method public java.lang.invoke.MethodType changeReturnType(Class<?>);
+    method public java.lang.invoke.MethodType dropParameterTypes(int, int);
+    method public java.lang.invoke.MethodType erase();
+    method public static java.lang.invoke.MethodType fromMethodDescriptorString(String, ClassLoader) throws java.lang.IllegalArgumentException, java.lang.TypeNotPresentException;
+    method public java.lang.invoke.MethodType generic();
+    method public static java.lang.invoke.MethodType genericMethodType(int, boolean);
+    method public static java.lang.invoke.MethodType genericMethodType(int);
+    method public boolean hasPrimitives();
+    method public boolean hasWrappers();
+    method public java.lang.invoke.MethodType insertParameterTypes(int, Class<?>...);
+    method public java.lang.invoke.MethodType insertParameterTypes(int, java.util.List<java.lang.Class<?>>);
+    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>[]);
+    method public static java.lang.invoke.MethodType methodType(Class<?>, java.util.List<java.lang.Class<?>>);
+    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>, Class<?>...);
+    method public static java.lang.invoke.MethodType methodType(Class<?>);
+    method public static java.lang.invoke.MethodType methodType(Class<?>, Class<?>);
+    method public static java.lang.invoke.MethodType methodType(Class<?>, java.lang.invoke.MethodType);
+    method public Class<?>[] parameterArray();
+    method public int parameterCount();
+    method public java.util.List<java.lang.Class<?>> parameterList();
+    method public Class<?> parameterType(int);
+    method public Class<?> returnType();
+    method public String toMethodDescriptorString();
+    method public java.lang.invoke.MethodType unwrap();
+    method public java.lang.invoke.MethodType wrap();
+  }
+
+  public class MutableCallSite extends java.lang.invoke.CallSite {
+    ctor public MutableCallSite(java.lang.invoke.MethodType);
+    ctor public MutableCallSite(java.lang.invoke.MethodHandle);
+    method public final java.lang.invoke.MethodHandle dynamicInvoker();
+    method public final java.lang.invoke.MethodHandle getTarget();
+    method public void setTarget(java.lang.invoke.MethodHandle);
+  }
+
+  public class VolatileCallSite extends java.lang.invoke.CallSite {
+    ctor public VolatileCallSite(java.lang.invoke.MethodType);
+    ctor public VolatileCallSite(java.lang.invoke.MethodHandle);
+    method public final java.lang.invoke.MethodHandle dynamicInvoker();
+    method public final java.lang.invoke.MethodHandle getTarget();
+    method public void setTarget(java.lang.invoke.MethodHandle);
+  }
+
+  public class WrongMethodTypeException extends java.lang.RuntimeException {
+    ctor public WrongMethodTypeException();
+    ctor public WrongMethodTypeException(String);
+  }
+
+}
+
+package java.lang.ref {
+
+  public class PhantomReference<T> extends java.lang.ref.Reference<T> {
+    ctor public PhantomReference(T, java.lang.ref.ReferenceQueue<? super T>);
+  }
+
+  public abstract class Reference<T> {
+    method public void clear();
+    method public boolean enqueue();
+    method public T get();
+    method @Deprecated public boolean isEnqueued();
+    method public static void reachabilityFence(Object);
+  }
+
+  public class ReferenceQueue<T> {
+    ctor public ReferenceQueue();
+    method public java.lang.ref.Reference<? extends T> poll();
+    method public java.lang.ref.Reference<? extends T> remove(long) throws java.lang.IllegalArgumentException, java.lang.InterruptedException;
+    method public java.lang.ref.Reference<? extends T> remove() throws java.lang.InterruptedException;
+  }
+
+  public class SoftReference<T> extends java.lang.ref.Reference<T> {
+    ctor public SoftReference(T);
+    ctor public SoftReference(T, java.lang.ref.ReferenceQueue<? super T>);
+  }
+
+  public class WeakReference<T> extends java.lang.ref.Reference<T> {
+    ctor public WeakReference(T);
+    ctor public WeakReference(T, java.lang.ref.ReferenceQueue<? super T>);
+  }
+
+}
+
+package java.lang.reflect {
+
+  public class AccessibleObject implements java.lang.reflect.AnnotatedElement {
+    ctor protected AccessibleObject();
+    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method public boolean isAccessible();
+    method public static void setAccessible(java.lang.reflect.AccessibleObject[], boolean) throws java.lang.SecurityException;
+    method public void setAccessible(boolean) throws java.lang.SecurityException;
+  }
+
+  public interface AnnotatedElement {
+    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method public default <T extends java.lang.annotation.Annotation> T[] getAnnotationsByType(@NonNull Class<T>);
+    method @Nullable public default <T extends java.lang.annotation.Annotation> T getDeclaredAnnotation(@NonNull Class<T>);
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method public default <T extends java.lang.annotation.Annotation> T[] getDeclaredAnnotationsByType(@NonNull Class<T>);
+    method public default boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
+  }
+
+  public final class Array {
+    method @Nullable public static Object get(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static boolean getBoolean(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static byte getByte(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static char getChar(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static double getDouble(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static float getFloat(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static int getInt(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static int getLength(@NonNull Object);
+    method public static long getLong(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static short getShort(@NonNull Object, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method @NonNull public static Object newInstance(@NonNull Class<?>, int) throws java.lang.NegativeArraySizeException;
+    method @NonNull public static Object newInstance(@NonNull Class<?>, int...) throws java.lang.IllegalArgumentException, java.lang.NegativeArraySizeException;
+    method public static void set(@NonNull Object, int, @Nullable Object) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setBoolean(@NonNull Object, int, boolean);
+    method public static void setByte(@NonNull Object, int, byte) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setChar(@NonNull Object, int, char) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setDouble(@NonNull Object, int, double) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setFloat(@NonNull Object, int, float) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setInt(@NonNull Object, int, int) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setLong(@NonNull Object, int, long) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+    method public static void setShort(@NonNull Object, int, short) throws java.lang.ArrayIndexOutOfBoundsException, java.lang.IllegalArgumentException;
+  }
+
+  public final class Constructor<T> extends java.lang.reflect.Executable {
+    method @NonNull public Class<T> getDeclaringClass();
+    method public Class<?>[] getExceptionTypes();
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method public java.lang.annotation.Annotation[][] getParameterAnnotations();
+    method @NonNull public Class<?>[] getParameterTypes();
+    method public java.lang.reflect.TypeVariable<java.lang.reflect.Constructor<T>>[] getTypeParameters();
+    method @NonNull public T newInstance(java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.InstantiationException, java.lang.reflect.InvocationTargetException;
+    method @NonNull public String toGenericString();
+  }
+
+  public abstract class Executable extends java.lang.reflect.AccessibleObject implements java.lang.reflect.GenericDeclaration java.lang.reflect.Member {
+    method @NonNull public abstract Class<?>[] getExceptionTypes();
+    method @NonNull public java.lang.reflect.Type[] getGenericExceptionTypes();
+    method @NonNull public java.lang.reflect.Type[] getGenericParameterTypes();
+    method @NonNull public abstract java.lang.annotation.Annotation[][] getParameterAnnotations();
+    method public int getParameterCount();
+    method @NonNull public abstract Class<?>[] getParameterTypes();
+    method @NonNull public java.lang.reflect.Parameter[] getParameters();
+    method public final boolean isAnnotationPresent(@NonNull Class<? extends java.lang.annotation.Annotation>);
+    method public boolean isSynthetic();
+    method public boolean isVarArgs();
+    method @NonNull public abstract String toGenericString();
+  }
+
+  public final class Field extends java.lang.reflect.AccessibleObject implements java.lang.reflect.Member {
+    method @Nullable public Object get(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public boolean getBoolean(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public byte getByte(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public char getChar(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method @NonNull public Class<?> getDeclaringClass();
+    method public double getDouble(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public float getFloat(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method @NonNull public java.lang.reflect.Type getGenericType();
+    method public int getInt(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public long getLong(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method public short getShort(@Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method @NonNull public Class<?> getType();
+    method public boolean isEnumConstant();
+    method public boolean isSynthetic();
+    method public void set(@Nullable Object, @Nullable Object) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setBoolean(@Nullable Object, boolean) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setByte(@Nullable Object, byte) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setChar(@Nullable Object, char) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setDouble(@Nullable Object, double) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setFloat(@Nullable Object, float) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setInt(@Nullable Object, int) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setLong(@Nullable Object, long) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method public void setShort(@Nullable Object, short) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException;
+    method @NonNull public String toGenericString();
+  }
+
+  public interface GenericArrayType extends java.lang.reflect.Type {
+    method @NonNull public java.lang.reflect.Type getGenericComponentType();
+  }
+
+  public interface GenericDeclaration extends java.lang.reflect.AnnotatedElement {
+    method @NonNull public java.lang.reflect.TypeVariable<?>[] getTypeParameters();
+  }
+
+  public class GenericSignatureFormatError extends java.lang.ClassFormatError {
+    ctor public GenericSignatureFormatError();
+    ctor public GenericSignatureFormatError(String);
+  }
+
+  public interface InvocationHandler {
+    method public Object invoke(Object, java.lang.reflect.Method, Object[]) throws java.lang.Throwable;
+  }
+
+  public class InvocationTargetException extends java.lang.ReflectiveOperationException {
+    ctor protected InvocationTargetException();
+    ctor public InvocationTargetException(Throwable);
+    ctor public InvocationTargetException(Throwable, String);
+    method public Throwable getTargetException();
+  }
+
+  public class MalformedParameterizedTypeException extends java.lang.RuntimeException {
+    ctor public MalformedParameterizedTypeException();
+  }
+
+  public class MalformedParametersException extends java.lang.RuntimeException {
+    ctor public MalformedParametersException();
+    ctor public MalformedParametersException(String);
+  }
+
+  public interface Member {
+    method @NonNull public Class<?> getDeclaringClass();
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method public boolean isSynthetic();
+    field public static final int DECLARED = 1; // 0x1
+    field public static final int PUBLIC = 0; // 0x0
+  }
+
+  public final class Method extends java.lang.reflect.Executable {
+    method @NonNull public Class<?> getDeclaringClass();
+    method @Nullable public Object getDefaultValue();
+    method @NonNull public Class<?>[] getExceptionTypes();
+    method @NonNull public java.lang.reflect.Type getGenericReturnType();
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method @NonNull public java.lang.annotation.Annotation[][] getParameterAnnotations();
+    method @NonNull public Class<?>[] getParameterTypes();
+    method @NonNull public Class<?> getReturnType();
+    method @NonNull public java.lang.reflect.TypeVariable<java.lang.reflect.Method>[] getTypeParameters();
+    method @Nullable public Object invoke(@Nullable Object, @Nullable java.lang.Object...) throws java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException;
+    method public boolean isBridge();
+    method public boolean isDefault();
+    method @NonNull public String toGenericString();
+  }
+
+  public class Modifier {
+    ctor public Modifier();
+    method public static int classModifiers();
+    method public static int constructorModifiers();
+    method public static int fieldModifiers();
+    method public static int interfaceModifiers();
+    method public static boolean isAbstract(int);
+    method public static boolean isFinal(int);
+    method public static boolean isInterface(int);
+    method public static boolean isNative(int);
+    method public static boolean isPrivate(int);
+    method public static boolean isProtected(int);
+    method public static boolean isPublic(int);
+    method public static boolean isStatic(int);
+    method public static boolean isStrict(int);
+    method public static boolean isSynchronized(int);
+    method public static boolean isTransient(int);
+    method public static boolean isVolatile(int);
+    method public static int methodModifiers();
+    method public static int parameterModifiers();
+    method public static String toString(int);
+    field public static final int ABSTRACT = 1024; // 0x400
+    field public static final int FINAL = 16; // 0x10
+    field public static final int INTERFACE = 512; // 0x200
+    field public static final int NATIVE = 256; // 0x100
+    field public static final int PRIVATE = 2; // 0x2
+    field public static final int PROTECTED = 4; // 0x4
+    field public static final int PUBLIC = 1; // 0x1
+    field public static final int STATIC = 8; // 0x8
+    field public static final int STRICT = 2048; // 0x800
+    field public static final int SYNCHRONIZED = 32; // 0x20
+    field public static final int TRANSIENT = 128; // 0x80
+    field public static final int VOLATILE = 64; // 0x40
+  }
+
+  public final class Parameter implements java.lang.reflect.AnnotatedElement {
+    method @Nullable public <T extends java.lang.annotation.Annotation> T getAnnotation(@NonNull Class<T>);
+    method @NonNull public java.lang.annotation.Annotation[] getAnnotations();
+    method @NonNull public java.lang.annotation.Annotation[] getDeclaredAnnotations();
+    method @NonNull public java.lang.reflect.Executable getDeclaringExecutable();
+    method public int getModifiers();
+    method @NonNull public String getName();
+    method @NonNull public java.lang.reflect.Type getParameterizedType();
+    method @NonNull public Class<?> getType();
+    method public boolean isImplicit();
+    method public boolean isNamePresent();
+    method public boolean isSynthetic();
+    method public boolean isVarArgs();
+  }
+
+  public interface ParameterizedType extends java.lang.reflect.Type {
+    method @NonNull public java.lang.reflect.Type[] getActualTypeArguments();
+    method @Nullable public java.lang.reflect.Type getOwnerType();
+    method @NonNull public java.lang.reflect.Type getRawType();
+  }
+
+  public class Proxy implements java.io.Serializable {
+    ctor protected Proxy(@NonNull java.lang.reflect.InvocationHandler);
+    method @NonNull public static java.lang.reflect.InvocationHandler getInvocationHandler(@NonNull Object) throws java.lang.IllegalArgumentException;
+    method @NonNull public static Class<?> getProxyClass(@Nullable ClassLoader, @NonNull Class<?>...) throws java.lang.IllegalArgumentException;
+    method public static boolean isProxyClass(@NonNull Class<?>);
+    method @NonNull public static Object newProxyInstance(@Nullable ClassLoader, @NonNull Class<?>[], @NonNull java.lang.reflect.InvocationHandler) throws java.lang.IllegalArgumentException;
+    field protected java.lang.reflect.InvocationHandler h;
+  }
+
+  public final class ReflectPermission extends java.security.BasicPermission {
+    ctor public ReflectPermission(String);
+    ctor public ReflectPermission(String, String);
+  }
+
+  public interface Type {
+    method @NonNull public default String getTypeName();
+  }
+
+  public interface TypeVariable<D extends java.lang.reflect.GenericDeclaration> extends java.lang.reflect.Type {
+    method @NonNull public java.lang.reflect.Type[] getBounds();
+    method @NonNull public D getGenericDeclaration();
+    method @NonNull public String getName();
+  }
+
+  public class UndeclaredThrowableException extends java.lang.RuntimeException {
+    ctor public UndeclaredThrowableException(Throwable);
+    ctor public UndeclaredThrowableException(Throwable, String);
+    method public Throwable getUndeclaredThrowable();
+  }
+
+  public interface WildcardType extends java.lang.reflect.Type {
+    method @NonNull public java.lang.reflect.Type[] getLowerBounds();
+    method @NonNull public java.lang.reflect.Type[] getUpperBounds();
+  }
+
+}
+
+package java.math {
+
+  public class BigDecimal extends java.lang.Number implements java.lang.Comparable<java.math.BigDecimal> {
+    ctor public BigDecimal(char[], int, int);
+    ctor public BigDecimal(char[], int, int, java.math.MathContext);
+    ctor public BigDecimal(char[]);
+    ctor public BigDecimal(char[], java.math.MathContext);
+    ctor public BigDecimal(String);
+    ctor public BigDecimal(String, java.math.MathContext);
+    ctor public BigDecimal(double);
+    ctor public BigDecimal(double, java.math.MathContext);
+    ctor public BigDecimal(java.math.BigInteger);
+    ctor public BigDecimal(java.math.BigInteger, java.math.MathContext);
+    ctor public BigDecimal(java.math.BigInteger, int);
+    ctor public BigDecimal(java.math.BigInteger, int, java.math.MathContext);
+    ctor public BigDecimal(int);
+    ctor public BigDecimal(int, java.math.MathContext);
+    ctor public BigDecimal(long);
+    ctor public BigDecimal(long, java.math.MathContext);
+    method public java.math.BigDecimal abs();
+    method public java.math.BigDecimal abs(java.math.MathContext);
+    method public java.math.BigDecimal add(java.math.BigDecimal);
+    method public java.math.BigDecimal add(java.math.BigDecimal, java.math.MathContext);
+    method public byte byteValueExact();
+    method public int compareTo(java.math.BigDecimal);
+    method public java.math.BigDecimal divide(java.math.BigDecimal, int, int);
+    method public java.math.BigDecimal divide(java.math.BigDecimal, int, java.math.RoundingMode);
+    method public java.math.BigDecimal divide(java.math.BigDecimal, int);
+    method public java.math.BigDecimal divide(java.math.BigDecimal, java.math.RoundingMode);
+    method public java.math.BigDecimal divide(java.math.BigDecimal);
+    method public java.math.BigDecimal divide(java.math.BigDecimal, java.math.MathContext);
+    method public java.math.BigDecimal[] divideAndRemainder(java.math.BigDecimal);
+    method public java.math.BigDecimal[] divideAndRemainder(java.math.BigDecimal, java.math.MathContext);
+    method public java.math.BigDecimal divideToIntegralValue(java.math.BigDecimal);
+    method public java.math.BigDecimal divideToIntegralValue(java.math.BigDecimal, java.math.MathContext);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int intValue();
+    method public int intValueExact();
+    method public long longValue();
+    method public long longValueExact();
+    method public java.math.BigDecimal max(java.math.BigDecimal);
+    method public java.math.BigDecimal min(java.math.BigDecimal);
+    method public java.math.BigDecimal movePointLeft(int);
+    method public java.math.BigDecimal movePointRight(int);
+    method public java.math.BigDecimal multiply(java.math.BigDecimal);
+    method public java.math.BigDecimal multiply(java.math.BigDecimal, java.math.MathContext);
+    method public java.math.BigDecimal negate();
+    method public java.math.BigDecimal negate(java.math.MathContext);
+    method public java.math.BigDecimal plus();
+    method public java.math.BigDecimal plus(java.math.MathContext);
+    method public java.math.BigDecimal pow(int);
+    method public java.math.BigDecimal pow(int, java.math.MathContext);
+    method public int precision();
+    method public java.math.BigDecimal remainder(java.math.BigDecimal);
+    method public java.math.BigDecimal remainder(java.math.BigDecimal, java.math.MathContext);
+    method public java.math.BigDecimal round(java.math.MathContext);
+    method public int scale();
+    method public java.math.BigDecimal scaleByPowerOfTen(int);
+    method public java.math.BigDecimal setScale(int, java.math.RoundingMode);
+    method public java.math.BigDecimal setScale(int, int);
+    method public java.math.BigDecimal setScale(int);
+    method public short shortValueExact();
+    method public int signum();
+    method public java.math.BigDecimal stripTrailingZeros();
+    method public java.math.BigDecimal subtract(java.math.BigDecimal);
+    method public java.math.BigDecimal subtract(java.math.BigDecimal, java.math.MathContext);
+    method public java.math.BigInteger toBigInteger();
+    method public java.math.BigInteger toBigIntegerExact();
+    method public String toEngineeringString();
+    method public String toPlainString();
+    method public java.math.BigDecimal ulp();
+    method public java.math.BigInteger unscaledValue();
+    method public static java.math.BigDecimal valueOf(long, int);
+    method public static java.math.BigDecimal valueOf(long);
+    method public static java.math.BigDecimal valueOf(double);
+    field public static final java.math.BigDecimal ONE;
+    field public static final int ROUND_CEILING = 2; // 0x2
+    field public static final int ROUND_DOWN = 1; // 0x1
+    field public static final int ROUND_FLOOR = 3; // 0x3
+    field public static final int ROUND_HALF_DOWN = 5; // 0x5
+    field public static final int ROUND_HALF_EVEN = 6; // 0x6
+    field public static final int ROUND_HALF_UP = 4; // 0x4
+    field public static final int ROUND_UNNECESSARY = 7; // 0x7
+    field public static final int ROUND_UP = 0; // 0x0
+    field public static final java.math.BigDecimal TEN;
+    field public static final java.math.BigDecimal ZERO;
+  }
+
+  public class BigInteger extends java.lang.Number implements java.lang.Comparable<java.math.BigInteger> {
+    ctor public BigInteger(byte[]);
+    ctor public BigInteger(int, byte[]);
+    ctor public BigInteger(@NonNull String, int);
+    ctor public BigInteger(@NonNull String);
+    ctor public BigInteger(int, @NonNull java.util.Random);
+    ctor public BigInteger(int, int, @NonNull java.util.Random);
+    method @NonNull public java.math.BigInteger abs();
+    method @NonNull public java.math.BigInteger add(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger and(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger andNot(@NonNull java.math.BigInteger);
+    method public int bitCount();
+    method public int bitLength();
+    method public byte byteValueExact();
+    method @NonNull public java.math.BigInteger clearBit(int);
+    method public int compareTo(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger divide(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger[] divideAndRemainder(@NonNull java.math.BigInteger);
+    method public double doubleValue();
+    method @NonNull public java.math.BigInteger flipBit(int);
+    method public float floatValue();
+    method @NonNull public java.math.BigInteger gcd(@NonNull java.math.BigInteger);
+    method public int getLowestSetBit();
+    method public int intValue();
+    method public int intValueExact();
+    method public boolean isProbablePrime(int);
+    method public long longValue();
+    method public long longValueExact();
+    method @NonNull public java.math.BigInteger max(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger min(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger mod(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger modInverse(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger modPow(@NonNull java.math.BigInteger, @NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger multiply(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger negate();
+    method @NonNull public java.math.BigInteger nextProbablePrime();
+    method @NonNull public java.math.BigInteger not();
+    method @NonNull public java.math.BigInteger or(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger pow(int);
+    method @NonNull public static java.math.BigInteger probablePrime(int, @NonNull java.util.Random);
+    method @NonNull public java.math.BigInteger remainder(@NonNull java.math.BigInteger);
+    method @NonNull public java.math.BigInteger setBit(int);
+    method @NonNull public java.math.BigInteger shiftLeft(int);
+    method @NonNull public java.math.BigInteger shiftRight(int);
+    method public short shortValueExact();
+    method public int signum();
+    method @NonNull public java.math.BigInteger subtract(@NonNull java.math.BigInteger);
+    method public boolean testBit(int);
+    method public byte[] toByteArray();
+    method @NonNull public String toString(int);
+    method @NonNull public static java.math.BigInteger valueOf(long);
+    method @NonNull public java.math.BigInteger xor(@NonNull java.math.BigInteger);
+    field @NonNull public static final java.math.BigInteger ONE;
+    field @NonNull public static final java.math.BigInteger TEN;
+    field @NonNull public static final java.math.BigInteger ZERO;
+  }
+
+  public final class MathContext implements java.io.Serializable {
+    ctor public MathContext(int);
+    ctor public MathContext(int, java.math.RoundingMode);
+    ctor public MathContext(String);
+    method public int getPrecision();
+    method public java.math.RoundingMode getRoundingMode();
+    field public static final java.math.MathContext DECIMAL128;
+    field public static final java.math.MathContext DECIMAL32;
+    field public static final java.math.MathContext DECIMAL64;
+    field public static final java.math.MathContext UNLIMITED;
+  }
+
+  public enum RoundingMode {
+    method public static java.math.RoundingMode valueOf(int);
+    enum_constant public static final java.math.RoundingMode CEILING;
+    enum_constant public static final java.math.RoundingMode DOWN;
+    enum_constant public static final java.math.RoundingMode FLOOR;
+    enum_constant public static final java.math.RoundingMode HALF_DOWN;
+    enum_constant public static final java.math.RoundingMode HALF_EVEN;
+    enum_constant public static final java.math.RoundingMode HALF_UP;
+    enum_constant public static final java.math.RoundingMode UNNECESSARY;
+    enum_constant public static final java.math.RoundingMode UP;
+  }
+
+}
+
+package java.net {
+
+  public abstract class Authenticator {
+    ctor public Authenticator();
+    method protected java.net.PasswordAuthentication getPasswordAuthentication();
+    method protected final String getRequestingHost();
+    method protected final int getRequestingPort();
+    method protected final String getRequestingPrompt();
+    method protected final String getRequestingProtocol();
+    method protected final String getRequestingScheme();
+    method protected final java.net.InetAddress getRequestingSite();
+    method protected java.net.URL getRequestingURL();
+    method protected java.net.Authenticator.RequestorType getRequestorType();
+    method public static java.net.PasswordAuthentication requestPasswordAuthentication(java.net.InetAddress, int, String, String, String);
+    method public static java.net.PasswordAuthentication requestPasswordAuthentication(String, java.net.InetAddress, int, String, String, String);
+    method public static java.net.PasswordAuthentication requestPasswordAuthentication(String, java.net.InetAddress, int, String, String, String, java.net.URL, java.net.Authenticator.RequestorType);
+    method public static void setDefault(java.net.Authenticator);
+  }
+
+  public enum Authenticator.RequestorType {
+    enum_constant public static final java.net.Authenticator.RequestorType PROXY;
+    enum_constant public static final java.net.Authenticator.RequestorType SERVER;
+  }
+
+  public class BindException extends java.net.SocketException {
+    ctor public BindException(String);
+    ctor public BindException();
+  }
+
+  public abstract class CacheRequest {
+    ctor public CacheRequest();
+    method public abstract void abort();
+    method public abstract java.io.OutputStream getBody() throws java.io.IOException;
+  }
+
+  public abstract class CacheResponse {
+    ctor public CacheResponse();
+    method public abstract java.io.InputStream getBody() throws java.io.IOException;
+    method public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaders() throws java.io.IOException;
+  }
+
+  public class ConnectException extends java.net.SocketException {
+    ctor public ConnectException(String);
+    ctor public ConnectException();
+  }
+
+  public abstract class ContentHandler {
+    ctor public ContentHandler();
+    method public abstract Object getContent(java.net.URLConnection) throws java.io.IOException;
+    method public Object getContent(java.net.URLConnection, Class[]) throws java.io.IOException;
+  }
+
+  public interface ContentHandlerFactory {
+    method public java.net.ContentHandler createContentHandler(String);
+  }
+
+  public abstract class CookieHandler {
+    ctor public CookieHandler();
+    method public abstract java.util.Map<java.lang.String,java.util.List<java.lang.String>> get(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public static java.net.CookieHandler getDefault();
+    method public abstract void put(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public static void setDefault(java.net.CookieHandler);
+  }
+
+  public class CookieManager extends java.net.CookieHandler {
+    ctor public CookieManager();
+    ctor public CookieManager(java.net.CookieStore, java.net.CookiePolicy);
+    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> get(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public java.net.CookieStore getCookieStore();
+    method public void put(java.net.URI, java.util.Map<java.lang.String,java.util.List<java.lang.String>>) throws java.io.IOException;
+    method public void setCookiePolicy(java.net.CookiePolicy);
+  }
+
+  public interface CookiePolicy {
+    method public boolean shouldAccept(java.net.URI, java.net.HttpCookie);
+    field public static final java.net.CookiePolicy ACCEPT_ALL;
+    field public static final java.net.CookiePolicy ACCEPT_NONE;
+    field public static final java.net.CookiePolicy ACCEPT_ORIGINAL_SERVER;
+  }
+
+  public interface CookieStore {
+    method public void add(java.net.URI, java.net.HttpCookie);
+    method public java.util.List<java.net.HttpCookie> get(java.net.URI);
+    method public java.util.List<java.net.HttpCookie> getCookies();
+    method public java.util.List<java.net.URI> getURIs();
+    method public boolean remove(java.net.URI, java.net.HttpCookie);
+    method public boolean removeAll();
+  }
+
+  public final class DatagramPacket {
+    ctor public DatagramPacket(byte[], int, int);
+    ctor public DatagramPacket(byte[], int);
+    ctor public DatagramPacket(byte[], int, int, java.net.InetAddress, int);
+    ctor public DatagramPacket(byte[], int, int, java.net.SocketAddress);
+    ctor public DatagramPacket(byte[], int, java.net.InetAddress, int);
+    ctor public DatagramPacket(byte[], int, java.net.SocketAddress);
+    method public java.net.InetAddress getAddress();
+    method public byte[] getData();
+    method public int getLength();
+    method public int getOffset();
+    method public int getPort();
+    method public java.net.SocketAddress getSocketAddress();
+    method public void setAddress(java.net.InetAddress);
+    method public void setData(byte[], int, int);
+    method public void setData(byte[]);
+    method public void setLength(int);
+    method public void setPort(int);
+    method public void setSocketAddress(java.net.SocketAddress);
+  }
+
+  public class DatagramSocket implements java.io.Closeable {
+    ctor public DatagramSocket() throws java.net.SocketException;
+    ctor protected DatagramSocket(java.net.DatagramSocketImpl);
+    ctor public DatagramSocket(java.net.SocketAddress) throws java.net.SocketException;
+    ctor public DatagramSocket(int) throws java.net.SocketException;
+    ctor public DatagramSocket(int, java.net.InetAddress) throws java.net.SocketException;
+    method public void bind(java.net.SocketAddress) throws java.net.SocketException;
+    method public void close();
+    method public void connect(java.net.InetAddress, int);
+    method public void connect(java.net.SocketAddress) throws java.net.SocketException;
+    method public void disconnect();
+    method public boolean getBroadcast() throws java.net.SocketException;
+    method public java.nio.channels.DatagramChannel getChannel();
+    method public java.net.InetAddress getInetAddress();
+    method public java.net.InetAddress getLocalAddress();
+    method public int getLocalPort();
+    method public java.net.SocketAddress getLocalSocketAddress();
+    method public int getPort();
+    method public int getReceiveBufferSize() throws java.net.SocketException;
+    method public java.net.SocketAddress getRemoteSocketAddress();
+    method public boolean getReuseAddress() throws java.net.SocketException;
+    method public int getSendBufferSize() throws java.net.SocketException;
+    method public int getSoTimeout() throws java.net.SocketException;
+    method public int getTrafficClass() throws java.net.SocketException;
+    method public boolean isBound();
+    method public boolean isClosed();
+    method public boolean isConnected();
+    method public void receive(java.net.DatagramPacket) throws java.io.IOException;
+    method public void send(java.net.DatagramPacket) throws java.io.IOException;
+    method public void setBroadcast(boolean) throws java.net.SocketException;
+    method public static void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory) throws java.io.IOException;
+    method public void setReceiveBufferSize(int) throws java.net.SocketException;
+    method public void setReuseAddress(boolean) throws java.net.SocketException;
+    method public void setSendBufferSize(int) throws java.net.SocketException;
+    method public void setSoTimeout(int) throws java.net.SocketException;
+    method public void setTrafficClass(int) throws java.net.SocketException;
+  }
+
+  public abstract class DatagramSocketImpl implements java.net.SocketOptions {
+    ctor public DatagramSocketImpl();
+    method protected abstract void bind(int, java.net.InetAddress) throws java.net.SocketException;
+    method protected abstract void close();
+    method protected void connect(java.net.InetAddress, int) throws java.net.SocketException;
+    method protected abstract void create() throws java.net.SocketException;
+    method protected void disconnect();
+    method protected java.io.FileDescriptor getFileDescriptor();
+    method protected int getLocalPort();
+    method @Deprecated protected abstract byte getTTL() throws java.io.IOException;
+    method protected abstract int getTimeToLive() throws java.io.IOException;
+    method protected abstract void join(java.net.InetAddress) throws java.io.IOException;
+    method protected abstract void joinGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
+    method protected abstract void leave(java.net.InetAddress) throws java.io.IOException;
+    method protected abstract void leaveGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
+    method protected abstract int peek(java.net.InetAddress) throws java.io.IOException;
+    method protected abstract int peekData(java.net.DatagramPacket) throws java.io.IOException;
+    method protected abstract void receive(java.net.DatagramPacket) throws java.io.IOException;
+    method protected abstract void send(java.net.DatagramPacket) throws java.io.IOException;
+    method @Deprecated protected abstract void setTTL(byte) throws java.io.IOException;
+    method protected abstract void setTimeToLive(int) throws java.io.IOException;
+    field protected java.io.FileDescriptor fd;
+    field protected int localPort;
+  }
+
+  public interface DatagramSocketImplFactory {
+    method public java.net.DatagramSocketImpl createDatagramSocketImpl();
+  }
+
+  public interface FileNameMap {
+    method public String getContentTypeFor(String);
+  }
+
+  public final class HttpCookie implements java.lang.Cloneable {
+    ctor public HttpCookie(String, String);
+    method public Object clone();
+    method public static boolean domainMatches(String, String);
+    method public String getComment();
+    method public String getCommentURL();
+    method public boolean getDiscard();
+    method public String getDomain();
+    method public long getMaxAge();
+    method public String getName();
+    method public String getPath();
+    method public String getPortlist();
+    method public boolean getSecure();
+    method public String getValue();
+    method public int getVersion();
+    method public boolean hasExpired();
+    method public boolean isHttpOnly();
+    method public static java.util.List<java.net.HttpCookie> parse(String);
+    method public void setComment(String);
+    method public void setCommentURL(String);
+    method public void setDiscard(boolean);
+    method public void setDomain(String);
+    method public void setHttpOnly(boolean);
+    method public void setMaxAge(long);
+    method public void setPath(String);
+    method public void setPortlist(String);
+    method public void setSecure(boolean);
+    method public void setValue(String);
+    method public void setVersion(int);
+  }
+
+  public class HttpRetryException extends java.io.IOException {
+    ctor public HttpRetryException(String, int);
+    ctor public HttpRetryException(String, int, String);
+    method public String getLocation();
+    method public String getReason();
+    method public int responseCode();
+  }
+
+  public abstract class HttpURLConnection extends java.net.URLConnection {
+    ctor protected HttpURLConnection(java.net.URL);
+    method public abstract void disconnect();
+    method public java.io.InputStream getErrorStream();
+    method public static boolean getFollowRedirects();
+    method public boolean getInstanceFollowRedirects();
+    method public String getRequestMethod();
+    method public int getResponseCode() throws java.io.IOException;
+    method public String getResponseMessage() throws java.io.IOException;
+    method public void setChunkedStreamingMode(int);
+    method public void setFixedLengthStreamingMode(int);
+    method public void setFixedLengthStreamingMode(long);
+    method public static void setFollowRedirects(boolean);
+    method public void setInstanceFollowRedirects(boolean);
+    method public void setRequestMethod(String) throws java.net.ProtocolException;
+    method public abstract boolean usingProxy();
+    field public static final int HTTP_ACCEPTED = 202; // 0xca
+    field public static final int HTTP_BAD_GATEWAY = 502; // 0x1f6
+    field public static final int HTTP_BAD_METHOD = 405; // 0x195
+    field public static final int HTTP_BAD_REQUEST = 400; // 0x190
+    field public static final int HTTP_CLIENT_TIMEOUT = 408; // 0x198
+    field public static final int HTTP_CONFLICT = 409; // 0x199
+    field public static final int HTTP_CREATED = 201; // 0xc9
+    field public static final int HTTP_ENTITY_TOO_LARGE = 413; // 0x19d
+    field public static final int HTTP_FORBIDDEN = 403; // 0x193
+    field public static final int HTTP_GATEWAY_TIMEOUT = 504; // 0x1f8
+    field public static final int HTTP_GONE = 410; // 0x19a
+    field public static final int HTTP_INTERNAL_ERROR = 500; // 0x1f4
+    field public static final int HTTP_LENGTH_REQUIRED = 411; // 0x19b
+    field public static final int HTTP_MOVED_PERM = 301; // 0x12d
+    field public static final int HTTP_MOVED_TEMP = 302; // 0x12e
+    field public static final int HTTP_MULT_CHOICE = 300; // 0x12c
+    field public static final int HTTP_NOT_ACCEPTABLE = 406; // 0x196
+    field public static final int HTTP_NOT_AUTHORITATIVE = 203; // 0xcb
+    field public static final int HTTP_NOT_FOUND = 404; // 0x194
+    field public static final int HTTP_NOT_IMPLEMENTED = 501; // 0x1f5
+    field public static final int HTTP_NOT_MODIFIED = 304; // 0x130
+    field public static final int HTTP_NO_CONTENT = 204; // 0xcc
+    field public static final int HTTP_OK = 200; // 0xc8
+    field public static final int HTTP_PARTIAL = 206; // 0xce
+    field public static final int HTTP_PAYMENT_REQUIRED = 402; // 0x192
+    field public static final int HTTP_PRECON_FAILED = 412; // 0x19c
+    field public static final int HTTP_PROXY_AUTH = 407; // 0x197
+    field public static final int HTTP_REQ_TOO_LONG = 414; // 0x19e
+    field public static final int HTTP_RESET = 205; // 0xcd
+    field public static final int HTTP_SEE_OTHER = 303; // 0x12f
+    field @Deprecated public static final int HTTP_SERVER_ERROR = 500; // 0x1f4
+    field public static final int HTTP_UNAUTHORIZED = 401; // 0x191
+    field public static final int HTTP_UNAVAILABLE = 503; // 0x1f7
+    field public static final int HTTP_UNSUPPORTED_TYPE = 415; // 0x19f
+    field public static final int HTTP_USE_PROXY = 305; // 0x131
+    field public static final int HTTP_VERSION = 505; // 0x1f9
+    field protected int chunkLength;
+    field protected int fixedContentLength;
+    field protected long fixedContentLengthLong;
+    field protected boolean instanceFollowRedirects;
+    field protected String method;
+    field protected int responseCode;
+    field protected String responseMessage;
+  }
+
+  public final class IDN {
+    method public static String toASCII(String, int);
+    method public static String toASCII(String);
+    method public static String toUnicode(String, int);
+    method public static String toUnicode(String);
+    field public static final int ALLOW_UNASSIGNED = 1; // 0x1
+    field public static final int USE_STD3_ASCII_RULES = 2; // 0x2
+  }
+
+  public final class Inet4Address extends java.net.InetAddress {
+  }
+
+  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();
+  }
+
+  public class InetAddress implements java.io.Serializable {
+    method public byte[] getAddress();
+    method public static java.net.InetAddress[] getAllByName(@Nullable String) throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getByAddress(@Nullable String, byte[]) throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getByAddress(byte[]) throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getByName(@Nullable String) throws java.net.UnknownHostException;
+    method @NonNull public String getCanonicalHostName();
+    method @Nullable public String getHostAddress();
+    method @NonNull public String getHostName();
+    method @NonNull public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getLoopbackAddress();
+    method public boolean isAnyLocalAddress();
+    method public boolean isLinkLocalAddress();
+    method public boolean isLoopbackAddress();
+    method public boolean isMCGlobal();
+    method public boolean isMCLinkLocal();
+    method public boolean isMCNodeLocal();
+    method public boolean isMCOrgLocal();
+    method public boolean isMCSiteLocal();
+    method public boolean isMulticastAddress();
+    method public boolean isReachable(int) throws java.io.IOException;
+    method public boolean isReachable(@Nullable java.net.NetworkInterface, int, int) throws java.io.IOException;
+    method public boolean isSiteLocalAddress();
+  }
+
+  public class InetSocketAddress extends java.net.SocketAddress {
+    ctor public InetSocketAddress(int);
+    ctor public InetSocketAddress(java.net.InetAddress, int);
+    ctor public InetSocketAddress(String, int);
+    method public static java.net.InetSocketAddress createUnresolved(String, int);
+    method public final boolean equals(Object);
+    method public final java.net.InetAddress getAddress();
+    method public final String getHostName();
+    method public final String getHostString();
+    method public final int getPort();
+    method public final int hashCode();
+    method public final boolean isUnresolved();
+  }
+
+  public class InterfaceAddress {
+    method public java.net.InetAddress getAddress();
+    method public java.net.InetAddress getBroadcast();
+    method public short getNetworkPrefixLength();
+  }
+
+  public abstract class JarURLConnection extends java.net.URLConnection {
+    ctor protected JarURLConnection(java.net.URL) throws java.net.MalformedURLException;
+    method public java.util.jar.Attributes getAttributes() throws java.io.IOException;
+    method public java.security.cert.Certificate[] getCertificates() throws java.io.IOException;
+    method public String getEntryName();
+    method public java.util.jar.JarEntry getJarEntry() throws java.io.IOException;
+    method public abstract java.util.jar.JarFile getJarFile() throws java.io.IOException;
+    method public java.net.URL getJarFileURL();
+    method public java.util.jar.Attributes getMainAttributes() throws java.io.IOException;
+    method public java.util.jar.Manifest getManifest() throws java.io.IOException;
+    field protected java.net.URLConnection jarFileURLConnection;
+  }
+
+  public class MalformedURLException extends java.io.IOException {
+    ctor public MalformedURLException();
+    ctor public MalformedURLException(String);
+  }
+
+  public class MulticastSocket extends java.net.DatagramSocket {
+    ctor public MulticastSocket() throws java.io.IOException;
+    ctor public MulticastSocket(int) throws java.io.IOException;
+    ctor public MulticastSocket(java.net.SocketAddress) throws java.io.IOException;
+    method public java.net.InetAddress getInterface() throws java.net.SocketException;
+    method public boolean getLoopbackMode() throws java.net.SocketException;
+    method public java.net.NetworkInterface getNetworkInterface() throws java.net.SocketException;
+    method @Deprecated public byte getTTL() throws java.io.IOException;
+    method public int getTimeToLive() throws java.io.IOException;
+    method public void joinGroup(java.net.InetAddress) throws java.io.IOException;
+    method public void joinGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
+    method public void leaveGroup(java.net.InetAddress) throws java.io.IOException;
+    method public void leaveGroup(java.net.SocketAddress, java.net.NetworkInterface) throws java.io.IOException;
+    method @Deprecated public void send(java.net.DatagramPacket, byte) throws java.io.IOException;
+    method public void setInterface(java.net.InetAddress) throws java.net.SocketException;
+    method public void setLoopbackMode(boolean) throws java.net.SocketException;
+    method public void setNetworkInterface(java.net.NetworkInterface) throws java.net.SocketException;
+    method @Deprecated public void setTTL(byte) throws java.io.IOException;
+    method public void setTimeToLive(int) throws java.io.IOException;
+  }
+
+  public final class NetPermission extends java.security.BasicPermission {
+    ctor public NetPermission(String);
+    ctor public NetPermission(String, String);
+  }
+
+  public final class NetworkInterface {
+    method public static java.net.NetworkInterface getByIndex(int) throws java.net.SocketException;
+    method public static java.net.NetworkInterface getByInetAddress(java.net.InetAddress) throws java.net.SocketException;
+    method public static java.net.NetworkInterface getByName(String) throws java.net.SocketException;
+    method public String getDisplayName();
+    method public byte[] getHardwareAddress() throws java.net.SocketException;
+    method public int getIndex();
+    method public java.util.Enumeration<java.net.InetAddress> getInetAddresses();
+    method public java.util.List<java.net.InterfaceAddress> getInterfaceAddresses();
+    method public int getMTU() throws java.net.SocketException;
+    method public String getName();
+    method public static java.util.Enumeration<java.net.NetworkInterface> getNetworkInterfaces() throws java.net.SocketException;
+    method public java.net.NetworkInterface getParent();
+    method public java.util.Enumeration<java.net.NetworkInterface> getSubInterfaces();
+    method public boolean isLoopback() throws java.net.SocketException;
+    method public boolean isPointToPoint() throws java.net.SocketException;
+    method public boolean isUp() throws java.net.SocketException;
+    method public boolean isVirtual();
+    method public boolean supportsMulticast() throws java.net.SocketException;
+  }
+
+  public class NoRouteToHostException extends java.net.SocketException {
+    ctor public NoRouteToHostException(String);
+    ctor public NoRouteToHostException();
+  }
+
+  public final class PasswordAuthentication {
+    ctor public PasswordAuthentication(String, char[]);
+    method public char[] getPassword();
+    method public String getUserName();
+  }
+
+  public class PortUnreachableException extends java.net.SocketException {
+    ctor public PortUnreachableException(String);
+    ctor public PortUnreachableException();
+  }
+
+  public class ProtocolException extends java.io.IOException {
+    ctor public ProtocolException(String);
+    ctor public ProtocolException();
+  }
+
+  public interface ProtocolFamily {
+    method public String name();
+  }
+
+  public class Proxy {
+    ctor public Proxy(java.net.Proxy.Type, java.net.SocketAddress);
+    method public java.net.SocketAddress address();
+    method public final boolean equals(Object);
+    method public final int hashCode();
+    method public java.net.Proxy.Type type();
+    field public static final java.net.Proxy NO_PROXY;
+  }
+
+  public enum Proxy.Type {
+    enum_constant public static final java.net.Proxy.Type DIRECT;
+    enum_constant public static final java.net.Proxy.Type HTTP;
+    enum_constant public static final java.net.Proxy.Type SOCKS;
+  }
+
+  public abstract class ProxySelector {
+    ctor public ProxySelector();
+    method public abstract void connectFailed(java.net.URI, java.net.SocketAddress, java.io.IOException);
+    method public static java.net.ProxySelector getDefault();
+    method public abstract java.util.List<java.net.Proxy> select(java.net.URI);
+    method public static void setDefault(java.net.ProxySelector);
+  }
+
+  public abstract class ResponseCache {
+    ctor public ResponseCache();
+    method public abstract 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 static java.net.ResponseCache getDefault();
+    method public abstract java.net.CacheRequest put(java.net.URI, java.net.URLConnection) throws java.io.IOException;
+    method public static void setDefault(java.net.ResponseCache);
+  }
+
+  public abstract class SecureCacheResponse extends java.net.CacheResponse {
+    ctor public SecureCacheResponse();
+    method public abstract String getCipherSuite();
+    method public abstract java.util.List<java.security.cert.Certificate> getLocalCertificateChain();
+    method public abstract java.security.Principal getLocalPrincipal();
+    method public abstract java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public abstract java.util.List<java.security.cert.Certificate> getServerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
+  }
+
+  public class ServerSocket implements java.io.Closeable {
+    ctor public ServerSocket() throws java.io.IOException;
+    ctor public ServerSocket(int) throws java.io.IOException;
+    ctor public ServerSocket(int, int) throws java.io.IOException;
+    ctor public ServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
+    method public java.net.Socket accept() throws java.io.IOException;
+    method public void bind(java.net.SocketAddress) throws java.io.IOException;
+    method public void bind(java.net.SocketAddress, int) throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public java.nio.channels.ServerSocketChannel getChannel();
+    method public java.net.InetAddress getInetAddress();
+    method public int getLocalPort();
+    method public java.net.SocketAddress getLocalSocketAddress();
+    method public int getReceiveBufferSize() throws java.net.SocketException;
+    method public boolean getReuseAddress() throws java.net.SocketException;
+    method public int getSoTimeout() throws java.io.IOException;
+    method protected final void implAccept(java.net.Socket) throws java.io.IOException;
+    method public boolean isBound();
+    method public boolean isClosed();
+    method public void setPerformancePreferences(int, int, int);
+    method public void setReceiveBufferSize(int) throws java.net.SocketException;
+    method public void setReuseAddress(boolean) throws java.net.SocketException;
+    method public void setSoTimeout(int) throws java.net.SocketException;
+    method public static void setSocketFactory(java.net.SocketImplFactory) throws java.io.IOException;
+  }
+
+  public class Socket implements java.io.Closeable {
+    ctor public Socket();
+    ctor public Socket(java.net.Proxy);
+    ctor protected Socket(java.net.SocketImpl) throws java.net.SocketException;
+    ctor public Socket(String, int) throws java.io.IOException, java.net.UnknownHostException;
+    ctor public Socket(java.net.InetAddress, int) throws java.io.IOException;
+    ctor public Socket(String, int, java.net.InetAddress, int) throws java.io.IOException;
+    ctor public Socket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
+    ctor @Deprecated public Socket(String, int, boolean) throws java.io.IOException;
+    ctor @Deprecated public Socket(java.net.InetAddress, int, boolean) throws java.io.IOException;
+    method public void bind(java.net.SocketAddress) throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public void connect(java.net.SocketAddress) throws java.io.IOException;
+    method public void connect(java.net.SocketAddress, int) throws java.io.IOException;
+    method public java.nio.channels.SocketChannel getChannel();
+    method public java.net.InetAddress getInetAddress();
+    method public java.io.InputStream getInputStream() throws java.io.IOException;
+    method public boolean getKeepAlive() throws java.net.SocketException;
+    method public java.net.InetAddress getLocalAddress();
+    method public int getLocalPort();
+    method public java.net.SocketAddress getLocalSocketAddress();
+    method public boolean getOOBInline() throws java.net.SocketException;
+    method public java.io.OutputStream getOutputStream() throws java.io.IOException;
+    method public int getPort();
+    method public int getReceiveBufferSize() throws java.net.SocketException;
+    method public java.net.SocketAddress getRemoteSocketAddress();
+    method public boolean getReuseAddress() throws java.net.SocketException;
+    method public int getSendBufferSize() throws java.net.SocketException;
+    method public int getSoLinger() throws java.net.SocketException;
+    method public int getSoTimeout() throws java.net.SocketException;
+    method public boolean getTcpNoDelay() throws java.net.SocketException;
+    method public int getTrafficClass() throws java.net.SocketException;
+    method public boolean isBound();
+    method public boolean isClosed();
+    method public boolean isConnected();
+    method public boolean isInputShutdown();
+    method public boolean isOutputShutdown();
+    method public void sendUrgentData(int) throws java.io.IOException;
+    method public void setKeepAlive(boolean) throws java.net.SocketException;
+    method public void setOOBInline(boolean) throws java.net.SocketException;
+    method public void setPerformancePreferences(int, int, int);
+    method public void setReceiveBufferSize(int) throws java.net.SocketException;
+    method public void setReuseAddress(boolean) throws java.net.SocketException;
+    method public void setSendBufferSize(int) throws java.net.SocketException;
+    method public void setSoLinger(boolean, int) throws java.net.SocketException;
+    method public void setSoTimeout(int) throws java.net.SocketException;
+    method public static void setSocketImplFactory(java.net.SocketImplFactory) throws java.io.IOException;
+    method public void setTcpNoDelay(boolean) throws java.net.SocketException;
+    method public void setTrafficClass(int) throws java.net.SocketException;
+    method public void shutdownInput() throws java.io.IOException;
+    method public void shutdownOutput() throws java.io.IOException;
+  }
+
+  public abstract class SocketAddress implements java.io.Serializable {
+    ctor public SocketAddress();
+  }
+
+  public class SocketException extends java.io.IOException {
+    ctor public SocketException(String);
+    ctor public SocketException();
+  }
+
+  public abstract class SocketImpl implements java.net.SocketOptions {
+    ctor public SocketImpl();
+    method protected abstract void accept(java.net.SocketImpl) throws java.io.IOException;
+    method protected abstract int available() throws java.io.IOException;
+    method protected abstract void bind(java.net.InetAddress, int) throws java.io.IOException;
+    method protected abstract void close() throws java.io.IOException;
+    method protected abstract void connect(String, int) throws java.io.IOException;
+    method protected abstract void connect(java.net.InetAddress, int) throws java.io.IOException;
+    method protected abstract void connect(java.net.SocketAddress, int) throws java.io.IOException;
+    method protected abstract void create(boolean) throws java.io.IOException;
+    method protected java.io.FileDescriptor getFileDescriptor();
+    method protected java.net.InetAddress getInetAddress();
+    method protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
+    method protected int getLocalPort();
+    method protected abstract java.io.OutputStream getOutputStream() throws java.io.IOException;
+    method protected int getPort();
+    method protected abstract void listen(int) throws java.io.IOException;
+    method protected abstract void sendUrgentData(int) throws java.io.IOException;
+    method protected void setPerformancePreferences(int, int, int);
+    method protected void shutdownInput() throws java.io.IOException;
+    method protected void shutdownOutput() throws java.io.IOException;
+    method protected boolean supportsUrgentData();
+    field protected java.net.InetAddress address;
+    field protected java.io.FileDescriptor fd;
+    field protected int localport;
+    field protected int port;
+  }
+
+  public interface SocketImplFactory {
+    method public java.net.SocketImpl createSocketImpl();
+  }
+
+  public interface SocketOption<T> {
+    method public String name();
+    method public Class<T> type();
+  }
+
+  public interface SocketOptions {
+    method public Object getOption(int) throws java.net.SocketException;
+    method public void setOption(int, Object) throws java.net.SocketException;
+    field public static final int IP_MULTICAST_IF = 16; // 0x10
+    field public static final int IP_MULTICAST_IF2 = 31; // 0x1f
+    field public static final int IP_MULTICAST_LOOP = 18; // 0x12
+    field public static final int IP_TOS = 3; // 0x3
+    field public static final int SO_BINDADDR = 15; // 0xf
+    field public static final int SO_BROADCAST = 32; // 0x20
+    field public static final int SO_KEEPALIVE = 8; // 0x8
+    field public static final int SO_LINGER = 128; // 0x80
+    field public static final int SO_OOBINLINE = 4099; // 0x1003
+    field public static final int SO_RCVBUF = 4098; // 0x1002
+    field public static final int SO_REUSEADDR = 4; // 0x4
+    field public static final int SO_SNDBUF = 4097; // 0x1001
+    field public static final int SO_TIMEOUT = 4102; // 0x1006
+    field public static final int TCP_NODELAY = 1; // 0x1
+  }
+
+  public final class SocketPermission extends java.security.Permission implements java.io.Serializable {
+    ctor public SocketPermission(String, String);
+    method public String getActions();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public class SocketTimeoutException extends java.io.InterruptedIOException {
+    ctor public SocketTimeoutException(String);
+    ctor public SocketTimeoutException();
+  }
+
+  public enum StandardProtocolFamily implements java.net.ProtocolFamily {
+    enum_constant public static final java.net.StandardProtocolFamily INET;
+    enum_constant public static final java.net.StandardProtocolFamily INET6;
+  }
+
+  public final class StandardSocketOptions {
+    field public static final java.net.SocketOption<java.net.NetworkInterface> IP_MULTICAST_IF;
+    field public static final java.net.SocketOption<java.lang.Boolean> IP_MULTICAST_LOOP;
+    field public static final java.net.SocketOption<java.lang.Integer> IP_MULTICAST_TTL;
+    field public static final java.net.SocketOption<java.lang.Integer> IP_TOS;
+    field public static final java.net.SocketOption<java.lang.Boolean> SO_BROADCAST;
+    field public static final java.net.SocketOption<java.lang.Boolean> SO_KEEPALIVE;
+    field public static final java.net.SocketOption<java.lang.Integer> SO_LINGER;
+    field public static final java.net.SocketOption<java.lang.Integer> SO_RCVBUF;
+    field public static final java.net.SocketOption<java.lang.Boolean> SO_REUSEADDR;
+    field public static final java.net.SocketOption<java.lang.Integer> SO_SNDBUF;
+    field public static final java.net.SocketOption<java.lang.Boolean> TCP_NODELAY;
+  }
+
+  public final class URI implements java.lang.Comparable<java.net.URI> java.io.Serializable {
+    ctor public URI(String) throws java.net.URISyntaxException;
+    ctor public URI(String, String, String, int, String, String, String) throws java.net.URISyntaxException;
+    ctor public URI(String, String, String, String, String) throws java.net.URISyntaxException;
+    ctor public URI(String, String, String, String) throws java.net.URISyntaxException;
+    ctor public URI(String, String, String) throws java.net.URISyntaxException;
+    method public int compareTo(java.net.URI);
+    method public static java.net.URI create(String);
+    method public String getAuthority();
+    method public String getFragment();
+    method public String getHost();
+    method public String getPath();
+    method public int getPort();
+    method public String getQuery();
+    method public String getRawAuthority();
+    method public String getRawFragment();
+    method public String getRawPath();
+    method public String getRawQuery();
+    method public String getRawSchemeSpecificPart();
+    method public String getRawUserInfo();
+    method public String getScheme();
+    method public String getSchemeSpecificPart();
+    method public String getUserInfo();
+    method public boolean isAbsolute();
+    method public boolean isOpaque();
+    method public java.net.URI normalize();
+    method public java.net.URI parseServerAuthority() throws java.net.URISyntaxException;
+    method public java.net.URI relativize(java.net.URI);
+    method public java.net.URI resolve(java.net.URI);
+    method public java.net.URI resolve(String);
+    method public String toASCIIString();
+    method public java.net.URL toURL() throws java.net.MalformedURLException;
+  }
+
+  public class URISyntaxException extends java.lang.Exception {
+    ctor public URISyntaxException(String, String, int);
+    ctor public URISyntaxException(String, String);
+    method public int getIndex();
+    method public String getInput();
+    method public String getReason();
+  }
+
+  public final class URL implements java.io.Serializable {
+    ctor public URL(String, String, int, String) throws java.net.MalformedURLException;
+    ctor public URL(String, String, String) throws java.net.MalformedURLException;
+    ctor public URL(String, String, int, String, java.net.URLStreamHandler) throws java.net.MalformedURLException;
+    ctor public URL(String) throws java.net.MalformedURLException;
+    ctor public URL(java.net.URL, String) throws java.net.MalformedURLException;
+    ctor public URL(java.net.URL, String, java.net.URLStreamHandler) throws java.net.MalformedURLException;
+    method public String getAuthority();
+    method public Object getContent() throws java.io.IOException;
+    method public Object getContent(Class[]) throws java.io.IOException;
+    method public int getDefaultPort();
+    method public String getFile();
+    method public String getHost();
+    method public String getPath();
+    method public int getPort();
+    method public String getProtocol();
+    method public String getQuery();
+    method public String getRef();
+    method public String getUserInfo();
+    method public java.net.URLConnection openConnection() throws java.io.IOException;
+    method public java.net.URLConnection openConnection(java.net.Proxy) throws java.io.IOException;
+    method public java.io.InputStream openStream() throws java.io.IOException;
+    method public boolean sameFile(java.net.URL);
+    method public static void setURLStreamHandlerFactory(java.net.URLStreamHandlerFactory);
+    method public String toExternalForm();
+    method public java.net.URI toURI() throws java.net.URISyntaxException;
+  }
+
+  public class URLClassLoader extends java.security.SecureClassLoader implements java.io.Closeable {
+    ctor public URLClassLoader(java.net.URL[], ClassLoader);
+    ctor public URLClassLoader(java.net.URL[]);
+    ctor public URLClassLoader(java.net.URL[], ClassLoader, java.net.URLStreamHandlerFactory);
+    method protected void addURL(java.net.URL);
+    method public void close() throws java.io.IOException;
+    method protected Package definePackage(String, java.util.jar.Manifest, java.net.URL) throws java.lang.IllegalArgumentException;
+    method public java.net.URL findResource(String);
+    method public java.util.Enumeration<java.net.URL> findResources(String) throws java.io.IOException;
+    method public java.net.URL[] getURLs();
+    method public static java.net.URLClassLoader newInstance(java.net.URL[], ClassLoader);
+    method public static java.net.URLClassLoader newInstance(java.net.URL[]);
+  }
+
+  public abstract class URLConnection {
+    ctor protected URLConnection(java.net.URL);
+    method public void addRequestProperty(String, String);
+    method public abstract void connect() throws java.io.IOException;
+    method public boolean getAllowUserInteraction();
+    method public int getConnectTimeout();
+    method public Object getContent() throws java.io.IOException;
+    method public Object getContent(Class[]) throws java.io.IOException;
+    method public String getContentEncoding();
+    method public int getContentLength();
+    method public long getContentLengthLong();
+    method public String getContentType();
+    method public long getDate();
+    method public static boolean getDefaultAllowUserInteraction();
+    method @Deprecated public static String getDefaultRequestProperty(String);
+    method public boolean getDefaultUseCaches();
+    method public boolean getDoInput();
+    method public boolean getDoOutput();
+    method public long getExpiration();
+    method public static java.net.FileNameMap getFileNameMap();
+    method public String getHeaderField(String);
+    method public String getHeaderField(int);
+    method public long getHeaderFieldDate(String, long);
+    method public int getHeaderFieldInt(String, int);
+    method public String getHeaderFieldKey(int);
+    method public long getHeaderFieldLong(String, long);
+    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getHeaderFields();
+    method public long getIfModifiedSince();
+    method public java.io.InputStream getInputStream() throws java.io.IOException;
+    method public long getLastModified();
+    method public java.io.OutputStream getOutputStream() throws java.io.IOException;
+    method public java.security.Permission getPermission() throws java.io.IOException;
+    method public int getReadTimeout();
+    method public java.util.Map<java.lang.String,java.util.List<java.lang.String>> getRequestProperties();
+    method public String getRequestProperty(String);
+    method public java.net.URL getURL();
+    method public boolean getUseCaches();
+    method public static String guessContentTypeFromName(String);
+    method public static String guessContentTypeFromStream(java.io.InputStream) throws java.io.IOException;
+    method public void setAllowUserInteraction(boolean);
+    method public void setConnectTimeout(int);
+    method public static void setContentHandlerFactory(java.net.ContentHandlerFactory);
+    method public static void setDefaultAllowUserInteraction(boolean);
+    method @Deprecated public static void setDefaultRequestProperty(String, String);
+    method public void setDefaultUseCaches(boolean);
+    method public void setDoInput(boolean);
+    method public void setDoOutput(boolean);
+    method public static void setFileNameMap(java.net.FileNameMap);
+    method public void setIfModifiedSince(long);
+    method public void setReadTimeout(int);
+    method public void setRequestProperty(String, String);
+    method public void setUseCaches(boolean);
+    field protected boolean allowUserInteraction;
+    field protected boolean connected;
+    field protected boolean doInput;
+    field protected boolean doOutput;
+    field protected long ifModifiedSince;
+    field protected java.net.URL url;
+    field protected boolean useCaches;
+  }
+
+  public class URLDecoder {
+    ctor public URLDecoder();
+    method @Deprecated public static String decode(String);
+    method public static String decode(String, String) throws java.io.UnsupportedEncodingException;
+  }
+
+  public class URLEncoder {
+    method @Deprecated public static String encode(String);
+    method public static String encode(String, String) throws java.io.UnsupportedEncodingException;
+  }
+
+  public abstract class URLStreamHandler {
+    ctor public URLStreamHandler();
+    method protected boolean equals(java.net.URL, java.net.URL);
+    method protected int getDefaultPort();
+    method protected java.net.InetAddress getHostAddress(java.net.URL);
+    method protected int hashCode(java.net.URL);
+    method protected boolean hostsEqual(java.net.URL, java.net.URL);
+    method protected abstract java.net.URLConnection openConnection(java.net.URL) throws java.io.IOException;
+    method protected java.net.URLConnection openConnection(java.net.URL, java.net.Proxy) throws java.io.IOException;
+    method protected void parseURL(java.net.URL, String, int, int);
+    method protected boolean sameFile(java.net.URL, java.net.URL);
+    method protected void setURL(java.net.URL, String, String, int, String, String, String, String, String);
+    method @Deprecated protected void setURL(java.net.URL, String, String, int, String, String);
+    method protected String toExternalForm(java.net.URL);
+  }
+
+  public interface URLStreamHandlerFactory {
+    method public java.net.URLStreamHandler createURLStreamHandler(String);
+  }
+
+  public class UnknownHostException extends java.io.IOException {
+    ctor public UnknownHostException(String);
+    ctor public UnknownHostException();
+  }
+
+  public class UnknownServiceException extends java.io.IOException {
+    ctor public UnknownServiceException();
+    ctor public UnknownServiceException(String);
+  }
+
+}
+
+package java.nio {
+
+  public abstract class Buffer {
+    method public abstract Object array();
+    method public abstract int arrayOffset();
+    method public final int capacity();
+    method public java.nio.Buffer clear();
+    method public java.nio.Buffer flip();
+    method public abstract boolean hasArray();
+    method public final boolean hasRemaining();
+    method public abstract boolean isDirect();
+    method public abstract boolean isReadOnly();
+    method public final int limit();
+    method public java.nio.Buffer limit(int);
+    method public java.nio.Buffer mark();
+    method public final int position();
+    method public java.nio.Buffer position(int);
+    method public final int remaining();
+    method public java.nio.Buffer reset();
+    method public java.nio.Buffer rewind();
+  }
+
+  public class BufferOverflowException extends java.lang.RuntimeException {
+    ctor public BufferOverflowException();
+  }
+
+  public class BufferUnderflowException extends java.lang.RuntimeException {
+    ctor public BufferUnderflowException();
+  }
+
+  public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+    method @NonNull public static java.nio.ByteBuffer allocate(int);
+    method @NonNull public static java.nio.ByteBuffer allocateDirect(int);
+    method @NonNull public final byte[] array();
+    method public final int arrayOffset();
+    method @NonNull public abstract java.nio.CharBuffer asCharBuffer();
+    method @NonNull public abstract java.nio.DoubleBuffer asDoubleBuffer();
+    method @NonNull public abstract java.nio.FloatBuffer asFloatBuffer();
+    method @NonNull public abstract java.nio.IntBuffer asIntBuffer();
+    method @NonNull public abstract java.nio.LongBuffer asLongBuffer();
+    method @NonNull public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+    method @NonNull public abstract java.nio.ShortBuffer asShortBuffer();
+    method @NonNull public abstract java.nio.ByteBuffer compact();
+    method public int compareTo(@NonNull java.nio.ByteBuffer);
+    method @NonNull public abstract java.nio.ByteBuffer duplicate();
+    method public abstract byte get();
+    method public abstract byte get(int);
+    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[], int, int);
+    method @NonNull public java.nio.ByteBuffer get(@NonNull byte[]);
+    method public abstract char getChar();
+    method public abstract char getChar(int);
+    method public abstract double getDouble();
+    method public abstract double getDouble(int);
+    method public abstract float getFloat();
+    method public abstract float getFloat(int);
+    method public abstract int getInt();
+    method public abstract int getInt(int);
+    method public abstract long getLong();
+    method public abstract long getLong(int);
+    method public abstract short getShort();
+    method public abstract short getShort(int);
+    method public final boolean hasArray();
+    method @NonNull public final java.nio.ByteOrder order();
+    method @NonNull public final java.nio.ByteBuffer order(@NonNull java.nio.ByteOrder);
+    method @NonNull public abstract java.nio.ByteBuffer put(byte);
+    method @NonNull public abstract java.nio.ByteBuffer put(int, byte);
+    method @NonNull public java.nio.ByteBuffer put(@NonNull java.nio.ByteBuffer);
+    method @NonNull public java.nio.ByteBuffer put(@NonNull byte[], int, int);
+    method @NonNull public final java.nio.ByteBuffer put(@NonNull byte[]);
+    method @NonNull public abstract java.nio.ByteBuffer putChar(char);
+    method @NonNull public abstract java.nio.ByteBuffer putChar(int, char);
+    method @NonNull public abstract java.nio.ByteBuffer putDouble(double);
+    method @NonNull public abstract java.nio.ByteBuffer putDouble(int, double);
+    method @NonNull public abstract java.nio.ByteBuffer putFloat(float);
+    method @NonNull public abstract java.nio.ByteBuffer putFloat(int, float);
+    method @NonNull public abstract java.nio.ByteBuffer putInt(int);
+    method @NonNull public abstract java.nio.ByteBuffer putInt(int, int);
+    method @NonNull public abstract java.nio.ByteBuffer putLong(long);
+    method @NonNull public abstract java.nio.ByteBuffer putLong(int, long);
+    method @NonNull public abstract java.nio.ByteBuffer putShort(short);
+    method @NonNull public abstract java.nio.ByteBuffer putShort(int, short);
+    method @NonNull public abstract java.nio.ByteBuffer slice();
+    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[], int, int);
+    method @NonNull public static java.nio.ByteBuffer wrap(@NonNull byte[]);
+  }
+
+  public final class ByteOrder {
+    method public static java.nio.ByteOrder nativeOrder();
+    field public static final java.nio.ByteOrder BIG_ENDIAN;
+    field public static final java.nio.ByteOrder LITTLE_ENDIAN;
+  }
+
+  public abstract class CharBuffer extends java.nio.Buffer implements java.lang.Appendable java.lang.CharSequence java.lang.Comparable<java.nio.CharBuffer> java.lang.Readable {
+    method public static java.nio.CharBuffer allocate(int);
+    method public java.nio.CharBuffer append(CharSequence);
+    method public java.nio.CharBuffer append(CharSequence, int, int);
+    method public java.nio.CharBuffer append(char);
+    method public final char[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.CharBuffer asReadOnlyBuffer();
+    method public final char charAt(int);
+    method public abstract java.nio.CharBuffer compact();
+    method public int compareTo(java.nio.CharBuffer);
+    method public abstract java.nio.CharBuffer duplicate();
+    method public abstract char get();
+    method public abstract char get(int);
+    method public java.nio.CharBuffer get(char[], int, int);
+    method public java.nio.CharBuffer get(char[]);
+    method public final boolean hasArray();
+    method public final int length();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.CharBuffer put(char);
+    method public abstract java.nio.CharBuffer put(int, char);
+    method public java.nio.CharBuffer put(java.nio.CharBuffer);
+    method public java.nio.CharBuffer put(char[], int, int);
+    method public final java.nio.CharBuffer put(char[]);
+    method public java.nio.CharBuffer put(String, int, int);
+    method public final java.nio.CharBuffer put(String);
+    method public int read(java.nio.CharBuffer) throws java.io.IOException;
+    method public abstract java.nio.CharBuffer slice();
+    method public abstract java.nio.CharBuffer subSequence(int, int);
+    method public static java.nio.CharBuffer wrap(char[], int, int);
+    method public static java.nio.CharBuffer wrap(char[]);
+    method public static java.nio.CharBuffer wrap(CharSequence, int, int);
+    method public static java.nio.CharBuffer wrap(CharSequence);
+  }
+
+  public abstract class DoubleBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.DoubleBuffer> {
+    method public static java.nio.DoubleBuffer allocate(int);
+    method public final double[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.DoubleBuffer asReadOnlyBuffer();
+    method public abstract java.nio.DoubleBuffer compact();
+    method public int compareTo(java.nio.DoubleBuffer);
+    method public abstract java.nio.DoubleBuffer duplicate();
+    method public abstract double get();
+    method public abstract double get(int);
+    method public java.nio.DoubleBuffer get(double[], int, int);
+    method public java.nio.DoubleBuffer get(double[]);
+    method public final boolean hasArray();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.DoubleBuffer put(double);
+    method public abstract java.nio.DoubleBuffer put(int, double);
+    method public java.nio.DoubleBuffer put(java.nio.DoubleBuffer);
+    method public java.nio.DoubleBuffer put(double[], int, int);
+    method public final java.nio.DoubleBuffer put(double[]);
+    method public abstract java.nio.DoubleBuffer slice();
+    method public static java.nio.DoubleBuffer wrap(double[], int, int);
+    method public static java.nio.DoubleBuffer wrap(double[]);
+  }
+
+  public abstract class FloatBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.FloatBuffer> {
+    method public static java.nio.FloatBuffer allocate(int);
+    method public final float[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.FloatBuffer asReadOnlyBuffer();
+    method public abstract java.nio.FloatBuffer compact();
+    method public int compareTo(java.nio.FloatBuffer);
+    method public abstract java.nio.FloatBuffer duplicate();
+    method public abstract float get();
+    method public abstract float get(int);
+    method public java.nio.FloatBuffer get(float[], int, int);
+    method public java.nio.FloatBuffer get(float[]);
+    method public final boolean hasArray();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.FloatBuffer put(float);
+    method public abstract java.nio.FloatBuffer put(int, float);
+    method public java.nio.FloatBuffer put(java.nio.FloatBuffer);
+    method public java.nio.FloatBuffer put(float[], int, int);
+    method public final java.nio.FloatBuffer put(float[]);
+    method public abstract java.nio.FloatBuffer slice();
+    method public static java.nio.FloatBuffer wrap(float[], int, int);
+    method public static java.nio.FloatBuffer wrap(float[]);
+  }
+
+  public abstract class IntBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.IntBuffer> {
+    method public static java.nio.IntBuffer allocate(int);
+    method public final int[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.IntBuffer asReadOnlyBuffer();
+    method public abstract java.nio.IntBuffer compact();
+    method public int compareTo(java.nio.IntBuffer);
+    method public abstract java.nio.IntBuffer duplicate();
+    method public abstract int get();
+    method public abstract int get(int);
+    method public java.nio.IntBuffer get(int[], int, int);
+    method public java.nio.IntBuffer get(int[]);
+    method public final boolean hasArray();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.IntBuffer put(int);
+    method public abstract java.nio.IntBuffer put(int, int);
+    method public java.nio.IntBuffer put(java.nio.IntBuffer);
+    method public java.nio.IntBuffer put(int[], int, int);
+    method public final java.nio.IntBuffer put(int[]);
+    method public abstract java.nio.IntBuffer slice();
+    method public static java.nio.IntBuffer wrap(int[], int, int);
+    method public static java.nio.IntBuffer wrap(int[]);
+  }
+
+  public class InvalidMarkException extends java.lang.IllegalStateException {
+    ctor public InvalidMarkException();
+  }
+
+  public abstract class LongBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.LongBuffer> {
+    method public static java.nio.LongBuffer allocate(int);
+    method public final long[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.LongBuffer asReadOnlyBuffer();
+    method public abstract java.nio.LongBuffer compact();
+    method public int compareTo(java.nio.LongBuffer);
+    method public abstract java.nio.LongBuffer duplicate();
+    method public abstract long get();
+    method public abstract long get(int);
+    method public java.nio.LongBuffer get(long[], int, int);
+    method public java.nio.LongBuffer get(long[]);
+    method public final boolean hasArray();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.LongBuffer put(long);
+    method public abstract java.nio.LongBuffer put(int, long);
+    method public java.nio.LongBuffer put(java.nio.LongBuffer);
+    method public java.nio.LongBuffer put(long[], int, int);
+    method public final java.nio.LongBuffer put(long[]);
+    method public abstract java.nio.LongBuffer slice();
+    method public static java.nio.LongBuffer wrap(long[], int, int);
+    method public static java.nio.LongBuffer wrap(long[]);
+  }
+
+  public abstract class MappedByteBuffer extends java.nio.ByteBuffer {
+    method public final java.nio.MappedByteBuffer force();
+    method public final boolean isLoaded();
+    method public final java.nio.MappedByteBuffer load();
+  }
+
+  public class ReadOnlyBufferException extends java.lang.UnsupportedOperationException {
+    ctor public ReadOnlyBufferException();
+  }
+
+  public abstract class ShortBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ShortBuffer> {
+    method public static java.nio.ShortBuffer allocate(int);
+    method public final short[] array();
+    method public final int arrayOffset();
+    method public abstract java.nio.ShortBuffer asReadOnlyBuffer();
+    method public abstract java.nio.ShortBuffer compact();
+    method public int compareTo(java.nio.ShortBuffer);
+    method public abstract java.nio.ShortBuffer duplicate();
+    method public abstract short get();
+    method public abstract short get(int);
+    method public java.nio.ShortBuffer get(short[], int, int);
+    method public java.nio.ShortBuffer get(short[]);
+    method public final boolean hasArray();
+    method public abstract java.nio.ByteOrder order();
+    method public abstract java.nio.ShortBuffer put(short);
+    method public abstract java.nio.ShortBuffer put(int, short);
+    method public java.nio.ShortBuffer put(java.nio.ShortBuffer);
+    method public java.nio.ShortBuffer put(short[], int, int);
+    method public final java.nio.ShortBuffer put(short[]);
+    method public abstract java.nio.ShortBuffer slice();
+    method public static java.nio.ShortBuffer wrap(short[], int, int);
+    method public static java.nio.ShortBuffer wrap(short[]);
+  }
+
+}
+
+package java.nio.channels {
+
+  public class AcceptPendingException extends java.lang.IllegalStateException {
+    ctor public AcceptPendingException();
+  }
+
+  public class AlreadyBoundException extends java.lang.IllegalStateException {
+    ctor public AlreadyBoundException();
+  }
+
+  public class AlreadyConnectedException extends java.lang.IllegalStateException {
+    ctor public AlreadyConnectedException();
+  }
+
+  public interface AsynchronousByteChannel extends java.nio.channels.AsynchronousChannel {
+    method public <A> void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer);
+    method public <A> void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer);
+  }
+
+  public interface AsynchronousChannel extends java.nio.channels.Channel {
+  }
+
+  public abstract class AsynchronousChannelGroup {
+    ctor protected AsynchronousChannelGroup(java.nio.channels.spi.AsynchronousChannelProvider);
+    method public abstract boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public abstract boolean isShutdown();
+    method public abstract boolean isTerminated();
+    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
+    method public abstract void shutdown();
+    method public abstract void shutdownNow() throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousChannelGroup withCachedThreadPool(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousChannelGroup withFixedThreadPool(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousChannelGroup withThreadPool(java.util.concurrent.ExecutorService) throws java.io.IOException;
+  }
+
+  public class AsynchronousCloseException extends java.nio.channels.ClosedChannelException {
+    ctor public AsynchronousCloseException();
+  }
+
+  public abstract class AsynchronousFileChannel implements java.nio.channels.AsynchronousChannel {
+    ctor protected AsynchronousFileChannel();
+    method public abstract void force(boolean) throws java.io.IOException;
+    method public abstract <A> void lock(long, long, boolean, A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock,? super A>);
+    method public final <A> void lock(A, java.nio.channels.CompletionHandler<java.nio.channels.FileLock,? super A>);
+    method public abstract java.util.concurrent.Future<java.nio.channels.FileLock> lock(long, long, boolean);
+    method public final java.util.concurrent.Future<java.nio.channels.FileLock> lock();
+    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousFileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public abstract <A> void read(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public abstract java.util.concurrent.Future<java.lang.Integer> read(java.nio.ByteBuffer, long);
+    method public abstract long size() throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousFileChannel truncate(long) throws java.io.IOException;
+    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
+    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
+    method public abstract <A> void write(java.nio.ByteBuffer, long, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public abstract java.util.concurrent.Future<java.lang.Integer> write(java.nio.ByteBuffer, long);
+  }
+
+  public abstract class AsynchronousServerSocketChannel implements java.nio.channels.AsynchronousChannel java.nio.channels.NetworkChannel {
+    ctor protected AsynchronousServerSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
+    method public abstract <A> void accept(A, java.nio.channels.CompletionHandler<java.nio.channels.AsynchronousSocketChannel,? super A>);
+    method public abstract java.util.concurrent.Future<java.nio.channels.AsynchronousSocketChannel> accept();
+    method public final java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousServerSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousServerSocketChannel open() throws java.io.IOException;
+    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
+    method public abstract <T> java.nio.channels.AsynchronousServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+  }
+
+  public abstract class AsynchronousSocketChannel implements java.nio.channels.AsynchronousByteChannel java.nio.channels.NetworkChannel {
+    ctor protected AsynchronousSocketChannel(java.nio.channels.spi.AsynchronousChannelProvider);
+    method public abstract java.nio.channels.AsynchronousSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract <A> void connect(java.net.SocketAddress, A, java.nio.channels.CompletionHandler<java.lang.Void,? super A>);
+    method public abstract java.util.concurrent.Future<java.lang.Void> connect(java.net.SocketAddress);
+    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousSocketChannel open(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
+    method public static java.nio.channels.AsynchronousSocketChannel open() throws java.io.IOException;
+    method public final java.nio.channels.spi.AsynchronousChannelProvider provider();
+    method public abstract <A> void read(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public final <A> void read(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public abstract <A> void read(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long,? super A>);
+    method public abstract <T> java.nio.channels.AsynchronousSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownInput() throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousSocketChannel shutdownOutput() throws java.io.IOException;
+    method public abstract <A> void write(java.nio.ByteBuffer, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public final <A> void write(java.nio.ByteBuffer, A, java.nio.channels.CompletionHandler<java.lang.Integer,? super A>);
+    method public abstract <A> void write(java.nio.ByteBuffer[], int, int, long, java.util.concurrent.TimeUnit, A, java.nio.channels.CompletionHandler<java.lang.Long,? super A>);
+  }
+
+  public interface ByteChannel extends java.nio.channels.ReadableByteChannel java.nio.channels.WritableByteChannel {
+  }
+
+  public class CancelledKeyException extends java.lang.IllegalStateException {
+    ctor public CancelledKeyException();
+  }
+
+  public interface Channel extends java.io.Closeable {
+    method public boolean isOpen();
+  }
+
+  public final class Channels {
+    method public static java.nio.channels.ReadableByteChannel newChannel(java.io.InputStream);
+    method public static java.nio.channels.WritableByteChannel newChannel(java.io.OutputStream);
+    method public static java.io.InputStream newInputStream(java.nio.channels.ReadableByteChannel);
+    method public static java.io.InputStream newInputStream(java.nio.channels.AsynchronousByteChannel);
+    method public static java.io.OutputStream newOutputStream(java.nio.channels.WritableByteChannel);
+    method public static java.io.OutputStream newOutputStream(java.nio.channels.AsynchronousByteChannel);
+    method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, java.nio.charset.CharsetDecoder, int);
+    method public static java.io.Reader newReader(java.nio.channels.ReadableByteChannel, String);
+    method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, java.nio.charset.CharsetEncoder, int);
+    method public static java.io.Writer newWriter(java.nio.channels.WritableByteChannel, String);
+  }
+
+  public class ClosedByInterruptException extends java.nio.channels.AsynchronousCloseException {
+    ctor public ClosedByInterruptException();
+  }
+
+  public class ClosedChannelException extends java.io.IOException {
+    ctor public ClosedChannelException();
+  }
+
+  public class ClosedSelectorException extends java.lang.IllegalStateException {
+    ctor public ClosedSelectorException();
+  }
+
+  public interface CompletionHandler<V, A> {
+    method public void completed(V, A);
+    method public void failed(Throwable, A);
+  }
+
+  public class ConnectionPendingException extends java.lang.IllegalStateException {
+    ctor public ConnectionPendingException();
+  }
+
+  public abstract class DatagramChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.MulticastChannel java.nio.channels.ScatteringByteChannel {
+    ctor protected DatagramChannel(java.nio.channels.spi.SelectorProvider);
+    method public abstract java.nio.channels.DatagramChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.nio.channels.DatagramChannel connect(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.nio.channels.DatagramChannel disconnect() throws java.io.IOException;
+    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
+    method public abstract boolean isConnected();
+    method public static java.nio.channels.DatagramChannel open() throws java.io.IOException;
+    method public static java.nio.channels.DatagramChannel open(java.net.ProtocolFamily) throws java.io.IOException;
+    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public abstract java.net.SocketAddress receive(java.nio.ByteBuffer) throws java.io.IOException;
+    method public abstract int send(java.nio.ByteBuffer, java.net.SocketAddress) throws java.io.IOException;
+    method public abstract <T> java.nio.channels.DatagramChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.net.DatagramSocket socket();
+    method public final int validOps();
+    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
+  }
+
+  public abstract class FileChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.ScatteringByteChannel java.nio.channels.SeekableByteChannel {
+    ctor protected FileChannel();
+    method public abstract void force(boolean) throws java.io.IOException;
+    method public abstract java.nio.channels.FileLock lock(long, long, boolean) throws java.io.IOException;
+    method public final java.nio.channels.FileLock lock() throws java.io.IOException;
+    method public abstract java.nio.MappedByteBuffer map(java.nio.channels.FileChannel.MapMode, long, long) throws java.io.IOException;
+    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.channels.FileChannel open(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public abstract java.nio.channels.FileChannel position(long) throws java.io.IOException;
+    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public abstract int read(java.nio.ByteBuffer, long) throws java.io.IOException;
+    method public abstract long transferFrom(java.nio.channels.ReadableByteChannel, long, long) throws java.io.IOException;
+    method public abstract long transferTo(long, long, java.nio.channels.WritableByteChannel) throws java.io.IOException;
+    method public abstract java.nio.channels.FileChannel truncate(long) throws java.io.IOException;
+    method public abstract java.nio.channels.FileLock tryLock(long, long, boolean) throws java.io.IOException;
+    method public final java.nio.channels.FileLock tryLock() throws java.io.IOException;
+    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public abstract int write(java.nio.ByteBuffer, long) throws java.io.IOException;
+  }
+
+  public static class FileChannel.MapMode {
+    field public static final java.nio.channels.FileChannel.MapMode PRIVATE;
+    field public static final java.nio.channels.FileChannel.MapMode READ_ONLY;
+    field public static final java.nio.channels.FileChannel.MapMode READ_WRITE;
+  }
+
+  public abstract class FileLock implements java.lang.AutoCloseable {
+    ctor protected FileLock(java.nio.channels.FileChannel, long, long, boolean);
+    ctor protected FileLock(java.nio.channels.AsynchronousFileChannel, long, long, boolean);
+    method public java.nio.channels.Channel acquiredBy();
+    method public final java.nio.channels.FileChannel channel();
+    method public final void close() throws java.io.IOException;
+    method public final boolean isShared();
+    method public abstract boolean isValid();
+    method public final boolean overlaps(long, long);
+    method public final long position();
+    method public abstract void release() throws java.io.IOException;
+    method public final long size();
+    method public final String toString();
+  }
+
+  public class FileLockInterruptionException extends java.io.IOException {
+    ctor public FileLockInterruptionException();
+  }
+
+  public interface GatheringByteChannel extends java.nio.channels.WritableByteChannel {
+    method public long write(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
+    method public long write(java.nio.ByteBuffer[]) throws java.io.IOException;
+  }
+
+  public class IllegalBlockingModeException extends java.lang.IllegalStateException {
+    ctor public IllegalBlockingModeException();
+  }
+
+  public class IllegalChannelGroupException extends java.lang.IllegalArgumentException {
+    ctor public IllegalChannelGroupException();
+  }
+
+  public class IllegalSelectorException extends java.lang.IllegalArgumentException {
+    ctor public IllegalSelectorException();
+  }
+
+  public class InterruptedByTimeoutException extends java.io.IOException {
+    ctor public InterruptedByTimeoutException();
+  }
+
+  public interface InterruptibleChannel extends java.nio.channels.Channel {
+  }
+
+  public abstract class MembershipKey {
+    ctor protected MembershipKey();
+    method public abstract java.nio.channels.MembershipKey block(java.net.InetAddress) throws java.io.IOException;
+    method public abstract java.nio.channels.MulticastChannel channel();
+    method public abstract void drop();
+    method public abstract java.net.InetAddress group();
+    method public abstract boolean isValid();
+    method public abstract java.net.NetworkInterface networkInterface();
+    method public abstract java.net.InetAddress sourceAddress();
+    method public abstract java.nio.channels.MembershipKey unblock(java.net.InetAddress);
+  }
+
+  public interface MulticastChannel extends java.nio.channels.NetworkChannel {
+    method public java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface) throws java.io.IOException;
+    method public java.nio.channels.MembershipKey join(java.net.InetAddress, java.net.NetworkInterface, java.net.InetAddress) throws java.io.IOException;
+  }
+
+  public interface NetworkChannel extends java.nio.channels.Channel {
+    method public java.nio.channels.NetworkChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public java.net.SocketAddress getLocalAddress() throws java.io.IOException;
+    method public <T> T getOption(java.net.SocketOption<T>) throws java.io.IOException;
+    method public <T> java.nio.channels.NetworkChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public java.util.Set<java.net.SocketOption<?>> supportedOptions();
+  }
+
+  public class NoConnectionPendingException extends java.lang.IllegalStateException {
+    ctor public NoConnectionPendingException();
+  }
+
+  public class NonReadableChannelException extends java.lang.IllegalStateException {
+    ctor public NonReadableChannelException();
+  }
+
+  public class NonWritableChannelException extends java.lang.IllegalStateException {
+    ctor public NonWritableChannelException();
+  }
+
+  public class NotYetBoundException extends java.lang.IllegalStateException {
+    ctor public NotYetBoundException();
+  }
+
+  public class NotYetConnectedException extends java.lang.IllegalStateException {
+    ctor public NotYetConnectedException();
+  }
+
+  public class OverlappingFileLockException extends java.lang.IllegalStateException {
+    ctor public OverlappingFileLockException();
+  }
+
+  public abstract class Pipe {
+    ctor protected Pipe();
+    method public static java.nio.channels.Pipe open() throws java.io.IOException;
+    method public abstract java.nio.channels.Pipe.SinkChannel sink();
+    method public abstract java.nio.channels.Pipe.SourceChannel source();
+  }
+
+  public abstract static class Pipe.SinkChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.GatheringByteChannel java.nio.channels.WritableByteChannel {
+    ctor protected Pipe.SinkChannel(java.nio.channels.spi.SelectorProvider);
+    method public final int validOps();
+  }
+
+  public abstract static class Pipe.SourceChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ReadableByteChannel java.nio.channels.ScatteringByteChannel {
+    ctor protected Pipe.SourceChannel(java.nio.channels.spi.SelectorProvider);
+    method public final int validOps();
+  }
+
+  public class ReadPendingException extends java.lang.IllegalStateException {
+    ctor public ReadPendingException();
+  }
+
+  public interface ReadableByteChannel extends java.nio.channels.Channel {
+    method public int read(java.nio.ByteBuffer) throws java.io.IOException;
+  }
+
+  public interface ScatteringByteChannel extends java.nio.channels.ReadableByteChannel {
+    method public long read(java.nio.ByteBuffer[], int, int) throws java.io.IOException;
+    method public long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+  }
+
+  public interface SeekableByteChannel extends java.nio.channels.ByteChannel {
+    method public long position() throws java.io.IOException;
+    method public java.nio.channels.SeekableByteChannel position(long) throws java.io.IOException;
+    method public long size() throws java.io.IOException;
+    method public java.nio.channels.SeekableByteChannel truncate(long) throws java.io.IOException;
+  }
+
+  public abstract class SelectableChannel extends java.nio.channels.spi.AbstractInterruptibleChannel implements java.nio.channels.Channel {
+    ctor protected SelectableChannel();
+    method public abstract Object blockingLock();
+    method public abstract java.nio.channels.SelectableChannel configureBlocking(boolean) throws java.io.IOException;
+    method public abstract boolean isBlocking();
+    method public abstract boolean isRegistered();
+    method public abstract java.nio.channels.SelectionKey keyFor(java.nio.channels.Selector);
+    method public abstract java.nio.channels.spi.SelectorProvider provider();
+    method public abstract java.nio.channels.SelectionKey register(java.nio.channels.Selector, int, Object) throws java.nio.channels.ClosedChannelException;
+    method public final java.nio.channels.SelectionKey register(java.nio.channels.Selector, int) throws java.nio.channels.ClosedChannelException;
+    method public abstract int validOps();
+  }
+
+  public abstract class SelectionKey {
+    ctor protected SelectionKey();
+    method public final Object attach(Object);
+    method public final Object attachment();
+    method public abstract void cancel();
+    method public abstract java.nio.channels.SelectableChannel channel();
+    method public abstract int interestOps();
+    method public abstract java.nio.channels.SelectionKey interestOps(int);
+    method public final boolean isAcceptable();
+    method public final boolean isConnectable();
+    method public final boolean isReadable();
+    method public abstract boolean isValid();
+    method public final boolean isWritable();
+    method public abstract int readyOps();
+    method public abstract java.nio.channels.Selector selector();
+    field public static final int OP_ACCEPT = 16; // 0x10
+    field public static final int OP_CONNECT = 8; // 0x8
+    field public static final int OP_READ = 1; // 0x1
+    field public static final int OP_WRITE = 4; // 0x4
+  }
+
+  public abstract class Selector implements java.io.Closeable {
+    ctor protected Selector();
+    method public abstract boolean isOpen();
+    method public abstract java.util.Set<java.nio.channels.SelectionKey> keys();
+    method public static java.nio.channels.Selector open() throws java.io.IOException;
+    method public abstract java.nio.channels.spi.SelectorProvider provider();
+    method public abstract int select(long) throws java.io.IOException;
+    method public abstract int select() throws java.io.IOException;
+    method public abstract int selectNow() throws java.io.IOException;
+    method public abstract java.util.Set<java.nio.channels.SelectionKey> selectedKeys();
+    method public abstract java.nio.channels.Selector wakeup();
+  }
+
+  public abstract class ServerSocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.NetworkChannel {
+    ctor protected ServerSocketChannel(java.nio.channels.spi.SelectorProvider);
+    method public abstract java.nio.channels.SocketChannel accept() throws java.io.IOException;
+    method public final java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract java.nio.channels.ServerSocketChannel bind(java.net.SocketAddress, int) throws java.io.IOException;
+    method public static java.nio.channels.ServerSocketChannel open() throws java.io.IOException;
+    method public abstract <T> java.nio.channels.ServerSocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.net.ServerSocket socket();
+    method public final int validOps();
+  }
+
+  public class ShutdownChannelGroupException extends java.lang.IllegalStateException {
+    ctor public ShutdownChannelGroupException();
+  }
+
+  public abstract class SocketChannel extends java.nio.channels.spi.AbstractSelectableChannel implements java.nio.channels.ByteChannel java.nio.channels.GatheringByteChannel java.nio.channels.NetworkChannel java.nio.channels.ScatteringByteChannel {
+    ctor protected SocketChannel(java.nio.channels.spi.SelectorProvider);
+    method public abstract java.nio.channels.SocketChannel bind(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract boolean connect(java.net.SocketAddress) throws java.io.IOException;
+    method public abstract boolean finishConnect() throws java.io.IOException;
+    method public abstract java.net.SocketAddress getRemoteAddress() throws java.io.IOException;
+    method public abstract boolean isConnected();
+    method public abstract boolean isConnectionPending();
+    method public static java.nio.channels.SocketChannel open() throws java.io.IOException;
+    method public static java.nio.channels.SocketChannel open(java.net.SocketAddress) throws java.io.IOException;
+    method public final long read(java.nio.ByteBuffer[]) throws java.io.IOException;
+    method public abstract <T> java.nio.channels.SocketChannel setOption(java.net.SocketOption<T>, T) throws java.io.IOException;
+    method public abstract java.nio.channels.SocketChannel shutdownInput() throws java.io.IOException;
+    method public abstract java.nio.channels.SocketChannel shutdownOutput() throws java.io.IOException;
+    method public abstract java.net.Socket socket();
+    method public final int validOps();
+    method public final long write(java.nio.ByteBuffer[]) throws java.io.IOException;
+  }
+
+  public class UnresolvedAddressException extends java.lang.IllegalArgumentException {
+    ctor public UnresolvedAddressException();
+  }
+
+  public class UnsupportedAddressTypeException extends java.lang.IllegalArgumentException {
+    ctor public UnsupportedAddressTypeException();
+  }
+
+  public interface WritableByteChannel extends java.nio.channels.Channel {
+    method public int write(java.nio.ByteBuffer) throws java.io.IOException;
+  }
+
+  public class WritePendingException extends java.lang.IllegalStateException {
+    ctor public WritePendingException();
+  }
+
+}
+
+package java.nio.channels.spi {
+
+  public abstract class AbstractInterruptibleChannel implements java.nio.channels.Channel java.nio.channels.InterruptibleChannel {
+    ctor protected AbstractInterruptibleChannel();
+    method protected final void begin();
+    method public final void close() throws java.io.IOException;
+    method protected final void end(boolean) throws java.nio.channels.AsynchronousCloseException;
+    method protected abstract void implCloseChannel() throws java.io.IOException;
+    method public final boolean isOpen();
+  }
+
+  public abstract class AbstractSelectableChannel extends java.nio.channels.SelectableChannel {
+    ctor protected AbstractSelectableChannel(java.nio.channels.spi.SelectorProvider);
+    method public final Object blockingLock();
+    method public final java.nio.channels.SelectableChannel configureBlocking(boolean) throws java.io.IOException;
+    method protected final void implCloseChannel() throws java.io.IOException;
+    method protected abstract void implCloseSelectableChannel() throws java.io.IOException;
+    method protected abstract void implConfigureBlocking(boolean) throws java.io.IOException;
+    method public final boolean isBlocking();
+    method public final boolean isRegistered();
+    method public final java.nio.channels.SelectionKey keyFor(java.nio.channels.Selector);
+    method public final java.nio.channels.spi.SelectorProvider provider();
+    method public final java.nio.channels.SelectionKey register(java.nio.channels.Selector, int, Object) throws java.nio.channels.ClosedChannelException;
+  }
+
+  public abstract class AbstractSelectionKey extends java.nio.channels.SelectionKey {
+    ctor protected AbstractSelectionKey();
+    method public final void cancel();
+    method public final boolean isValid();
+  }
+
+  public abstract class AbstractSelector extends java.nio.channels.Selector {
+    ctor protected AbstractSelector(java.nio.channels.spi.SelectorProvider);
+    method protected final void begin();
+    method protected final java.util.Set<java.nio.channels.SelectionKey> cancelledKeys();
+    method public final void close() throws java.io.IOException;
+    method protected final void deregister(java.nio.channels.spi.AbstractSelectionKey);
+    method protected final void end();
+    method protected abstract void implCloseSelector() throws java.io.IOException;
+    method public final boolean isOpen();
+    method public final java.nio.channels.spi.SelectorProvider provider();
+    method protected abstract java.nio.channels.SelectionKey register(java.nio.channels.spi.AbstractSelectableChannel, int, Object);
+  }
+
+  public abstract class AsynchronousChannelProvider {
+    ctor protected AsynchronousChannelProvider();
+    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(int, java.util.concurrent.ThreadFactory) throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousChannelGroup openAsynchronousChannelGroup(java.util.concurrent.ExecutorService, int) throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
+    method public abstract java.nio.channels.AsynchronousSocketChannel openAsynchronousSocketChannel(java.nio.channels.AsynchronousChannelGroup) throws java.io.IOException;
+    method public static java.nio.channels.spi.AsynchronousChannelProvider provider();
+  }
+
+  public abstract class SelectorProvider {
+    ctor protected SelectorProvider();
+    method public java.nio.channels.Channel inheritedChannel() throws java.io.IOException;
+    method public abstract java.nio.channels.DatagramChannel openDatagramChannel() throws java.io.IOException;
+    method public abstract java.nio.channels.DatagramChannel openDatagramChannel(java.net.ProtocolFamily) throws java.io.IOException;
+    method public abstract java.nio.channels.Pipe openPipe() throws java.io.IOException;
+    method public abstract java.nio.channels.spi.AbstractSelector openSelector() throws java.io.IOException;
+    method public abstract java.nio.channels.ServerSocketChannel openServerSocketChannel() throws java.io.IOException;
+    method public abstract java.nio.channels.SocketChannel openSocketChannel() throws java.io.IOException;
+    method public static java.nio.channels.spi.SelectorProvider provider();
+  }
+
+}
+
+package java.nio.charset {
+
+  public class CharacterCodingException extends java.io.IOException {
+    ctor public CharacterCodingException();
+  }
+
+  public abstract class Charset implements java.lang.Comparable<java.nio.charset.Charset> {
+    ctor protected Charset(String, String[]);
+    method public final java.util.Set<java.lang.String> aliases();
+    method public static java.util.SortedMap<java.lang.String,java.nio.charset.Charset> availableCharsets();
+    method public boolean canEncode();
+    method public final int compareTo(java.nio.charset.Charset);
+    method public abstract boolean contains(java.nio.charset.Charset);
+    method public final java.nio.CharBuffer decode(java.nio.ByteBuffer);
+    method public static java.nio.charset.Charset defaultCharset();
+    method public String displayName();
+    method public String displayName(java.util.Locale);
+    method public final java.nio.ByteBuffer encode(java.nio.CharBuffer);
+    method public final java.nio.ByteBuffer encode(String);
+    method public final boolean equals(Object);
+    method public static java.nio.charset.Charset forName(String);
+    method public final int hashCode();
+    method public final boolean isRegistered();
+    method public static boolean isSupported(String);
+    method public final String name();
+    method public abstract java.nio.charset.CharsetDecoder newDecoder();
+    method public abstract java.nio.charset.CharsetEncoder newEncoder();
+    method public final String toString();
+  }
+
+  public abstract class CharsetDecoder {
+    ctor protected CharsetDecoder(java.nio.charset.Charset, float, float);
+    method public final float averageCharsPerByte();
+    method public final java.nio.charset.Charset charset();
+    method public final java.nio.charset.CoderResult decode(java.nio.ByteBuffer, java.nio.CharBuffer, boolean);
+    method public final java.nio.CharBuffer decode(java.nio.ByteBuffer) throws java.nio.charset.CharacterCodingException;
+    method protected abstract java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer, java.nio.CharBuffer);
+    method public java.nio.charset.Charset detectedCharset();
+    method public final java.nio.charset.CoderResult flush(java.nio.CharBuffer);
+    method protected java.nio.charset.CoderResult implFlush(java.nio.CharBuffer);
+    method protected void implOnMalformedInput(java.nio.charset.CodingErrorAction);
+    method protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction);
+    method protected void implReplaceWith(String);
+    method protected void implReset();
+    method public boolean isAutoDetecting();
+    method public boolean isCharsetDetected();
+    method public java.nio.charset.CodingErrorAction malformedInputAction();
+    method public final float maxCharsPerByte();
+    method public final java.nio.charset.CharsetDecoder onMalformedInput(java.nio.charset.CodingErrorAction);
+    method public final java.nio.charset.CharsetDecoder onUnmappableCharacter(java.nio.charset.CodingErrorAction);
+    method public final java.nio.charset.CharsetDecoder replaceWith(String);
+    method public final String replacement();
+    method public final java.nio.charset.CharsetDecoder reset();
+    method public java.nio.charset.CodingErrorAction unmappableCharacterAction();
+  }
+
+  public abstract class CharsetEncoder {
+    ctor protected CharsetEncoder(java.nio.charset.Charset, float, float, byte[]);
+    ctor protected CharsetEncoder(java.nio.charset.Charset, float, float);
+    method public final float averageBytesPerChar();
+    method public boolean canEncode(char);
+    method public boolean canEncode(CharSequence);
+    method public final java.nio.charset.Charset charset();
+    method public final java.nio.charset.CoderResult encode(java.nio.CharBuffer, java.nio.ByteBuffer, boolean);
+    method public final java.nio.ByteBuffer encode(java.nio.CharBuffer) throws java.nio.charset.CharacterCodingException;
+    method protected abstract java.nio.charset.CoderResult encodeLoop(java.nio.CharBuffer, java.nio.ByteBuffer);
+    method public final java.nio.charset.CoderResult flush(java.nio.ByteBuffer);
+    method protected java.nio.charset.CoderResult implFlush(java.nio.ByteBuffer);
+    method protected void implOnMalformedInput(java.nio.charset.CodingErrorAction);
+    method protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction);
+    method protected void implReplaceWith(byte[]);
+    method protected void implReset();
+    method public boolean isLegalReplacement(byte[]);
+    method public java.nio.charset.CodingErrorAction malformedInputAction();
+    method public final float maxBytesPerChar();
+    method public final java.nio.charset.CharsetEncoder onMalformedInput(java.nio.charset.CodingErrorAction);
+    method public final java.nio.charset.CharsetEncoder onUnmappableCharacter(java.nio.charset.CodingErrorAction);
+    method public final java.nio.charset.CharsetEncoder replaceWith(byte[]);
+    method public final byte[] replacement();
+    method public final java.nio.charset.CharsetEncoder reset();
+    method public java.nio.charset.CodingErrorAction unmappableCharacterAction();
+  }
+
+  public class CoderMalfunctionError extends java.lang.Error {
+    ctor public CoderMalfunctionError(Exception);
+  }
+
+  public class CoderResult {
+    method public boolean isError();
+    method public boolean isMalformed();
+    method public boolean isOverflow();
+    method public boolean isUnderflow();
+    method public boolean isUnmappable();
+    method public int length();
+    method public static java.nio.charset.CoderResult malformedForLength(int);
+    method public void throwException() throws java.nio.charset.CharacterCodingException;
+    method public static java.nio.charset.CoderResult unmappableForLength(int);
+    field public static final java.nio.charset.CoderResult OVERFLOW;
+    field public static final java.nio.charset.CoderResult UNDERFLOW;
+  }
+
+  public class CodingErrorAction {
+    field public static final java.nio.charset.CodingErrorAction IGNORE;
+    field public static final java.nio.charset.CodingErrorAction REPLACE;
+    field public static final java.nio.charset.CodingErrorAction REPORT;
+  }
+
+  public class IllegalCharsetNameException extends java.lang.IllegalArgumentException {
+    ctor public IllegalCharsetNameException(String);
+    method public String getCharsetName();
+  }
+
+  public class MalformedInputException extends java.nio.charset.CharacterCodingException {
+    ctor public MalformedInputException(int);
+    method public int getInputLength();
+  }
+
+  public final class StandardCharsets {
+    field public static final java.nio.charset.Charset ISO_8859_1;
+    field public static final java.nio.charset.Charset US_ASCII;
+    field public static final java.nio.charset.Charset UTF_16;
+    field public static final java.nio.charset.Charset UTF_16BE;
+    field public static final java.nio.charset.Charset UTF_16LE;
+    field public static final java.nio.charset.Charset UTF_8;
+  }
+
+  public class UnmappableCharacterException extends java.nio.charset.CharacterCodingException {
+    ctor public UnmappableCharacterException(int);
+    method public int getInputLength();
+  }
+
+  public class UnsupportedCharsetException extends java.lang.IllegalArgumentException {
+    ctor public UnsupportedCharsetException(String);
+    method public String getCharsetName();
+  }
+
+}
+
+package java.nio.charset.spi {
+
+  public abstract class CharsetProvider {
+    ctor protected CharsetProvider();
+    method public abstract java.nio.charset.Charset charsetForName(String);
+    method public abstract java.util.Iterator<java.nio.charset.Charset> charsets();
+  }
+
+}
+
+package java.nio.file {
+
+  public class AccessDeniedException extends java.nio.file.FileSystemException {
+    ctor public AccessDeniedException(String);
+    ctor public AccessDeniedException(String, String, String);
+  }
+
+  public enum AccessMode {
+    enum_constant public static final java.nio.file.AccessMode EXECUTE;
+    enum_constant public static final java.nio.file.AccessMode READ;
+    enum_constant public static final java.nio.file.AccessMode WRITE;
+  }
+
+  public class AtomicMoveNotSupportedException extends java.nio.file.FileSystemException {
+    ctor public AtomicMoveNotSupportedException(String, String, String);
+  }
+
+  public class ClosedDirectoryStreamException extends java.lang.IllegalStateException {
+    ctor public ClosedDirectoryStreamException();
+  }
+
+  public class ClosedFileSystemException extends java.lang.IllegalStateException {
+    ctor public ClosedFileSystemException();
+  }
+
+  public class ClosedWatchServiceException extends java.lang.IllegalStateException {
+    ctor public ClosedWatchServiceException();
+  }
+
+  public interface CopyOption {
+  }
+
+  public final class DirectoryIteratorException extends java.util.ConcurrentModificationException {
+    ctor public DirectoryIteratorException(java.io.IOException);
+    method public java.io.IOException getCause();
+  }
+
+  public class DirectoryNotEmptyException extends java.nio.file.FileSystemException {
+    ctor public DirectoryNotEmptyException(String);
+  }
+
+  public interface DirectoryStream<T> extends java.io.Closeable java.lang.Iterable<T> {
+  }
+
+  @java.lang.FunctionalInterface public static interface DirectoryStream.Filter<T> {
+    method public boolean accept(T) throws java.io.IOException;
+  }
+
+  public class FileAlreadyExistsException extends java.nio.file.FileSystemException {
+    ctor public FileAlreadyExistsException(String);
+    ctor public FileAlreadyExistsException(String, String, String);
+  }
+
+  public abstract class FileStore {
+    ctor protected FileStore();
+    method public abstract Object getAttribute(String) throws java.io.IOException;
+    method public abstract <V extends java.nio.file.attribute.FileStoreAttributeView> V getFileStoreAttributeView(Class<V>);
+    method public abstract long getTotalSpace() throws java.io.IOException;
+    method public abstract long getUnallocatedSpace() throws java.io.IOException;
+    method public abstract long getUsableSpace() throws java.io.IOException;
+    method public abstract boolean isReadOnly();
+    method public abstract String name();
+    method public abstract boolean supportsFileAttributeView(Class<? extends java.nio.file.attribute.FileAttributeView>);
+    method public abstract boolean supportsFileAttributeView(String);
+    method public abstract String type();
+  }
+
+  public abstract class FileSystem implements java.io.Closeable {
+    ctor protected FileSystem();
+    method public abstract Iterable<java.nio.file.FileStore> getFileStores();
+    method public abstract java.nio.file.Path getPath(String, java.lang.String...);
+    method public abstract java.nio.file.PathMatcher getPathMatcher(String);
+    method public abstract Iterable<java.nio.file.Path> getRootDirectories();
+    method public abstract String getSeparator();
+    method public abstract java.nio.file.attribute.UserPrincipalLookupService getUserPrincipalLookupService();
+    method public abstract boolean isOpen();
+    method public abstract boolean isReadOnly();
+    method public abstract java.nio.file.WatchService newWatchService() throws java.io.IOException;
+    method public abstract java.nio.file.spi.FileSystemProvider provider();
+    method public abstract java.util.Set<java.lang.String> supportedFileAttributeViews();
+  }
+
+  public class FileSystemAlreadyExistsException extends java.lang.RuntimeException {
+    ctor public FileSystemAlreadyExistsException();
+    ctor public FileSystemAlreadyExistsException(String);
+  }
+
+  public class FileSystemException extends java.io.IOException {
+    ctor public FileSystemException(String);
+    ctor public FileSystemException(String, String, String);
+    method public String getFile();
+    method public String getOtherFile();
+    method public String getReason();
+  }
+
+  public class FileSystemLoopException extends java.nio.file.FileSystemException {
+    ctor public FileSystemLoopException(String);
+  }
+
+  public class FileSystemNotFoundException extends java.lang.RuntimeException {
+    ctor public FileSystemNotFoundException();
+    ctor public FileSystemNotFoundException(String);
+  }
+
+  public final class FileSystems {
+    method public static java.nio.file.FileSystem getDefault();
+    method public static java.nio.file.FileSystem getFileSystem(java.net.URI);
+    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>) throws java.io.IOException;
+    method public static java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>, ClassLoader) throws java.io.IOException;
+    method public static java.nio.file.FileSystem newFileSystem(java.nio.file.Path, ClassLoader) throws java.io.IOException;
+  }
+
+  public enum FileVisitOption {
+    enum_constant public static final java.nio.file.FileVisitOption FOLLOW_LINKS;
+  }
+
+  public enum FileVisitResult {
+    enum_constant public static final java.nio.file.FileVisitResult CONTINUE;
+    enum_constant public static final java.nio.file.FileVisitResult SKIP_SIBLINGS;
+    enum_constant public static final java.nio.file.FileVisitResult SKIP_SUBTREE;
+    enum_constant public static final java.nio.file.FileVisitResult TERMINATE;
+  }
+
+  public interface FileVisitor<T> {
+    method public java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
+  }
+
+  public final class Files {
+    method public static java.nio.file.Path copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
+    method public static long copy(java.io.InputStream, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
+    method public static long copy(java.nio.file.Path, java.io.OutputStream) throws java.io.IOException;
+    method public static java.nio.file.Path createDirectories(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createFile(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
+    method public static java.nio.file.Path createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createTempDirectory(java.nio.file.Path, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createTempDirectory(String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createTempFile(java.nio.file.Path, String, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.file.Path createTempFile(String, String, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static void delete(java.nio.file.Path) throws java.io.IOException;
+    method public static boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
+    method public static boolean exists(java.nio.file.Path, java.nio.file.LinkOption...);
+    method public static java.util.stream.Stream<java.nio.file.Path> find(java.nio.file.Path, int, java.util.function.BiPredicate<java.nio.file.Path,java.nio.file.attribute.BasicFileAttributes>, java.nio.file.FileVisitOption...) throws java.io.IOException;
+    method public static Object getAttribute(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(java.nio.file.Path, Class<V>, java.nio.file.LinkOption...);
+    method public static java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
+    method public static java.nio.file.attribute.FileTime getLastModifiedTime(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static java.nio.file.attribute.UserPrincipal getOwner(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> getPosixFilePermissions(java.nio.file.Path, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static boolean isDirectory(java.nio.file.Path, java.nio.file.LinkOption...);
+    method public static boolean isExecutable(java.nio.file.Path);
+    method public static boolean isHidden(java.nio.file.Path) throws java.io.IOException;
+    method public static boolean isReadable(java.nio.file.Path);
+    method public static boolean isRegularFile(java.nio.file.Path, java.nio.file.LinkOption...);
+    method public static boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
+    method public static boolean isSymbolicLink(java.nio.file.Path);
+    method public static boolean isWritable(java.nio.file.Path);
+    method public static java.util.stream.Stream<java.lang.String> lines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
+    method public static java.util.stream.Stream<java.lang.String> lines(java.nio.file.Path) throws java.io.IOException;
+    method public static java.util.stream.Stream<java.nio.file.Path> list(java.nio.file.Path) throws java.io.IOException;
+    method public static java.nio.file.Path move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
+    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
+    method public static java.io.BufferedReader newBufferedReader(java.nio.file.Path) throws java.io.IOException;
+    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.io.BufferedWriter newBufferedWriter(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public static java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path) throws java.io.IOException;
+    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, String) throws java.io.IOException;
+    method public static java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
+    method public static java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static boolean notExists(java.nio.file.Path, java.nio.file.LinkOption...);
+    method public static String probeContentType(java.nio.file.Path) throws java.io.IOException;
+    method public static byte[] readAllBytes(java.nio.file.Path) throws java.io.IOException;
+    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path, java.nio.charset.Charset) throws java.io.IOException;
+    method public static java.util.List<java.lang.String> readAllLines(java.nio.file.Path) throws java.io.IOException;
+    method public static <A extends java.nio.file.attribute.BasicFileAttributes> A readAttributes(java.nio.file.Path, Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static java.util.Map<java.lang.String,java.lang.Object> readAttributes(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
+    method public static java.nio.file.Path setAttribute(java.nio.file.Path, String, Object, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public static java.nio.file.Path setLastModifiedTime(java.nio.file.Path, java.nio.file.attribute.FileTime) throws java.io.IOException;
+    method public static java.nio.file.Path setOwner(java.nio.file.Path, java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
+    method public static java.nio.file.Path setPosixFilePermissions(java.nio.file.Path, java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
+    method public static long size(java.nio.file.Path) throws java.io.IOException;
+    method public static java.util.stream.Stream<java.nio.file.Path> walk(java.nio.file.Path, int, java.nio.file.FileVisitOption...) throws java.io.IOException;
+    method public static java.util.stream.Stream<java.nio.file.Path> walk(java.nio.file.Path, java.nio.file.FileVisitOption...) throws java.io.IOException;
+    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.util.Set<java.nio.file.FileVisitOption>, int, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
+    method public static java.nio.file.Path walkFileTree(java.nio.file.Path, java.nio.file.FileVisitor<? super java.nio.file.Path>) throws java.io.IOException;
+    method public static java.nio.file.Path write(java.nio.file.Path, byte[], java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.nio.file.Path write(java.nio.file.Path, Iterable<? extends java.lang.CharSequence>, java.nio.charset.Charset, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public static java.nio.file.Path write(java.nio.file.Path, Iterable<? extends java.lang.CharSequence>, java.nio.file.OpenOption...) throws java.io.IOException;
+  }
+
+  public class InvalidPathException extends java.lang.IllegalArgumentException {
+    ctor public InvalidPathException(String, String, int);
+    ctor public InvalidPathException(String, String);
+    method public int getIndex();
+    method public String getInput();
+    method public String getReason();
+  }
+
+  public enum LinkOption implements java.nio.file.CopyOption java.nio.file.OpenOption {
+    enum_constant public static final java.nio.file.LinkOption NOFOLLOW_LINKS;
+  }
+
+  public final class LinkPermission extends java.security.BasicPermission {
+    ctor public LinkPermission(String);
+    ctor public LinkPermission(String, String);
+  }
+
+  public class NoSuchFileException extends java.nio.file.FileSystemException {
+    ctor public NoSuchFileException(String);
+    ctor public NoSuchFileException(String, String, String);
+  }
+
+  public class NotDirectoryException extends java.nio.file.FileSystemException {
+    ctor public NotDirectoryException(String);
+  }
+
+  public class NotLinkException extends java.nio.file.FileSystemException {
+    ctor public NotLinkException(String);
+    ctor public NotLinkException(String, String, String);
+  }
+
+  public interface OpenOption {
+  }
+
+  public interface Path extends java.lang.Comparable<java.nio.file.Path> java.lang.Iterable<java.nio.file.Path> java.nio.file.Watchable {
+    method public int compareTo(java.nio.file.Path);
+    method public boolean endsWith(java.nio.file.Path);
+    method public boolean endsWith(String);
+    method public boolean equals(Object);
+    method public java.nio.file.Path getFileName();
+    method public java.nio.file.FileSystem getFileSystem();
+    method public java.nio.file.Path getName(int);
+    method public int getNameCount();
+    method public java.nio.file.Path getParent();
+    method public java.nio.file.Path getRoot();
+    method public int hashCode();
+    method public boolean isAbsolute();
+    method public java.util.Iterator<java.nio.file.Path> iterator();
+    method public java.nio.file.Path normalize();
+    method public java.nio.file.Path relativize(java.nio.file.Path);
+    method public java.nio.file.Path resolve(java.nio.file.Path);
+    method public java.nio.file.Path resolve(String);
+    method public java.nio.file.Path resolveSibling(java.nio.file.Path);
+    method public java.nio.file.Path resolveSibling(String);
+    method public boolean startsWith(java.nio.file.Path);
+    method public boolean startsWith(String);
+    method public java.nio.file.Path subpath(int, int);
+    method public java.nio.file.Path toAbsolutePath();
+    method public java.io.File toFile();
+    method public java.nio.file.Path toRealPath(java.nio.file.LinkOption...) throws java.io.IOException;
+    method public String toString();
+    method public java.net.URI toUri();
+  }
+
+  @java.lang.FunctionalInterface public interface PathMatcher {
+    method public boolean matches(java.nio.file.Path);
+  }
+
+  public final class Paths {
+    method public static java.nio.file.Path get(String, java.lang.String...);
+    method public static java.nio.file.Path get(java.net.URI);
+  }
+
+  public class ProviderMismatchException extends java.lang.IllegalArgumentException {
+    ctor public ProviderMismatchException();
+    ctor public ProviderMismatchException(String);
+  }
+
+  public class ProviderNotFoundException extends java.lang.RuntimeException {
+    ctor public ProviderNotFoundException();
+    ctor public ProviderNotFoundException(String);
+  }
+
+  public class ReadOnlyFileSystemException extends java.lang.UnsupportedOperationException {
+    ctor public ReadOnlyFileSystemException();
+  }
+
+  public interface SecureDirectoryStream<T> extends java.nio.file.DirectoryStream<T> {
+    method public void deleteDirectory(T) throws java.io.IOException;
+    method public void deleteFile(T) throws java.io.IOException;
+    method public <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(Class<V>);
+    method public <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(T, Class<V>, java.nio.file.LinkOption...);
+    method public void move(T, java.nio.file.SecureDirectoryStream<T>, T) throws java.io.IOException;
+    method public java.nio.channels.SeekableByteChannel newByteChannel(T, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public java.nio.file.SecureDirectoryStream<T> newDirectoryStream(T, java.nio.file.LinkOption...) throws java.io.IOException;
+  }
+
+  public class SimpleFileVisitor<T> implements java.nio.file.FileVisitor<T> {
+    ctor protected SimpleFileVisitor();
+    method public java.nio.file.FileVisitResult postVisitDirectory(T, java.io.IOException) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult preVisitDirectory(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult visitFile(T, java.nio.file.attribute.BasicFileAttributes) throws java.io.IOException;
+    method public java.nio.file.FileVisitResult visitFileFailed(T, java.io.IOException) throws java.io.IOException;
+  }
+
+  public enum StandardCopyOption implements java.nio.file.CopyOption {
+    enum_constant public static final java.nio.file.StandardCopyOption ATOMIC_MOVE;
+    enum_constant public static final java.nio.file.StandardCopyOption COPY_ATTRIBUTES;
+    enum_constant public static final java.nio.file.StandardCopyOption REPLACE_EXISTING;
+  }
+
+  public enum StandardOpenOption implements java.nio.file.OpenOption {
+    enum_constant public static final java.nio.file.StandardOpenOption APPEND;
+    enum_constant public static final java.nio.file.StandardOpenOption CREATE;
+    enum_constant public static final java.nio.file.StandardOpenOption CREATE_NEW;
+    enum_constant public static final java.nio.file.StandardOpenOption DELETE_ON_CLOSE;
+    enum_constant public static final java.nio.file.StandardOpenOption DSYNC;
+    enum_constant public static final java.nio.file.StandardOpenOption READ;
+    enum_constant public static final java.nio.file.StandardOpenOption SPARSE;
+    enum_constant public static final java.nio.file.StandardOpenOption SYNC;
+    enum_constant public static final java.nio.file.StandardOpenOption TRUNCATE_EXISTING;
+    enum_constant public static final java.nio.file.StandardOpenOption WRITE;
+  }
+
+  public final class StandardWatchEventKinds {
+    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_CREATE;
+    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_DELETE;
+    field public static final java.nio.file.WatchEvent.Kind<java.nio.file.Path> ENTRY_MODIFY;
+    field public static final java.nio.file.WatchEvent.Kind<java.lang.Object> OVERFLOW;
+  }
+
+  public interface WatchEvent<T> {
+    method public T context();
+    method public int count();
+    method public java.nio.file.WatchEvent.Kind<T> kind();
+  }
+
+  public static interface WatchEvent.Kind<T> {
+    method public String name();
+    method public Class<T> type();
+  }
+
+  public static interface WatchEvent.Modifier {
+    method public String name();
+  }
+
+  public interface WatchKey {
+    method public void cancel();
+    method public boolean isValid();
+    method public java.util.List<java.nio.file.WatchEvent<?>> pollEvents();
+    method public boolean reset();
+    method public java.nio.file.Watchable watchable();
+  }
+
+  public interface WatchService extends java.io.Closeable {
+    method public java.nio.file.WatchKey poll();
+    method public java.nio.file.WatchKey poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public java.nio.file.WatchKey take() throws java.lang.InterruptedException;
+  }
+
+  public interface Watchable {
+    method public java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>[], java.nio.file.WatchEvent.Modifier...) throws java.io.IOException;
+    method public java.nio.file.WatchKey register(java.nio.file.WatchService, java.nio.file.WatchEvent.Kind<?>...) throws java.io.IOException;
+  }
+
+}
+
+package java.nio.file.attribute {
+
+  public final class AclEntry {
+    method public java.util.Set<java.nio.file.attribute.AclEntryFlag> flags();
+    method public static java.nio.file.attribute.AclEntry.Builder newBuilder();
+    method public static java.nio.file.attribute.AclEntry.Builder newBuilder(java.nio.file.attribute.AclEntry);
+    method public java.util.Set<java.nio.file.attribute.AclEntryPermission> permissions();
+    method public java.nio.file.attribute.UserPrincipal principal();
+    method public java.nio.file.attribute.AclEntryType type();
+  }
+
+  public static final class AclEntry.Builder {
+    method public java.nio.file.attribute.AclEntry build();
+    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.util.Set<java.nio.file.attribute.AclEntryFlag>);
+    method public java.nio.file.attribute.AclEntry.Builder setFlags(java.nio.file.attribute.AclEntryFlag...);
+    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.util.Set<java.nio.file.attribute.AclEntryPermission>);
+    method public java.nio.file.attribute.AclEntry.Builder setPermissions(java.nio.file.attribute.AclEntryPermission...);
+    method public java.nio.file.attribute.AclEntry.Builder setPrincipal(java.nio.file.attribute.UserPrincipal);
+    method public java.nio.file.attribute.AclEntry.Builder setType(java.nio.file.attribute.AclEntryType);
+  }
+
+  public enum AclEntryFlag {
+    enum_constant public static final java.nio.file.attribute.AclEntryFlag DIRECTORY_INHERIT;
+    enum_constant public static final java.nio.file.attribute.AclEntryFlag FILE_INHERIT;
+    enum_constant public static final java.nio.file.attribute.AclEntryFlag INHERIT_ONLY;
+    enum_constant public static final java.nio.file.attribute.AclEntryFlag NO_PROPAGATE_INHERIT;
+  }
+
+  public enum AclEntryPermission {
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission APPEND_DATA;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission DELETE_CHILD;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission EXECUTE;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ACL;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_ATTRIBUTES;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_DATA;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission READ_NAMED_ATTRS;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission SYNCHRONIZE;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ACL;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_ATTRIBUTES;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_DATA;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_NAMED_ATTRS;
+    enum_constant public static final java.nio.file.attribute.AclEntryPermission WRITE_OWNER;
+    field public static final java.nio.file.attribute.AclEntryPermission ADD_FILE;
+    field public static final java.nio.file.attribute.AclEntryPermission ADD_SUBDIRECTORY;
+    field public static final java.nio.file.attribute.AclEntryPermission LIST_DIRECTORY;
+  }
+
+  public enum AclEntryType {
+    enum_constant public static final java.nio.file.attribute.AclEntryType ALARM;
+    enum_constant public static final java.nio.file.attribute.AclEntryType ALLOW;
+    enum_constant public static final java.nio.file.attribute.AclEntryType AUDIT;
+    enum_constant public static final java.nio.file.attribute.AclEntryType DENY;
+  }
+
+  public interface AclFileAttributeView extends java.nio.file.attribute.FileOwnerAttributeView {
+    method public java.util.List<java.nio.file.attribute.AclEntry> getAcl() throws java.io.IOException;
+    method public void setAcl(java.util.List<java.nio.file.attribute.AclEntry>) throws java.io.IOException;
+  }
+
+  public interface AttributeView {
+    method public String name();
+  }
+
+  public interface BasicFileAttributeView extends java.nio.file.attribute.FileAttributeView {
+    method public java.nio.file.attribute.BasicFileAttributes readAttributes() throws java.io.IOException;
+    method public void setTimes(java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime, java.nio.file.attribute.FileTime) throws java.io.IOException;
+  }
+
+  public interface BasicFileAttributes {
+    method public java.nio.file.attribute.FileTime creationTime();
+    method public Object fileKey();
+    method public boolean isDirectory();
+    method public boolean isOther();
+    method public boolean isRegularFile();
+    method public boolean isSymbolicLink();
+    method public java.nio.file.attribute.FileTime lastAccessTime();
+    method public java.nio.file.attribute.FileTime lastModifiedTime();
+    method public long size();
+  }
+
+  public interface DosFileAttributeView extends java.nio.file.attribute.BasicFileAttributeView {
+    method public java.nio.file.attribute.DosFileAttributes readAttributes() throws java.io.IOException;
+    method public void setArchive(boolean) throws java.io.IOException;
+    method public void setHidden(boolean) throws java.io.IOException;
+    method public void setReadOnly(boolean) throws java.io.IOException;
+    method public void setSystem(boolean) throws java.io.IOException;
+  }
+
+  public interface DosFileAttributes extends java.nio.file.attribute.BasicFileAttributes {
+    method public boolean isArchive();
+    method public boolean isHidden();
+    method public boolean isReadOnly();
+    method public boolean isSystem();
+  }
+
+  public interface FileAttribute<T> {
+    method public String name();
+    method public T value();
+  }
+
+  public interface FileAttributeView extends java.nio.file.attribute.AttributeView {
+  }
+
+  public interface FileOwnerAttributeView extends java.nio.file.attribute.FileAttributeView {
+    method public java.nio.file.attribute.UserPrincipal getOwner() throws java.io.IOException;
+    method public void setOwner(java.nio.file.attribute.UserPrincipal) throws java.io.IOException;
+  }
+
+  public interface FileStoreAttributeView extends java.nio.file.attribute.AttributeView {
+  }
+
+  public final class FileTime implements java.lang.Comparable<java.nio.file.attribute.FileTime> {
+    method public int compareTo(java.nio.file.attribute.FileTime);
+    method public static java.nio.file.attribute.FileTime from(long, java.util.concurrent.TimeUnit);
+    method public static java.nio.file.attribute.FileTime from(java.time.Instant);
+    method public static java.nio.file.attribute.FileTime fromMillis(long);
+    method public long to(java.util.concurrent.TimeUnit);
+    method public java.time.Instant toInstant();
+    method public long toMillis();
+  }
+
+  public interface GroupPrincipal extends java.nio.file.attribute.UserPrincipal {
+  }
+
+  public interface PosixFileAttributeView extends java.nio.file.attribute.BasicFileAttributeView java.nio.file.attribute.FileOwnerAttributeView {
+    method public java.nio.file.attribute.PosixFileAttributes readAttributes() throws java.io.IOException;
+    method public void setGroup(java.nio.file.attribute.GroupPrincipal) throws java.io.IOException;
+    method public void setPermissions(java.util.Set<java.nio.file.attribute.PosixFilePermission>) throws java.io.IOException;
+  }
+
+  public interface PosixFileAttributes extends java.nio.file.attribute.BasicFileAttributes {
+    method public java.nio.file.attribute.GroupPrincipal group();
+    method public java.nio.file.attribute.UserPrincipal owner();
+    method public java.util.Set<java.nio.file.attribute.PosixFilePermission> permissions();
+  }
+
+  public enum PosixFilePermission {
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_EXECUTE;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_READ;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission GROUP_WRITE;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_EXECUTE;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_READ;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OTHERS_WRITE;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_EXECUTE;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_READ;
+    enum_constant public static final java.nio.file.attribute.PosixFilePermission OWNER_WRITE;
+  }
+
+  public final class PosixFilePermissions {
+    method public static java.nio.file.attribute.FileAttribute<java.util.Set<java.nio.file.attribute.PosixFilePermission>> asFileAttribute(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
+    method public static java.util.Set<java.nio.file.attribute.PosixFilePermission> fromString(String);
+    method public static String toString(java.util.Set<java.nio.file.attribute.PosixFilePermission>);
+  }
+
+  public interface UserDefinedFileAttributeView extends java.nio.file.attribute.FileAttributeView {
+    method public void delete(String) throws java.io.IOException;
+    method public java.util.List<java.lang.String> list() throws java.io.IOException;
+    method public int read(String, java.nio.ByteBuffer) throws java.io.IOException;
+    method public int size(String) throws java.io.IOException;
+    method public int write(String, java.nio.ByteBuffer) throws java.io.IOException;
+  }
+
+  public interface UserPrincipal extends java.security.Principal {
+  }
+
+  public abstract class UserPrincipalLookupService {
+    ctor protected UserPrincipalLookupService();
+    method public abstract java.nio.file.attribute.GroupPrincipal lookupPrincipalByGroupName(String) throws java.io.IOException;
+    method public abstract java.nio.file.attribute.UserPrincipal lookupPrincipalByName(String) throws java.io.IOException;
+  }
+
+  public class UserPrincipalNotFoundException extends java.io.IOException {
+    ctor public UserPrincipalNotFoundException(String);
+    method public String getName();
+  }
+
+}
+
+package java.nio.file.spi {
+
+  public abstract class FileSystemProvider {
+    ctor protected FileSystemProvider();
+    method public abstract void checkAccess(java.nio.file.Path, java.nio.file.AccessMode...) throws java.io.IOException;
+    method public abstract void copy(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
+    method public abstract void createDirectory(java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public void createLink(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
+    method public void createSymbolicLink(java.nio.file.Path, java.nio.file.Path, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public abstract void delete(java.nio.file.Path) throws java.io.IOException;
+    method public boolean deleteIfExists(java.nio.file.Path) throws java.io.IOException;
+    method public abstract <V extends java.nio.file.attribute.FileAttributeView> V getFileAttributeView(java.nio.file.Path, Class<V>, java.nio.file.LinkOption...);
+    method public abstract java.nio.file.FileStore getFileStore(java.nio.file.Path) throws java.io.IOException;
+    method public abstract java.nio.file.FileSystem getFileSystem(java.net.URI);
+    method public abstract java.nio.file.Path getPath(java.net.URI);
+    method public abstract String getScheme();
+    method public static java.util.List<java.nio.file.spi.FileSystemProvider> installedProviders();
+    method public abstract boolean isHidden(java.nio.file.Path) throws java.io.IOException;
+    method public abstract boolean isSameFile(java.nio.file.Path, java.nio.file.Path) throws java.io.IOException;
+    method public abstract void move(java.nio.file.Path, java.nio.file.Path, java.nio.file.CopyOption...) throws java.io.IOException;
+    method public java.nio.channels.AsynchronousFileChannel newAsynchronousFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.util.concurrent.ExecutorService, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public abstract java.nio.channels.SeekableByteChannel newByteChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public abstract java.nio.file.DirectoryStream<java.nio.file.Path> newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter<? super java.nio.file.Path>) throws java.io.IOException;
+    method public java.nio.channels.FileChannel newFileChannel(java.nio.file.Path, java.util.Set<? extends java.nio.file.OpenOption>, java.nio.file.attribute.FileAttribute<?>...) throws java.io.IOException;
+    method public abstract java.nio.file.FileSystem newFileSystem(java.net.URI, java.util.Map<java.lang.String,?>) throws java.io.IOException;
+    method public java.nio.file.FileSystem newFileSystem(java.nio.file.Path, java.util.Map<java.lang.String,?>) throws java.io.IOException;
+    method public java.io.InputStream newInputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public java.io.OutputStream newOutputStream(java.nio.file.Path, java.nio.file.OpenOption...) throws java.io.IOException;
+    method public abstract <A extends java.nio.file.attribute.BasicFileAttributes> A readAttributes(java.nio.file.Path, Class<A>, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public abstract java.util.Map<java.lang.String,java.lang.Object> readAttributes(java.nio.file.Path, String, java.nio.file.LinkOption...) throws java.io.IOException;
+    method public java.nio.file.Path readSymbolicLink(java.nio.file.Path) throws java.io.IOException;
+    method public abstract void setAttribute(java.nio.file.Path, String, Object, java.nio.file.LinkOption...) throws java.io.IOException;
+  }
+
+  public abstract class FileTypeDetector {
+    ctor protected FileTypeDetector();
+    method public abstract String probeContentType(java.nio.file.Path) throws java.io.IOException;
+  }
+
+}
+
+package java.security {
+
+  public final class AccessControlContext {
+    ctor public AccessControlContext(java.security.ProtectionDomain[]);
+    ctor public AccessControlContext(java.security.AccessControlContext, java.security.DomainCombiner);
+    method public void checkPermission(java.security.Permission) throws java.security.AccessControlException;
+    method public java.security.DomainCombiner getDomainCombiner();
+  }
+
+  public class AccessControlException extends java.lang.SecurityException {
+    ctor public AccessControlException(String);
+    ctor public AccessControlException(String, java.security.Permission);
+    method public java.security.Permission getPermission();
+  }
+
+  public final class AccessController {
+    method public static void checkPermission(java.security.Permission) throws java.security.AccessControlException;
+    method public static <T> T doPrivileged(java.security.PrivilegedAction<T>);
+    method public static <T> T doPrivileged(java.security.PrivilegedAction<T>, java.security.AccessControlContext);
+    method public static <T> T doPrivileged(java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
+    method public static <T> T doPrivileged(java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) throws java.security.PrivilegedActionException;
+    method public static <T> T doPrivilegedWithCombiner(java.security.PrivilegedAction<T>);
+    method public static <T> T doPrivilegedWithCombiner(java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
+    method public static java.security.AccessControlContext getContext();
+  }
+
+  public interface AlgorithmConstraints {
+    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, String, java.security.AlgorithmParameters);
+    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, java.security.Key);
+    method public boolean permits(java.util.Set<java.security.CryptoPrimitive>, String, java.security.Key, java.security.AlgorithmParameters);
+  }
+
+  public class AlgorithmParameterGenerator {
+    ctor protected AlgorithmParameterGenerator(java.security.AlgorithmParameterGeneratorSpi, java.security.Provider, String);
+    method public final java.security.AlgorithmParameters generateParameters();
+    method public final String getAlgorithm();
+    method public static java.security.AlgorithmParameterGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.AlgorithmParameterGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.AlgorithmParameterGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final void init(int);
+    method public final void init(int, java.security.SecureRandom);
+    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
+    method public final void init(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public abstract class AlgorithmParameterGeneratorSpi {
+    ctor public AlgorithmParameterGeneratorSpi();
+    method protected abstract java.security.AlgorithmParameters engineGenerateParameters();
+    method protected abstract void engineInit(int, java.security.SecureRandom);
+    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public class AlgorithmParameters {
+    ctor protected AlgorithmParameters(java.security.AlgorithmParametersSpi, java.security.Provider, String);
+    method public final String getAlgorithm();
+    method public final byte[] getEncoded() throws java.io.IOException;
+    method public final byte[] getEncoded(String) throws java.io.IOException;
+    method public static java.security.AlgorithmParameters getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.AlgorithmParameters getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.AlgorithmParameters getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final <T extends java.security.spec.AlgorithmParameterSpec> T getParameterSpec(Class<T>) throws java.security.spec.InvalidParameterSpecException;
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.spec.InvalidParameterSpecException;
+    method public final void init(byte[]) throws java.io.IOException;
+    method public final void init(byte[], String) throws java.io.IOException;
+    method public final String toString();
+  }
+
+  public abstract class AlgorithmParametersSpi {
+    ctor public AlgorithmParametersSpi();
+    method protected abstract byte[] engineGetEncoded() throws java.io.IOException;
+    method protected abstract byte[] engineGetEncoded(String) throws java.io.IOException;
+    method protected abstract <T extends java.security.spec.AlgorithmParameterSpec> T engineGetParameterSpec(Class<T>) throws java.security.spec.InvalidParameterSpecException;
+    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec) throws java.security.spec.InvalidParameterSpecException;
+    method protected abstract void engineInit(byte[]) throws java.io.IOException;
+    method protected abstract void engineInit(byte[], String) throws java.io.IOException;
+    method protected abstract String engineToString();
+  }
+
+  public final class AllPermission extends java.security.Permission {
+    ctor public AllPermission();
+    ctor public AllPermission(String, String);
+    method public String getActions();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public abstract class AuthProvider extends java.security.Provider {
+    ctor protected AuthProvider(String, double, String);
+    method public abstract void login(javax.security.auth.Subject, javax.security.auth.callback.CallbackHandler) throws javax.security.auth.login.LoginException;
+    method public abstract void logout() throws javax.security.auth.login.LoginException;
+    method public abstract void setCallbackHandler(javax.security.auth.callback.CallbackHandler);
+  }
+
+  public abstract class BasicPermission extends java.security.Permission implements java.io.Serializable {
+    ctor public BasicPermission(String);
+    ctor public BasicPermission(String, String);
+    method public String getActions();
+    method public boolean implies(java.security.Permission);
+  }
+
+  @Deprecated public interface Certificate {
+    method @Deprecated public void decode(java.io.InputStream) throws java.io.IOException, java.security.KeyException;
+    method @Deprecated public void encode(java.io.OutputStream) throws java.io.IOException, java.security.KeyException;
+    method @Deprecated public String getFormat();
+    method @Deprecated public java.security.Principal getGuarantor();
+    method @Deprecated public java.security.Principal getPrincipal();
+    method @Deprecated public java.security.PublicKey getPublicKey();
+    method @Deprecated public String toString(boolean);
+  }
+
+  public final class CodeSigner implements java.io.Serializable {
+    ctor public CodeSigner(java.security.cert.CertPath, java.security.Timestamp);
+    method public java.security.cert.CertPath getSignerCertPath();
+    method public java.security.Timestamp getTimestamp();
+  }
+
+  public class CodeSource implements java.io.Serializable {
+    ctor public CodeSource(java.net.URL, java.security.cert.Certificate[]);
+    ctor public CodeSource(java.net.URL, java.security.CodeSigner[]);
+    method public final java.security.cert.Certificate[] getCertificates();
+    method public final java.security.CodeSigner[] getCodeSigners();
+    method public final java.net.URL getLocation();
+    method public boolean implies(java.security.CodeSource);
+  }
+
+  public enum CryptoPrimitive {
+    enum_constant public static final java.security.CryptoPrimitive BLOCK_CIPHER;
+    enum_constant public static final java.security.CryptoPrimitive KEY_AGREEMENT;
+    enum_constant public static final java.security.CryptoPrimitive KEY_ENCAPSULATION;
+    enum_constant public static final java.security.CryptoPrimitive KEY_WRAP;
+    enum_constant public static final java.security.CryptoPrimitive MAC;
+    enum_constant public static final java.security.CryptoPrimitive MESSAGE_DIGEST;
+    enum_constant public static final java.security.CryptoPrimitive PUBLIC_KEY_ENCRYPTION;
+    enum_constant public static final java.security.CryptoPrimitive SECURE_RANDOM;
+    enum_constant public static final java.security.CryptoPrimitive SIGNATURE;
+    enum_constant public static final java.security.CryptoPrimitive STREAM_CIPHER;
+  }
+
+  public class DigestException extends java.security.GeneralSecurityException {
+    ctor public DigestException();
+    ctor public DigestException(String);
+    ctor public DigestException(String, Throwable);
+    ctor public DigestException(Throwable);
+  }
+
+  public class DigestInputStream extends java.io.FilterInputStream {
+    ctor public DigestInputStream(java.io.InputStream, java.security.MessageDigest);
+    method public java.security.MessageDigest getMessageDigest();
+    method public void on(boolean);
+    method public void setMessageDigest(java.security.MessageDigest);
+    field protected java.security.MessageDigest digest;
+  }
+
+  public class DigestOutputStream extends java.io.FilterOutputStream {
+    ctor public DigestOutputStream(java.io.OutputStream, java.security.MessageDigest);
+    method public java.security.MessageDigest getMessageDigest();
+    method public void on(boolean);
+    method public void setMessageDigest(java.security.MessageDigest);
+    field protected java.security.MessageDigest digest;
+  }
+
+  public interface DomainCombiner {
+    method public java.security.ProtectionDomain[] combine(java.security.ProtectionDomain[], java.security.ProtectionDomain[]);
+  }
+
+  public final class DomainLoadStoreParameter implements java.security.KeyStore.LoadStoreParameter {
+    ctor public DomainLoadStoreParameter(java.net.URI, java.util.Map<java.lang.String,java.security.KeyStore.ProtectionParameter>);
+    method public java.net.URI getConfiguration();
+    method public java.security.KeyStore.ProtectionParameter getProtectionParameter();
+    method public java.util.Map<java.lang.String,java.security.KeyStore.ProtectionParameter> getProtectionParams();
+  }
+
+  public class GeneralSecurityException extends java.lang.Exception {
+    ctor public GeneralSecurityException();
+    ctor public GeneralSecurityException(String);
+    ctor public GeneralSecurityException(String, Throwable);
+    ctor public GeneralSecurityException(Throwable);
+  }
+
+  public interface Guard {
+    method public void checkGuard(Object) throws java.lang.SecurityException;
+  }
+
+  public class GuardedObject implements java.io.Serializable {
+    ctor public GuardedObject(Object, java.security.Guard);
+    method public Object getObject() throws java.lang.SecurityException;
+  }
+
+  @Deprecated public abstract class Identity implements java.security.Principal java.io.Serializable {
+    ctor @Deprecated protected Identity();
+    ctor @Deprecated public Identity(String, java.security.IdentityScope) throws java.security.KeyManagementException;
+    ctor @Deprecated public Identity(String);
+    method @Deprecated public void addCertificate(java.security.Certificate) throws java.security.KeyManagementException;
+    method @Deprecated public java.security.Certificate[] certificates();
+    method @Deprecated public final boolean equals(Object);
+    method @Deprecated public String getInfo();
+    method @Deprecated public final String getName();
+    method @Deprecated public java.security.PublicKey getPublicKey();
+    method @Deprecated public final java.security.IdentityScope getScope();
+    method @Deprecated protected boolean identityEquals(java.security.Identity);
+    method @Deprecated public void removeCertificate(java.security.Certificate) throws java.security.KeyManagementException;
+    method @Deprecated public void setInfo(String);
+    method @Deprecated public void setPublicKey(java.security.PublicKey) throws java.security.KeyManagementException;
+    method @Deprecated public String toString(boolean);
+  }
+
+  @Deprecated public abstract class IdentityScope extends java.security.Identity {
+    ctor @Deprecated protected IdentityScope();
+    ctor @Deprecated public IdentityScope(String);
+    ctor @Deprecated public IdentityScope(String, java.security.IdentityScope) throws java.security.KeyManagementException;
+    method @Deprecated public abstract void addIdentity(java.security.Identity) throws java.security.KeyManagementException;
+    method @Deprecated public abstract java.security.Identity getIdentity(String);
+    method @Deprecated public java.security.Identity getIdentity(java.security.Principal);
+    method @Deprecated public abstract java.security.Identity getIdentity(java.security.PublicKey);
+    method @Deprecated public static java.security.IdentityScope getSystemScope();
+    method @Deprecated public abstract java.util.Enumeration<java.security.Identity> identities();
+    method @Deprecated public abstract void removeIdentity(java.security.Identity) throws java.security.KeyManagementException;
+    method @Deprecated protected static void setSystemScope(java.security.IdentityScope);
+    method @Deprecated public abstract int size();
+  }
+
+  public class InvalidAlgorithmParameterException extends java.security.GeneralSecurityException {
+    ctor public InvalidAlgorithmParameterException();
+    ctor public InvalidAlgorithmParameterException(String);
+    ctor public InvalidAlgorithmParameterException(String, Throwable);
+    ctor public InvalidAlgorithmParameterException(Throwable);
+  }
+
+  public class InvalidKeyException extends java.security.KeyException {
+    ctor public InvalidKeyException();
+    ctor public InvalidKeyException(String);
+    ctor public InvalidKeyException(String, Throwable);
+    ctor public InvalidKeyException(Throwable);
+  }
+
+  public class InvalidParameterException extends java.lang.IllegalArgumentException {
+    ctor public InvalidParameterException();
+    ctor public InvalidParameterException(String);
+  }
+
+  public interface Key extends java.io.Serializable {
+    method public String getAlgorithm();
+    method public byte[] getEncoded();
+    method public String getFormat();
+    field public static final long serialVersionUID = 6603384152749567654L; // 0x5ba3eee69414eea6L
+  }
+
+  public class KeyException extends java.security.GeneralSecurityException {
+    ctor public KeyException();
+    ctor public KeyException(String);
+    ctor public KeyException(String, Throwable);
+    ctor public KeyException(Throwable);
+  }
+
+  public class KeyFactory {
+    ctor protected KeyFactory(java.security.KeyFactorySpi, java.security.Provider, String);
+    method public final java.security.PrivateKey generatePrivate(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method public final java.security.PublicKey generatePublic(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method public final String getAlgorithm();
+    method public static java.security.KeyFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.KeyFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.KeyFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final <T extends java.security.spec.KeySpec> T getKeySpec(java.security.Key, Class<T>) throws java.security.spec.InvalidKeySpecException;
+    method public final java.security.Provider getProvider();
+    method public final java.security.Key translateKey(java.security.Key) throws java.security.InvalidKeyException;
+  }
+
+  public abstract class KeyFactorySpi {
+    ctor public KeyFactorySpi();
+    method protected abstract java.security.PrivateKey engineGeneratePrivate(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method protected abstract java.security.PublicKey engineGeneratePublic(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method protected abstract <T extends java.security.spec.KeySpec> T engineGetKeySpec(java.security.Key, Class<T>) throws java.security.spec.InvalidKeySpecException;
+    method protected abstract java.security.Key engineTranslateKey(java.security.Key) throws java.security.InvalidKeyException;
+  }
+
+  public class KeyManagementException extends java.security.KeyException {
+    ctor public KeyManagementException();
+    ctor public KeyManagementException(String);
+    ctor public KeyManagementException(String, Throwable);
+    ctor public KeyManagementException(Throwable);
+  }
+
+  public final class KeyPair implements java.io.Serializable {
+    ctor public KeyPair(java.security.PublicKey, java.security.PrivateKey);
+    method public java.security.PrivateKey getPrivate();
+    method public java.security.PublicKey getPublic();
+  }
+
+  public abstract class KeyPairGenerator extends java.security.KeyPairGeneratorSpi {
+    ctor protected KeyPairGenerator(String);
+    method public final java.security.KeyPair genKeyPair();
+    method public java.security.KeyPair generateKeyPair();
+    method public String getAlgorithm();
+    method public static java.security.KeyPairGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.KeyPairGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.KeyPairGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public void initialize(int);
+    method public void initialize(int, java.security.SecureRandom);
+    method public void initialize(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public abstract class KeyPairGeneratorSpi {
+    ctor public KeyPairGeneratorSpi();
+    method public abstract java.security.KeyPair generateKeyPair();
+    method public abstract void initialize(int, java.security.SecureRandom);
+    method public void initialize(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public class KeyRep implements java.io.Serializable {
+    ctor public KeyRep(java.security.KeyRep.Type, String, String, byte[]);
+    method protected Object readResolve() throws java.io.ObjectStreamException;
+  }
+
+  public enum KeyRep.Type {
+    enum_constant public static final java.security.KeyRep.Type PRIVATE;
+    enum_constant public static final java.security.KeyRep.Type PUBLIC;
+    enum_constant public static final java.security.KeyRep.Type SECRET;
+  }
+
+  public class KeyStore {
+    ctor protected KeyStore(java.security.KeyStoreSpi, java.security.Provider, String);
+    method public final java.util.Enumeration<java.lang.String> aliases() throws java.security.KeyStoreException;
+    method public final boolean containsAlias(String) throws java.security.KeyStoreException;
+    method public final void deleteEntry(String) throws java.security.KeyStoreException;
+    method public final boolean entryInstanceOf(String, Class<? extends java.security.KeyStore.Entry>) throws java.security.KeyStoreException;
+    method public final java.security.cert.Certificate getCertificate(String) throws java.security.KeyStoreException;
+    method public final String getCertificateAlias(java.security.cert.Certificate) throws java.security.KeyStoreException;
+    method public final java.security.cert.Certificate[] getCertificateChain(String) throws java.security.KeyStoreException;
+    method public final java.util.Date getCreationDate(String) throws java.security.KeyStoreException;
+    method public static final String getDefaultType();
+    method public final java.security.KeyStore.Entry getEntry(String, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableEntryException;
+    method public static java.security.KeyStore getInstance(String) throws java.security.KeyStoreException;
+    method public static java.security.KeyStore getInstance(String, String) throws java.security.KeyStoreException, java.security.NoSuchProviderException;
+    method public static java.security.KeyStore getInstance(String, java.security.Provider) throws java.security.KeyStoreException;
+    method public final java.security.Key getKey(String, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
+    method public final java.security.Provider getProvider();
+    method public final String getType();
+    method public final boolean isCertificateEntry(String) throws java.security.KeyStoreException;
+    method public final boolean isKeyEntry(String) throws java.security.KeyStoreException;
+    method public final void load(java.io.InputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+    method public final void load(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+    method public final void setCertificateEntry(String, java.security.cert.Certificate) throws java.security.KeyStoreException;
+    method public final void setEntry(String, java.security.KeyStore.Entry, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException;
+    method public final void setKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
+    method public final void setKeyEntry(String, byte[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
+    method public final int size() throws java.security.KeyStoreException;
+    method public final void store(java.io.OutputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException;
+    method public final void store(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException;
+  }
+
+  public abstract static class KeyStore.Builder {
+    ctor protected KeyStore.Builder();
+    method public abstract java.security.KeyStore getKeyStore() throws java.security.KeyStoreException;
+    method public abstract java.security.KeyStore.ProtectionParameter getProtectionParameter(String) throws java.security.KeyStoreException;
+    method public static java.security.KeyStore.Builder newInstance(java.security.KeyStore, java.security.KeyStore.ProtectionParameter);
+    method public static java.security.KeyStore.Builder newInstance(String, java.security.Provider, java.io.File, java.security.KeyStore.ProtectionParameter);
+    method public static java.security.KeyStore.Builder newInstance(String, java.security.Provider, java.security.KeyStore.ProtectionParameter);
+  }
+
+  public static class KeyStore.CallbackHandlerProtection implements java.security.KeyStore.ProtectionParameter {
+    ctor public KeyStore.CallbackHandlerProtection(javax.security.auth.callback.CallbackHandler);
+    method public javax.security.auth.callback.CallbackHandler getCallbackHandler();
+  }
+
+  public static interface KeyStore.Entry {
+    method public default java.util.Set<java.security.KeyStore.Entry.Attribute> getAttributes();
+  }
+
+  public static interface KeyStore.Entry.Attribute {
+    method public String getName();
+    method public String getValue();
+  }
+
+  public static interface KeyStore.LoadStoreParameter {
+    method public java.security.KeyStore.ProtectionParameter getProtectionParameter();
+  }
+
+  public static class KeyStore.PasswordProtection implements javax.security.auth.Destroyable java.security.KeyStore.ProtectionParameter {
+    ctor public KeyStore.PasswordProtection(char[]);
+    ctor public KeyStore.PasswordProtection(char[], String, java.security.spec.AlgorithmParameterSpec);
+    method public char[] getPassword();
+    method public String getProtectionAlgorithm();
+    method public java.security.spec.AlgorithmParameterSpec getProtectionParameters();
+  }
+
+  public static final class KeyStore.PrivateKeyEntry implements java.security.KeyStore.Entry {
+    ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[]);
+    ctor public KeyStore.PrivateKeyEntry(java.security.PrivateKey, java.security.cert.Certificate[], java.util.Set<java.security.KeyStore.Entry.Attribute>);
+    method public java.security.cert.Certificate getCertificate();
+    method public java.security.cert.Certificate[] getCertificateChain();
+    method public java.security.PrivateKey getPrivateKey();
+  }
+
+  public static interface KeyStore.ProtectionParameter {
+  }
+
+  public static final class KeyStore.SecretKeyEntry implements java.security.KeyStore.Entry {
+    ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey);
+    ctor public KeyStore.SecretKeyEntry(javax.crypto.SecretKey, java.util.Set<java.security.KeyStore.Entry.Attribute>);
+    method public javax.crypto.SecretKey getSecretKey();
+  }
+
+  public static final class KeyStore.TrustedCertificateEntry implements java.security.KeyStore.Entry {
+    ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate);
+    ctor public KeyStore.TrustedCertificateEntry(java.security.cert.Certificate, java.util.Set<java.security.KeyStore.Entry.Attribute>);
+    method public java.security.cert.Certificate getTrustedCertificate();
+  }
+
+  public class KeyStoreException extends java.security.GeneralSecurityException {
+    ctor public KeyStoreException();
+    ctor public KeyStoreException(String);
+    ctor public KeyStoreException(String, Throwable);
+    ctor public KeyStoreException(Throwable);
+  }
+
+  public abstract class KeyStoreSpi {
+    ctor public KeyStoreSpi();
+    method public abstract java.util.Enumeration<java.lang.String> engineAliases();
+    method public abstract boolean engineContainsAlias(String);
+    method public abstract void engineDeleteEntry(String) throws java.security.KeyStoreException;
+    method public boolean engineEntryInstanceOf(String, Class<? extends java.security.KeyStore.Entry>);
+    method public abstract java.security.cert.Certificate engineGetCertificate(String);
+    method public abstract String engineGetCertificateAlias(java.security.cert.Certificate);
+    method public abstract java.security.cert.Certificate[] engineGetCertificateChain(String);
+    method public abstract java.util.Date engineGetCreationDate(String);
+    method public java.security.KeyStore.Entry engineGetEntry(String, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableEntryException;
+    method public abstract java.security.Key engineGetKey(String, char[]) throws java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
+    method public abstract boolean engineIsCertificateEntry(String);
+    method public abstract boolean engineIsKeyEntry(String);
+    method public abstract void engineLoad(java.io.InputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+    method public void engineLoad(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+    method public abstract void engineSetCertificateEntry(String, java.security.cert.Certificate) throws java.security.KeyStoreException;
+    method public void engineSetEntry(String, java.security.KeyStore.Entry, java.security.KeyStore.ProtectionParameter) throws java.security.KeyStoreException;
+    method public abstract void engineSetKeyEntry(String, java.security.Key, char[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
+    method public abstract void engineSetKeyEntry(String, byte[], java.security.cert.Certificate[]) throws java.security.KeyStoreException;
+    method public abstract int engineSize();
+    method public abstract void engineStore(java.io.OutputStream, char[]) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+    method public void engineStore(java.security.KeyStore.LoadStoreParameter) throws java.security.cert.CertificateException, java.io.IOException, java.security.NoSuchAlgorithmException;
+  }
+
+  public abstract class MessageDigest extends java.security.MessageDigestSpi {
+    ctor protected MessageDigest(@NonNull String);
+    method @NonNull public byte[] digest();
+    method public int digest(@NonNull byte[], int, int) throws java.security.DigestException;
+    method @NonNull public byte[] digest(@NonNull byte[]);
+    method @NonNull public final String getAlgorithm();
+    method public final int getDigestLength();
+    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String) throws java.security.NoSuchAlgorithmException;
+    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method @NonNull public static java.security.MessageDigest getInstance(@NonNull String, @NonNull java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method @NonNull public final java.security.Provider getProvider();
+    method public static boolean isEqual(@Nullable byte[], @Nullable byte[]);
+    method public void reset();
+    method public void update(byte);
+    method public void update(@NonNull byte[], int, int);
+    method public void update(@NonNull byte[]);
+    method public final void update(@NonNull java.nio.ByteBuffer);
+  }
+
+  public abstract class MessageDigestSpi {
+    ctor public MessageDigestSpi();
+    method public Object clone() throws java.lang.CloneNotSupportedException;
+    method protected abstract byte[] engineDigest();
+    method protected int engineDigest(byte[], int, int) throws java.security.DigestException;
+    method protected int engineGetDigestLength();
+    method protected abstract void engineReset();
+    method protected abstract void engineUpdate(byte);
+    method protected abstract void engineUpdate(byte[], int, int);
+    method protected void engineUpdate(java.nio.ByteBuffer);
+  }
+
+  public class NoSuchAlgorithmException extends java.security.GeneralSecurityException {
+    ctor public NoSuchAlgorithmException();
+    ctor public NoSuchAlgorithmException(String);
+    ctor public NoSuchAlgorithmException(String, Throwable);
+    ctor public NoSuchAlgorithmException(Throwable);
+  }
+
+  public class NoSuchProviderException extends java.security.GeneralSecurityException {
+    ctor public NoSuchProviderException();
+    ctor public NoSuchProviderException(String);
+  }
+
+  public final class PKCS12Attribute implements java.security.KeyStore.Entry.Attribute {
+    ctor public PKCS12Attribute(String, String);
+    ctor public PKCS12Attribute(byte[]);
+    method public byte[] getEncoded();
+    method public String getName();
+    method public String getValue();
+  }
+
+  public abstract class Permission implements java.security.Guard java.io.Serializable {
+    ctor public Permission(String);
+    method public void checkGuard(Object) throws java.lang.SecurityException;
+    method public abstract String getActions();
+    method public final String getName();
+    method public abstract boolean implies(java.security.Permission);
+    method public java.security.PermissionCollection newPermissionCollection();
+  }
+
+  public abstract class PermissionCollection implements java.io.Serializable {
+    ctor public PermissionCollection();
+    method public abstract void add(java.security.Permission);
+    method public abstract java.util.Enumeration<java.security.Permission> elements();
+    method public abstract boolean implies(java.security.Permission);
+    method public boolean isReadOnly();
+    method public void setReadOnly();
+  }
+
+  public final class Permissions extends java.security.PermissionCollection implements java.io.Serializable {
+    ctor public Permissions();
+    method public void add(java.security.Permission);
+    method public java.util.Enumeration<java.security.Permission> elements();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public abstract class Policy {
+    ctor public Policy();
+    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.Policy getInstance(String, java.security.Policy.Parameters, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public java.security.Policy.Parameters getParameters();
+    method public java.security.PermissionCollection getPermissions(java.security.CodeSource);
+    method public java.security.PermissionCollection getPermissions(java.security.ProtectionDomain);
+    method public static java.security.Policy getPolicy();
+    method public java.security.Provider getProvider();
+    method public String getType();
+    method public boolean implies(java.security.ProtectionDomain, java.security.Permission);
+    method public void refresh();
+    method public static void setPolicy(java.security.Policy);
+    field public static final java.security.PermissionCollection UNSUPPORTED_EMPTY_COLLECTION;
+  }
+
+  public static interface Policy.Parameters {
+  }
+
+  public abstract class PolicySpi {
+    ctor public PolicySpi();
+    method protected java.security.PermissionCollection engineGetPermissions(java.security.CodeSource);
+    method protected java.security.PermissionCollection engineGetPermissions(java.security.ProtectionDomain);
+    method protected abstract boolean engineImplies(java.security.ProtectionDomain, java.security.Permission);
+    method protected void engineRefresh();
+  }
+
+  public interface Principal {
+    method public boolean equals(Object);
+    method public String getName();
+    method public int hashCode();
+    method public default boolean implies(javax.security.auth.Subject);
+    method public String toString();
+  }
+
+  public interface PrivateKey extends java.security.Key javax.security.auth.Destroyable {
+    field public static final long serialVersionUID = 6034044314589513430L; // 0x53bd3b559a12c6d6L
+  }
+
+  public interface PrivilegedAction<T> {
+    method public T run();
+  }
+
+  public class PrivilegedActionException extends java.lang.Exception {
+    ctor public PrivilegedActionException(Exception);
+    method public Exception getException();
+  }
+
+  public interface PrivilegedExceptionAction<T> {
+    method public T run() throws java.lang.Exception;
+  }
+
+  public class ProtectionDomain {
+    ctor public ProtectionDomain(java.security.CodeSource, java.security.PermissionCollection);
+    ctor public ProtectionDomain(java.security.CodeSource, java.security.PermissionCollection, ClassLoader, java.security.Principal[]);
+    method public final ClassLoader getClassLoader();
+    method public final java.security.CodeSource getCodeSource();
+    method public final java.security.PermissionCollection getPermissions();
+    method public final java.security.Principal[] getPrincipals();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public abstract class Provider extends java.util.Properties {
+    ctor protected Provider(String, double, String);
+    method public Object compute(Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
+    method public Object computeIfAbsent(Object, java.util.function.Function<? super java.lang.Object,?>);
+    method public Object computeIfPresent(Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
+    method public java.util.Enumeration<java.lang.Object> elements();
+    method public java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet();
+    method public void forEach(java.util.function.BiConsumer<? super java.lang.Object,? super java.lang.Object>);
+    method public Object get(Object);
+    method public String getInfo();
+    method public String getName();
+    method public Object getOrDefault(Object, Object);
+    method public java.security.Provider.Service getService(String, String);
+    method public java.util.Set<java.security.Provider.Service> getServices();
+    method public double getVersion();
+    method public java.util.Set<java.lang.Object> keySet();
+    method public java.util.Enumeration<java.lang.Object> keys();
+    method public Object merge(Object, Object, java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
+    method public Object put(Object, Object);
+    method public void putAll(java.util.Map<?,?>);
+    method public Object putIfAbsent(Object, Object);
+    method protected void putService(java.security.Provider.Service);
+    method public Object remove(Object);
+    method protected void removeService(java.security.Provider.Service);
+    method public boolean replace(Object, Object, Object);
+    method public Object replace(Object, Object);
+    method public void replaceAll(java.util.function.BiFunction<? super java.lang.Object,? super java.lang.Object,?>);
+    method public java.util.Collection<java.lang.Object> values();
+  }
+
+  public static class Provider.Service {
+    ctor public Provider.Service(java.security.Provider, String, String, String, java.util.List<java.lang.String>, java.util.Map<java.lang.String,java.lang.String>);
+    method public final String getAlgorithm();
+    method public final String getAttribute(String);
+    method public final String getClassName();
+    method public final java.security.Provider getProvider();
+    method public final String getType();
+    method public Object newInstance(Object) throws java.security.NoSuchAlgorithmException;
+    method public boolean supportsParameter(Object);
+  }
+
+  public class ProviderException extends java.lang.RuntimeException {
+    ctor public ProviderException();
+    ctor public ProviderException(String);
+    ctor public ProviderException(String, Throwable);
+    ctor public ProviderException(Throwable);
+  }
+
+  public interface PublicKey extends java.security.Key {
+    field public static final long serialVersionUID = 7187392471159151072L; // 0x63bebf5f40c219e0L
+  }
+
+  public class SecureClassLoader extends java.lang.ClassLoader {
+    ctor protected SecureClassLoader(ClassLoader);
+    ctor protected SecureClassLoader();
+    method protected final Class<?> defineClass(String, byte[], int, int, java.security.CodeSource);
+    method protected final Class<?> defineClass(String, java.nio.ByteBuffer, java.security.CodeSource);
+    method protected java.security.PermissionCollection getPermissions(java.security.CodeSource);
+  }
+
+  public class SecureRandom extends java.util.Random {
+    ctor public SecureRandom();
+    ctor public SecureRandom(byte[]);
+    ctor protected SecureRandom(java.security.SecureRandomSpi, java.security.Provider);
+    method public byte[] generateSeed(int);
+    method public String getAlgorithm();
+    method public static java.security.SecureRandom getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.SecureRandom getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.SecureRandom getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.SecureRandom getInstanceStrong() throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public static byte[] getSeed(int);
+    method protected final int next(int);
+    method public void setSeed(byte[]);
+  }
+
+  public abstract class SecureRandomSpi implements java.io.Serializable {
+    ctor public SecureRandomSpi();
+    method protected abstract byte[] engineGenerateSeed(int);
+    method protected abstract void engineNextBytes(byte[]);
+    method protected abstract void engineSetSeed(byte[]);
+  }
+
+  public final class Security {
+    method public static int addProvider(java.security.Provider);
+    method @Deprecated public static String getAlgorithmProperty(String, String);
+    method public static java.util.Set<java.lang.String> getAlgorithms(String);
+    method public static String getProperty(String);
+    method public static java.security.Provider getProvider(String);
+    method public static java.security.Provider[] getProviders();
+    method public static java.security.Provider[] getProviders(String);
+    method public static java.security.Provider[] getProviders(java.util.Map<java.lang.String,java.lang.String>);
+    method public static int insertProviderAt(java.security.Provider, int);
+    method public static void removeProvider(String);
+    method public static void setProperty(String, String);
+  }
+
+  public final class SecurityPermission extends java.security.BasicPermission {
+    ctor public SecurityPermission(String);
+    ctor public SecurityPermission(String, String);
+  }
+
+  public abstract class Signature extends java.security.SignatureSpi {
+    ctor protected Signature(String);
+    method public final String getAlgorithm();
+    method public static java.security.Signature getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.Signature getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.Signature getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method @Deprecated public final Object getParameter(String) throws java.security.InvalidParameterException;
+    method public final java.security.AlgorithmParameters getParameters();
+    method public final java.security.Provider getProvider();
+    method public final void initSign(java.security.PrivateKey) throws java.security.InvalidKeyException;
+    method public final void initSign(java.security.PrivateKey, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method public final void initVerify(java.security.PublicKey) throws java.security.InvalidKeyException;
+    method public final void initVerify(java.security.cert.Certificate) throws java.security.InvalidKeyException;
+    method @Deprecated public final void setParameter(String, Object) throws java.security.InvalidParameterException;
+    method public final void setParameter(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
+    method public final byte[] sign() throws java.security.SignatureException;
+    method public final int sign(byte[], int, int) throws java.security.SignatureException;
+    method public final void update(byte) throws java.security.SignatureException;
+    method public final void update(byte[]) throws java.security.SignatureException;
+    method public final void update(byte[], int, int) throws java.security.SignatureException;
+    method public final void update(java.nio.ByteBuffer) throws java.security.SignatureException;
+    method public final boolean verify(byte[]) throws java.security.SignatureException;
+    method public final boolean verify(byte[], int, int) throws java.security.SignatureException;
+    field protected static final int SIGN = 2; // 0x2
+    field protected static final int UNINITIALIZED = 0; // 0x0
+    field protected static final int VERIFY = 3; // 0x3
+    field protected int state;
+  }
+
+  public class SignatureException extends java.security.GeneralSecurityException {
+    ctor public SignatureException();
+    ctor public SignatureException(String);
+    ctor public SignatureException(String, Throwable);
+    ctor public SignatureException(Throwable);
+  }
+
+  public abstract class SignatureSpi {
+    ctor public SignatureSpi();
+    method public Object clone() throws java.lang.CloneNotSupportedException;
+    method @Deprecated protected abstract Object engineGetParameter(String) throws java.security.InvalidParameterException;
+    method protected java.security.AlgorithmParameters engineGetParameters();
+    method protected abstract void engineInitSign(java.security.PrivateKey) throws java.security.InvalidKeyException;
+    method protected void engineInitSign(java.security.PrivateKey, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method protected abstract void engineInitVerify(java.security.PublicKey) throws java.security.InvalidKeyException;
+    method @Deprecated protected abstract void engineSetParameter(String, Object) throws java.security.InvalidParameterException;
+    method protected void engineSetParameter(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
+    method protected abstract byte[] engineSign() throws java.security.SignatureException;
+    method protected int engineSign(byte[], int, int) throws java.security.SignatureException;
+    method protected abstract void engineUpdate(byte) throws java.security.SignatureException;
+    method protected abstract void engineUpdate(byte[], int, int) throws java.security.SignatureException;
+    method protected void engineUpdate(java.nio.ByteBuffer);
+    method protected abstract boolean engineVerify(byte[]) throws java.security.SignatureException;
+    method protected boolean engineVerify(byte[], int, int) throws java.security.SignatureException;
+    field protected java.security.SecureRandom appRandom;
+  }
+
+  public final class SignedObject implements java.io.Serializable {
+    ctor public SignedObject(java.io.Serializable, java.security.PrivateKey, java.security.Signature) throws java.io.IOException, java.security.InvalidKeyException, java.security.SignatureException;
+    method public String getAlgorithm();
+    method public Object getObject() throws java.lang.ClassNotFoundException, java.io.IOException;
+    method public byte[] getSignature();
+    method public boolean verify(java.security.PublicKey, java.security.Signature) throws java.security.InvalidKeyException, java.security.SignatureException;
+  }
+
+  @Deprecated public abstract class Signer extends java.security.Identity {
+    ctor @Deprecated protected Signer();
+    ctor @Deprecated public Signer(String);
+    ctor @Deprecated public Signer(String, java.security.IdentityScope) throws java.security.KeyManagementException;
+    method @Deprecated public java.security.PrivateKey getPrivateKey();
+    method @Deprecated public final void setKeyPair(java.security.KeyPair) throws java.security.InvalidParameterException, java.security.KeyException;
+  }
+
+  public final class Timestamp implements java.io.Serializable {
+    ctor public Timestamp(java.util.Date, java.security.cert.CertPath);
+    method public java.security.cert.CertPath getSignerCertPath();
+    method public java.util.Date getTimestamp();
+  }
+
+  public class UnrecoverableEntryException extends java.security.GeneralSecurityException {
+    ctor public UnrecoverableEntryException();
+    ctor public UnrecoverableEntryException(String);
+  }
+
+  public class UnrecoverableKeyException extends java.security.UnrecoverableEntryException {
+    ctor public UnrecoverableKeyException();
+    ctor public UnrecoverableKeyException(String);
+  }
+
+  public final class UnresolvedPermission extends java.security.Permission implements java.io.Serializable {
+    ctor public UnresolvedPermission(String, String, String, java.security.cert.Certificate[]);
+    method public String getActions();
+    method public String getUnresolvedActions();
+    method public java.security.cert.Certificate[] getUnresolvedCerts();
+    method public String getUnresolvedName();
+    method public String getUnresolvedType();
+    method public boolean implies(java.security.Permission);
+  }
+
+}
+
+package java.security.acl {
+
+  public interface Acl extends java.security.acl.Owner {
+    method public boolean addEntry(java.security.Principal, java.security.acl.AclEntry) throws java.security.acl.NotOwnerException;
+    method public boolean checkPermission(java.security.Principal, java.security.acl.Permission);
+    method public java.util.Enumeration<java.security.acl.AclEntry> entries();
+    method public String getName();
+    method public java.util.Enumeration<java.security.acl.Permission> getPermissions(java.security.Principal);
+    method public boolean removeEntry(java.security.Principal, java.security.acl.AclEntry) throws java.security.acl.NotOwnerException;
+    method public void setName(java.security.Principal, String) throws java.security.acl.NotOwnerException;
+    method public String toString();
+  }
+
+  public interface AclEntry extends java.lang.Cloneable {
+    method public boolean addPermission(java.security.acl.Permission);
+    method public boolean checkPermission(java.security.acl.Permission);
+    method public Object clone();
+    method public java.security.Principal getPrincipal();
+    method public boolean isNegative();
+    method public java.util.Enumeration<java.security.acl.Permission> permissions();
+    method public boolean removePermission(java.security.acl.Permission);
+    method public void setNegativePermissions();
+    method public boolean setPrincipal(java.security.Principal);
+    method public String toString();
+  }
+
+  public class AclNotFoundException extends java.lang.Exception {
+    ctor public AclNotFoundException();
+  }
+
+  public interface Group extends java.security.Principal {
+    method public boolean addMember(java.security.Principal);
+    method public boolean isMember(java.security.Principal);
+    method public java.util.Enumeration<? extends java.security.Principal> members();
+    method public boolean removeMember(java.security.Principal);
+  }
+
+  public class LastOwnerException extends java.lang.Exception {
+    ctor public LastOwnerException();
+  }
+
+  public class NotOwnerException extends java.lang.Exception {
+    ctor public NotOwnerException();
+  }
+
+  public interface Owner {
+    method public boolean addOwner(java.security.Principal, java.security.Principal) throws java.security.acl.NotOwnerException;
+    method public boolean deleteOwner(java.security.Principal, java.security.Principal) throws java.security.acl.LastOwnerException, java.security.acl.NotOwnerException;
+    method public boolean isOwner(java.security.Principal);
+  }
+
+  public interface Permission {
+  }
+
+}
+
+package java.security.cert {
+
+  public abstract class CRL {
+    ctor protected CRL(String);
+    method public final String getType();
+    method public abstract boolean isRevoked(java.security.cert.Certificate);
+    method public abstract String toString();
+  }
+
+  public class CRLException extends java.security.GeneralSecurityException {
+    ctor public CRLException();
+    ctor public CRLException(String);
+    ctor public CRLException(String, Throwable);
+    ctor public CRLException(Throwable);
+  }
+
+  public enum CRLReason {
+    enum_constant public static final java.security.cert.CRLReason AA_COMPROMISE;
+    enum_constant public static final java.security.cert.CRLReason AFFILIATION_CHANGED;
+    enum_constant public static final java.security.cert.CRLReason CA_COMPROMISE;
+    enum_constant public static final java.security.cert.CRLReason CERTIFICATE_HOLD;
+    enum_constant public static final java.security.cert.CRLReason CESSATION_OF_OPERATION;
+    enum_constant public static final java.security.cert.CRLReason KEY_COMPROMISE;
+    enum_constant public static final java.security.cert.CRLReason PRIVILEGE_WITHDRAWN;
+    enum_constant public static final java.security.cert.CRLReason REMOVE_FROM_CRL;
+    enum_constant public static final java.security.cert.CRLReason SUPERSEDED;
+    enum_constant public static final java.security.cert.CRLReason UNSPECIFIED;
+    enum_constant public static final java.security.cert.CRLReason UNUSED;
+  }
+
+  public interface CRLSelector extends java.lang.Cloneable {
+    method public Object clone();
+    method public boolean match(java.security.cert.CRL);
+  }
+
+  public abstract class CertPath implements java.io.Serializable {
+    ctor protected CertPath(String);
+    method public abstract java.util.List<? extends java.security.cert.Certificate> getCertificates();
+    method public abstract byte[] getEncoded() throws java.security.cert.CertificateEncodingException;
+    method public abstract byte[] getEncoded(String) throws java.security.cert.CertificateEncodingException;
+    method public abstract java.util.Iterator<java.lang.String> getEncodings();
+    method public String getType();
+    method protected Object writeReplace() throws java.io.ObjectStreamException;
+  }
+
+  protected static class CertPath.CertPathRep implements java.io.Serializable {
+    ctor protected CertPath.CertPathRep(String, byte[]);
+    method protected Object readResolve() throws java.io.ObjectStreamException;
+  }
+
+  public class CertPathBuilder {
+    ctor protected CertPathBuilder(java.security.cert.CertPathBuilderSpi, java.security.Provider, String);
+    method public final java.security.cert.CertPathBuilderResult build(java.security.cert.CertPathParameters) throws java.security.cert.CertPathBuilderException, java.security.InvalidAlgorithmParameterException;
+    method public final String getAlgorithm();
+    method public static final String getDefaultType();
+    method public static java.security.cert.CertPathBuilder getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.cert.CertPathBuilder getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.cert.CertPathBuilder getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final java.security.cert.CertPathChecker getRevocationChecker();
+  }
+
+  public class CertPathBuilderException extends java.security.GeneralSecurityException {
+    ctor public CertPathBuilderException();
+    ctor public CertPathBuilderException(String);
+    ctor public CertPathBuilderException(Throwable);
+    ctor public CertPathBuilderException(String, Throwable);
+  }
+
+  public interface CertPathBuilderResult extends java.lang.Cloneable {
+    method public Object clone();
+    method public java.security.cert.CertPath getCertPath();
+  }
+
+  public abstract class CertPathBuilderSpi {
+    ctor public CertPathBuilderSpi();
+    method public abstract java.security.cert.CertPathBuilderResult engineBuild(java.security.cert.CertPathParameters) throws java.security.cert.CertPathBuilderException, java.security.InvalidAlgorithmParameterException;
+    method public java.security.cert.CertPathChecker engineGetRevocationChecker();
+  }
+
+  public interface CertPathChecker {
+    method public void check(java.security.cert.Certificate) throws java.security.cert.CertPathValidatorException;
+    method public void init(boolean) throws java.security.cert.CertPathValidatorException;
+    method public boolean isForwardCheckingSupported();
+  }
+
+  public interface CertPathParameters extends java.lang.Cloneable {
+    method public Object clone();
+  }
+
+  public class CertPathValidator {
+    ctor protected CertPathValidator(java.security.cert.CertPathValidatorSpi, java.security.Provider, String);
+    method public final String getAlgorithm();
+    method public static final String getDefaultType();
+    method public static java.security.cert.CertPathValidator getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static java.security.cert.CertPathValidator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.cert.CertPathValidator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final java.security.cert.CertPathChecker getRevocationChecker();
+    method public final java.security.cert.CertPathValidatorResult validate(java.security.cert.CertPath, java.security.cert.CertPathParameters) throws java.security.cert.CertPathValidatorException, java.security.InvalidAlgorithmParameterException;
+  }
+
+  public class CertPathValidatorException extends java.security.GeneralSecurityException {
+    ctor public CertPathValidatorException();
+    ctor public CertPathValidatorException(String);
+    ctor public CertPathValidatorException(Throwable);
+    ctor public CertPathValidatorException(String, Throwable);
+    ctor public CertPathValidatorException(String, Throwable, java.security.cert.CertPath, int);
+    ctor public CertPathValidatorException(String, Throwable, java.security.cert.CertPath, int, java.security.cert.CertPathValidatorException.Reason);
+    method public java.security.cert.CertPath getCertPath();
+    method public int getIndex();
+    method public java.security.cert.CertPathValidatorException.Reason getReason();
+  }
+
+  public enum CertPathValidatorException.BasicReason implements java.security.cert.CertPathValidatorException.Reason {
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason ALGORITHM_CONSTRAINED;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason EXPIRED;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason INVALID_SIGNATURE;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason NOT_YET_VALID;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason REVOKED;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason UNDETERMINED_REVOCATION_STATUS;
+    enum_constant public static final java.security.cert.CertPathValidatorException.BasicReason UNSPECIFIED;
+  }
+
+  public static interface CertPathValidatorException.Reason extends java.io.Serializable {
+  }
+
+  public interface CertPathValidatorResult extends java.lang.Cloneable {
+    method public Object clone();
+  }
+
+  public abstract class CertPathValidatorSpi {
+    ctor public CertPathValidatorSpi();
+    method public java.security.cert.CertPathChecker engineGetRevocationChecker();
+    method public abstract java.security.cert.CertPathValidatorResult engineValidate(java.security.cert.CertPath, java.security.cert.CertPathParameters) throws java.security.cert.CertPathValidatorException, java.security.InvalidAlgorithmParameterException;
+  }
+
+  public interface CertSelector extends java.lang.Cloneable {
+    method public Object clone();
+    method public boolean match(java.security.cert.Certificate);
+  }
+
+  public class CertStore {
+    ctor protected CertStore(java.security.cert.CertStoreSpi, java.security.Provider, String, java.security.cert.CertStoreParameters);
+    method public final java.util.Collection<? extends java.security.cert.CRL> getCRLs(java.security.cert.CRLSelector) throws java.security.cert.CertStoreException;
+    method public final java.security.cert.CertStoreParameters getCertStoreParameters();
+    method public final java.util.Collection<? extends java.security.cert.Certificate> getCertificates(java.security.cert.CertSelector) throws java.security.cert.CertStoreException;
+    method public static final String getDefaultType();
+    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException;
+    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters, String) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static java.security.cert.CertStore getInstance(String, java.security.cert.CertStoreParameters, java.security.Provider) throws java.security.InvalidAlgorithmParameterException, java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final String getType();
+  }
+
+  public class CertStoreException extends java.security.GeneralSecurityException {
+    ctor public CertStoreException();
+    ctor public CertStoreException(String);
+    ctor public CertStoreException(Throwable);
+    ctor public CertStoreException(String, Throwable);
+  }
+
+  public interface CertStoreParameters extends java.lang.Cloneable {
+    method public Object clone();
+  }
+
+  public abstract class CertStoreSpi {
+    ctor public CertStoreSpi(java.security.cert.CertStoreParameters) throws java.security.InvalidAlgorithmParameterException;
+    method public abstract java.util.Collection<? extends java.security.cert.CRL> engineGetCRLs(java.security.cert.CRLSelector) throws java.security.cert.CertStoreException;
+    method public abstract java.util.Collection<? extends java.security.cert.Certificate> engineGetCertificates(java.security.cert.CertSelector) throws java.security.cert.CertStoreException;
+  }
+
+  public abstract class Certificate implements java.io.Serializable {
+    ctor protected Certificate(String);
+    method public abstract byte[] getEncoded() throws java.security.cert.CertificateEncodingException;
+    method public abstract java.security.PublicKey getPublicKey();
+    method public final String getType();
+    method public abstract String toString();
+    method public abstract void verify(java.security.PublicKey) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method public abstract void verify(java.security.PublicKey, String) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method public void verify(java.security.PublicKey, java.security.Provider) throws java.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
+    method protected Object writeReplace() throws java.io.ObjectStreamException;
+  }
+
+  protected static class Certificate.CertificateRep implements java.io.Serializable {
+    ctor protected Certificate.CertificateRep(String, byte[]);
+    method protected Object readResolve() throws java.io.ObjectStreamException;
+  }
+
+  public class CertificateEncodingException extends java.security.cert.CertificateException {
+    ctor public CertificateEncodingException();
+    ctor public CertificateEncodingException(String);
+    ctor public CertificateEncodingException(String, Throwable);
+    ctor public CertificateEncodingException(Throwable);
+  }
+
+  public class CertificateException extends java.security.GeneralSecurityException {
+    ctor public CertificateException();
+    ctor public CertificateException(String);
+    ctor public CertificateException(String, Throwable);
+    ctor public CertificateException(Throwable);
+  }
+
+  public class CertificateExpiredException extends java.security.cert.CertificateException {
+    ctor public CertificateExpiredException();
+    ctor public CertificateExpiredException(String);
+  }
+
+  public class CertificateFactory {
+    ctor protected CertificateFactory(java.security.cert.CertificateFactorySpi, java.security.Provider, String);
+    method public final java.security.cert.CRL generateCRL(java.io.InputStream) throws java.security.cert.CRLException;
+    method public final java.util.Collection<? extends java.security.cert.CRL> generateCRLs(java.io.InputStream) throws java.security.cert.CRLException;
+    method public final java.security.cert.CertPath generateCertPath(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public final java.security.cert.CertPath generateCertPath(java.io.InputStream, String) throws java.security.cert.CertificateException;
+    method public final java.security.cert.CertPath generateCertPath(java.util.List<? extends java.security.cert.Certificate>) throws java.security.cert.CertificateException;
+    method public final java.security.cert.Certificate generateCertificate(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public final java.util.Collection<? extends java.security.cert.Certificate> generateCertificates(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public final java.util.Iterator<java.lang.String> getCertPathEncodings();
+    method public static final java.security.cert.CertificateFactory getInstance(String) throws java.security.cert.CertificateException;
+    method public static final java.security.cert.CertificateFactory getInstance(String, String) throws java.security.cert.CertificateException, java.security.NoSuchProviderException;
+    method public static final java.security.cert.CertificateFactory getInstance(String, java.security.Provider) throws java.security.cert.CertificateException;
+    method public final java.security.Provider getProvider();
+    method public final String getType();
+  }
+
+  public abstract class CertificateFactorySpi {
+    ctor public CertificateFactorySpi();
+    method public abstract java.security.cert.CRL engineGenerateCRL(java.io.InputStream) throws java.security.cert.CRLException;
+    method public abstract java.util.Collection<? extends java.security.cert.CRL> engineGenerateCRLs(java.io.InputStream) throws java.security.cert.CRLException;
+    method public java.security.cert.CertPath engineGenerateCertPath(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public java.security.cert.CertPath engineGenerateCertPath(java.io.InputStream, String) throws java.security.cert.CertificateException;
+    method public java.security.cert.CertPath engineGenerateCertPath(java.util.List<? extends java.security.cert.Certificate>) throws java.security.cert.CertificateException;
+    method public abstract java.security.cert.Certificate engineGenerateCertificate(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public abstract java.util.Collection<? extends java.security.cert.Certificate> engineGenerateCertificates(java.io.InputStream) throws java.security.cert.CertificateException;
+    method public java.util.Iterator<java.lang.String> engineGetCertPathEncodings();
+  }
+
+  public class CertificateNotYetValidException extends java.security.cert.CertificateException {
+    ctor public CertificateNotYetValidException();
+    ctor public CertificateNotYetValidException(String);
+  }
+
+  public class CertificateParsingException extends java.security.cert.CertificateException {
+    ctor public CertificateParsingException();
+    ctor public CertificateParsingException(String);
+    ctor public CertificateParsingException(String, Throwable);
+    ctor public CertificateParsingException(Throwable);
+  }
+
+  public class CertificateRevokedException extends java.security.cert.CertificateException {
+    ctor public CertificateRevokedException(java.util.Date, java.security.cert.CRLReason, javax.security.auth.x500.X500Principal, java.util.Map<java.lang.String,java.security.cert.Extension>);
+    method public javax.security.auth.x500.X500Principal getAuthorityName();
+    method public java.util.Map<java.lang.String,java.security.cert.Extension> getExtensions();
+    method public java.util.Date getInvalidityDate();
+    method public java.util.Date getRevocationDate();
+    method public java.security.cert.CRLReason getRevocationReason();
+  }
+
+  public class CollectionCertStoreParameters implements java.security.cert.CertStoreParameters {
+    ctor public CollectionCertStoreParameters(java.util.Collection<?>);
+    ctor public CollectionCertStoreParameters();
+    method public Object clone();
+    method public java.util.Collection<?> getCollection();
+  }
+
+  public interface Extension {
+    method public void encode(java.io.OutputStream) throws java.io.IOException;
+    method public String getId();
+    method public byte[] getValue();
+    method public boolean isCritical();
+  }
+
+  public class LDAPCertStoreParameters implements java.security.cert.CertStoreParameters {
+    ctor public LDAPCertStoreParameters(String, int);
+    ctor public LDAPCertStoreParameters(String);
+    ctor public LDAPCertStoreParameters();
+    method public Object clone();
+    method public int getPort();
+    method public String getServerName();
+  }
+
+  public class PKIXBuilderParameters extends java.security.cert.PKIXParameters {
+    ctor public PKIXBuilderParameters(java.util.Set<java.security.cert.TrustAnchor>, java.security.cert.CertSelector) throws java.security.InvalidAlgorithmParameterException;
+    ctor public PKIXBuilderParameters(java.security.KeyStore, java.security.cert.CertSelector) throws java.security.InvalidAlgorithmParameterException, java.security.KeyStoreException;
+    method public int getMaxPathLength();
+    method public void setMaxPathLength(int);
+  }
+
+  public class PKIXCertPathBuilderResult extends java.security.cert.PKIXCertPathValidatorResult implements java.security.cert.CertPathBuilderResult {
+    ctor public PKIXCertPathBuilderResult(java.security.cert.CertPath, java.security.cert.TrustAnchor, java.security.cert.PolicyNode, java.security.PublicKey);
+    method public java.security.cert.CertPath getCertPath();
+  }
+
+  public abstract class PKIXCertPathChecker implements java.security.cert.CertPathChecker java.lang.Cloneable {
+    ctor protected PKIXCertPathChecker();
+    method public abstract void check(java.security.cert.Certificate, java.util.Collection<java.lang.String>) throws java.security.cert.CertPathValidatorException;
+    method public void check(java.security.cert.Certificate) throws java.security.cert.CertPathValidatorException;
+    method public Object clone();
+    method public abstract java.util.Set<java.lang.String> getSupportedExtensions();
+  }
+
+  public class PKIXCertPathValidatorResult implements java.security.cert.CertPathValidatorResult {
+    ctor public PKIXCertPathValidatorResult(java.security.cert.TrustAnchor, java.security.cert.PolicyNode, java.security.PublicKey);
+    method public Object clone();
+    method public java.security.cert.PolicyNode getPolicyTree();
+    method public java.security.PublicKey getPublicKey();
+    method public java.security.cert.TrustAnchor getTrustAnchor();
+  }
+
+  public class PKIXParameters implements java.security.cert.CertPathParameters {
+    ctor public PKIXParameters(java.util.Set<java.security.cert.TrustAnchor>) throws java.security.InvalidAlgorithmParameterException;
+    ctor public PKIXParameters(java.security.KeyStore) throws java.security.InvalidAlgorithmParameterException, java.security.KeyStoreException;
+    method public void addCertPathChecker(java.security.cert.PKIXCertPathChecker);
+    method public void addCertStore(java.security.cert.CertStore);
+    method public Object clone();
+    method public java.util.List<java.security.cert.PKIXCertPathChecker> getCertPathCheckers();
+    method public java.util.List<java.security.cert.CertStore> getCertStores();
+    method public java.util.Date getDate();
+    method public java.util.Set<java.lang.String> getInitialPolicies();
+    method public boolean getPolicyQualifiersRejected();
+    method public String getSigProvider();
+    method public java.security.cert.CertSelector getTargetCertConstraints();
+    method public java.util.Set<java.security.cert.TrustAnchor> getTrustAnchors();
+    method public boolean isAnyPolicyInhibited();
+    method public boolean isExplicitPolicyRequired();
+    method public boolean isPolicyMappingInhibited();
+    method public boolean isRevocationEnabled();
+    method public void setAnyPolicyInhibited(boolean);
+    method public void setCertPathCheckers(java.util.List<java.security.cert.PKIXCertPathChecker>);
+    method public void setCertStores(java.util.List<java.security.cert.CertStore>);
+    method public void setDate(java.util.Date);
+    method public void setExplicitPolicyRequired(boolean);
+    method public void setInitialPolicies(java.util.Set<java.lang.String>);
+    method public void setPolicyMappingInhibited(boolean);
+    method public void setPolicyQualifiersRejected(boolean);
+    method public void setRevocationEnabled(boolean);
+    method public void setSigProvider(String);
+    method public void setTargetCertConstraints(java.security.cert.CertSelector);
+    method public void setTrustAnchors(java.util.Set<java.security.cert.TrustAnchor>) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public enum PKIXReason implements java.security.cert.CertPathValidatorException.Reason {
+    enum_constant public static final java.security.cert.PKIXReason INVALID_KEY_USAGE;
+    enum_constant public static final java.security.cert.PKIXReason INVALID_NAME;
+    enum_constant public static final java.security.cert.PKIXReason INVALID_POLICY;
+    enum_constant public static final java.security.cert.PKIXReason NAME_CHAINING;
+    enum_constant public static final java.security.cert.PKIXReason NOT_CA_CERT;
+    enum_constant public static final java.security.cert.PKIXReason NO_TRUST_ANCHOR;
+    enum_constant public static final java.security.cert.PKIXReason PATH_TOO_LONG;
+    enum_constant public static final java.security.cert.PKIXReason UNRECOGNIZED_CRIT_EXT;
+  }
+
+  public abstract class PKIXRevocationChecker extends java.security.cert.PKIXCertPathChecker {
+    ctor protected PKIXRevocationChecker();
+    method public java.security.cert.PKIXRevocationChecker clone();
+    method public java.util.List<java.security.cert.Extension> getOcspExtensions();
+    method public java.net.URI getOcspResponder();
+    method public java.security.cert.X509Certificate getOcspResponderCert();
+    method public java.util.Map<java.security.cert.X509Certificate,byte[]> getOcspResponses();
+    method public java.util.Set<java.security.cert.PKIXRevocationChecker.Option> getOptions();
+    method public abstract java.util.List<java.security.cert.CertPathValidatorException> getSoftFailExceptions();
+    method public void setOcspExtensions(java.util.List<java.security.cert.Extension>);
+    method public void setOcspResponder(java.net.URI);
+    method public void setOcspResponderCert(java.security.cert.X509Certificate);
+    method public void setOcspResponses(java.util.Map<java.security.cert.X509Certificate,byte[]>);
+    method public void setOptions(java.util.Set<java.security.cert.PKIXRevocationChecker.Option>);
+  }
+
+  public enum PKIXRevocationChecker.Option {
+    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option NO_FALLBACK;
+    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option ONLY_END_ENTITY;
+    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option PREFER_CRLS;
+    enum_constant public static final java.security.cert.PKIXRevocationChecker.Option SOFT_FAIL;
+  }
+
+  public interface PolicyNode {
+    method public java.util.Iterator<? extends java.security.cert.PolicyNode> getChildren();
+    method public int getDepth();
+    method public java.util.Set<java.lang.String> getExpectedPolicies();
+    method public java.security.cert.PolicyNode getParent();
+    method public java.util.Set<? extends java.security.cert.PolicyQualifierInfo> getPolicyQualifiers();
+    method public String getValidPolicy();
+    method public boolean isCritical();
+  }
+
+  public class PolicyQualifierInfo {
+    ctor public PolicyQualifierInfo(byte[]) throws java.io.IOException;
+    method public final byte[] getEncoded();
+    method public final byte[] getPolicyQualifier();
+    method public final String getPolicyQualifierId();
+  }
+
+  public class TrustAnchor {
+    ctor public TrustAnchor(java.security.cert.X509Certificate, byte[]);
+    ctor public TrustAnchor(javax.security.auth.x500.X500Principal, java.security.PublicKey, byte[]);
+    ctor public TrustAnchor(String, java.security.PublicKey, byte[]);
+    method public final javax.security.auth.x500.X500Principal getCA();
+    method public final String getCAName();
+    method public final java.security.PublicKey getCAPublicKey();
+    method public final byte[] getNameConstraints();
+    method public final java.security.cert.X509Certificate getTrustedCert();
+  }
+
+  public abstract class X509CRL extends java.security.cert.CRL implements java.security.cert.X509Extension {
+    ctor protected X509CRL();
+    method public abstract byte[] getEncoded() throws java.security.cert.CRLException;
+    method public abstract java.security.Principal getIssuerDN();
+    method public javax.security.auth.x500.X500Principal getIssuerX500Principal();
+    method public abstract java.util.Date getNextUpdate();
+    method public abstract java.security.cert.X509CRLEntry getRevokedCertificate(java.math.BigInteger);
+    method public java.security.cert.X509CRLEntry getRevokedCertificate(java.security.cert.X509Certificate);
+    method public abstract java.util.Set<? extends java.security.cert.X509CRLEntry> getRevokedCertificates();
+    method public abstract String getSigAlgName();
+    method public abstract String getSigAlgOID();
+    method public abstract byte[] getSigAlgParams();
+    method public abstract byte[] getSignature();
+    method public abstract byte[] getTBSCertList() throws java.security.cert.CRLException;
+    method public abstract java.util.Date getThisUpdate();
+    method public abstract int getVersion();
+    method public abstract void verify(java.security.PublicKey) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method public abstract void verify(java.security.PublicKey, String) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method public void verify(java.security.PublicKey, java.security.Provider) throws java.security.cert.CRLException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.SignatureException;
+  }
+
+  public abstract class X509CRLEntry implements java.security.cert.X509Extension {
+    ctor public X509CRLEntry();
+    method public javax.security.auth.x500.X500Principal getCertificateIssuer();
+    method public abstract byte[] getEncoded() throws java.security.cert.CRLException;
+    method public abstract java.util.Date getRevocationDate();
+    method public java.security.cert.CRLReason getRevocationReason();
+    method public abstract java.math.BigInteger getSerialNumber();
+    method public abstract boolean hasExtensions();
+    method public abstract String toString();
+  }
+
+  public class X509CRLSelector implements java.security.cert.CRLSelector {
+    ctor public X509CRLSelector();
+    method public void addIssuer(javax.security.auth.x500.X500Principal);
+    method public void addIssuerName(String) throws java.io.IOException;
+    method public void addIssuerName(byte[]) throws java.io.IOException;
+    method public Object clone();
+    method public java.security.cert.X509Certificate getCertificateChecking();
+    method public java.util.Date getDateAndTime();
+    method public java.util.Collection<java.lang.Object> getIssuerNames();
+    method public java.util.Collection<javax.security.auth.x500.X500Principal> getIssuers();
+    method public java.math.BigInteger getMaxCRL();
+    method public java.math.BigInteger getMinCRL();
+    method public boolean match(java.security.cert.CRL);
+    method public void setCertificateChecking(java.security.cert.X509Certificate);
+    method public void setDateAndTime(java.util.Date);
+    method public void setIssuerNames(java.util.Collection<?>) throws java.io.IOException;
+    method public void setIssuers(java.util.Collection<javax.security.auth.x500.X500Principal>);
+    method public void setMaxCRLNumber(java.math.BigInteger);
+    method public void setMinCRLNumber(java.math.BigInteger);
+  }
+
+  public class X509CertSelector implements java.security.cert.CertSelector {
+    ctor public X509CertSelector();
+    method public void addPathToName(int, String) throws java.io.IOException;
+    method public void addPathToName(int, byte[]) throws java.io.IOException;
+    method public void addSubjectAlternativeName(int, String) throws java.io.IOException;
+    method public void addSubjectAlternativeName(int, byte[]) throws java.io.IOException;
+    method public Object clone();
+    method public byte[] getAuthorityKeyIdentifier();
+    method public int getBasicConstraints();
+    method public java.security.cert.X509Certificate getCertificate();
+    method public java.util.Date getCertificateValid();
+    method public java.util.Set<java.lang.String> getExtendedKeyUsage();
+    method public javax.security.auth.x500.X500Principal getIssuer();
+    method public byte[] getIssuerAsBytes() throws java.io.IOException;
+    method public String getIssuerAsString();
+    method public boolean[] getKeyUsage();
+    method public boolean getMatchAllSubjectAltNames();
+    method public byte[] getNameConstraints();
+    method public java.util.Collection<java.util.List<?>> getPathToNames();
+    method public java.util.Set<java.lang.String> getPolicy();
+    method public java.util.Date getPrivateKeyValid();
+    method public java.math.BigInteger getSerialNumber();
+    method public javax.security.auth.x500.X500Principal getSubject();
+    method public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames();
+    method public byte[] getSubjectAsBytes() throws java.io.IOException;
+    method public String getSubjectAsString();
+    method public byte[] getSubjectKeyIdentifier();
+    method public java.security.PublicKey getSubjectPublicKey();
+    method public String getSubjectPublicKeyAlgID();
+    method public boolean match(java.security.cert.Certificate);
+    method public void setAuthorityKeyIdentifier(byte[]);
+    method public void setBasicConstraints(int);
+    method public void setCertificate(java.security.cert.X509Certificate);
+    method public void setCertificateValid(java.util.Date);
+    method public void setExtendedKeyUsage(java.util.Set<java.lang.String>) throws java.io.IOException;
+    method public void setIssuer(javax.security.auth.x500.X500Principal);
+    method public void setIssuer(String) throws java.io.IOException;
+    method public void setIssuer(byte[]) throws java.io.IOException;
+    method public void setKeyUsage(boolean[]);
+    method public void setMatchAllSubjectAltNames(boolean);
+    method public void setNameConstraints(byte[]) throws java.io.IOException;
+    method public void setPathToNames(java.util.Collection<java.util.List<?>>) throws java.io.IOException;
+    method public void setPolicy(java.util.Set<java.lang.String>) throws java.io.IOException;
+    method public void setPrivateKeyValid(java.util.Date);
+    method public void setSerialNumber(java.math.BigInteger);
+    method public void setSubject(javax.security.auth.x500.X500Principal);
+    method public void setSubject(String) throws java.io.IOException;
+    method public void setSubject(byte[]) throws java.io.IOException;
+    method public void setSubjectAlternativeNames(java.util.Collection<java.util.List<?>>) throws java.io.IOException;
+    method public void setSubjectKeyIdentifier(byte[]);
+    method public void setSubjectPublicKey(java.security.PublicKey);
+    method public void setSubjectPublicKey(byte[]) throws java.io.IOException;
+    method public void setSubjectPublicKeyAlgID(String) throws java.io.IOException;
+  }
+
+  public abstract class X509Certificate extends java.security.cert.Certificate implements java.security.cert.X509Extension {
+    ctor protected X509Certificate();
+    method public abstract void checkValidity() throws java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException;
+    method public abstract void checkValidity(java.util.Date) throws java.security.cert.CertificateExpiredException, java.security.cert.CertificateNotYetValidException;
+    method public abstract int getBasicConstraints();
+    method public java.util.List<java.lang.String> getExtendedKeyUsage() throws java.security.cert.CertificateParsingException;
+    method public java.util.Collection<java.util.List<?>> getIssuerAlternativeNames() throws java.security.cert.CertificateParsingException;
+    method public abstract java.security.Principal getIssuerDN();
+    method public abstract boolean[] getIssuerUniqueID();
+    method public javax.security.auth.x500.X500Principal getIssuerX500Principal();
+    method public abstract boolean[] getKeyUsage();
+    method public abstract java.util.Date getNotAfter();
+    method public abstract java.util.Date getNotBefore();
+    method public abstract java.math.BigInteger getSerialNumber();
+    method public abstract String getSigAlgName();
+    method public abstract String getSigAlgOID();
+    method public abstract byte[] getSigAlgParams();
+    method public abstract byte[] getSignature();
+    method public java.util.Collection<java.util.List<?>> getSubjectAlternativeNames() throws java.security.cert.CertificateParsingException;
+    method public abstract java.security.Principal getSubjectDN();
+    method public abstract boolean[] getSubjectUniqueID();
+    method public javax.security.auth.x500.X500Principal getSubjectX500Principal();
+    method public abstract byte[] getTBSCertificate() throws java.security.cert.CertificateEncodingException;
+    method public abstract int getVersion();
+  }
+
+  public interface X509Extension {
+    method public java.util.Set<java.lang.String> getCriticalExtensionOIDs();
+    method public byte[] getExtensionValue(String);
+    method public java.util.Set<java.lang.String> getNonCriticalExtensionOIDs();
+    method public boolean hasUnsupportedCriticalExtension();
+  }
+
+}
+
+package java.security.interfaces {
+
+  public interface DSAKey {
+    method public java.security.interfaces.DSAParams getParams();
+  }
+
+  public interface DSAKeyPairGenerator {
+    method public void initialize(java.security.interfaces.DSAParams, java.security.SecureRandom) throws java.security.InvalidParameterException;
+    method public void initialize(int, boolean, java.security.SecureRandom) throws java.security.InvalidParameterException;
+  }
+
+  public interface DSAParams {
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getQ();
+  }
+
+  public interface DSAPrivateKey extends java.security.interfaces.DSAKey java.security.PrivateKey {
+    method public java.math.BigInteger getX();
+    field public static final long serialVersionUID = 7776497482533790279L; // 0x6bebab423b256247L
+  }
+
+  public interface DSAPublicKey extends java.security.interfaces.DSAKey java.security.PublicKey {
+    method public java.math.BigInteger getY();
+    field public static final long serialVersionUID = 1234526332779022332L; // 0x1121eb28ab28c7fcL
+  }
+
+  public interface ECKey {
+    method public java.security.spec.ECParameterSpec getParams();
+  }
+
+  public interface ECPrivateKey extends java.security.PrivateKey java.security.interfaces.ECKey {
+    method public java.math.BigInteger getS();
+    field public static final long serialVersionUID = -7896394956925609184L; // 0x926a5e9fa2435b20L
+  }
+
+  public interface ECPublicKey extends java.security.PublicKey java.security.interfaces.ECKey {
+    method public java.security.spec.ECPoint getW();
+    field public static final long serialVersionUID = -3314988629879632826L; // 0xd1fecb679990cc46L
+  }
+
+  public interface RSAKey {
+    method public java.math.BigInteger getModulus();
+  }
+
+  public interface RSAMultiPrimePrivateCrtKey extends java.security.interfaces.RSAPrivateKey {
+    method public java.math.BigInteger getCrtCoefficient();
+    method public java.security.spec.RSAOtherPrimeInfo[] getOtherPrimeInfo();
+    method public java.math.BigInteger getPrimeExponentP();
+    method public java.math.BigInteger getPrimeExponentQ();
+    method public java.math.BigInteger getPrimeP();
+    method public java.math.BigInteger getPrimeQ();
+    method public java.math.BigInteger getPublicExponent();
+    field public static final long serialVersionUID = 618058533534628008L; // 0x893c8f62dbaf8a8L
+  }
+
+  public interface RSAPrivateCrtKey extends java.security.interfaces.RSAPrivateKey {
+    method public java.math.BigInteger getCrtCoefficient();
+    method public java.math.BigInteger getPrimeExponentP();
+    method public java.math.BigInteger getPrimeExponentQ();
+    method public java.math.BigInteger getPrimeP();
+    method public java.math.BigInteger getPrimeQ();
+    method public java.math.BigInteger getPublicExponent();
+    field public static final long serialVersionUID = -5682214253527700368L; // 0xb124b83df8d1ec70L
+  }
+
+  public interface RSAPrivateKey extends java.security.PrivateKey java.security.interfaces.RSAKey {
+    method public java.math.BigInteger getPrivateExponent();
+    field public static final long serialVersionUID = 5187144804936595022L; // 0x47fc70b7a8c2364eL
+  }
+
+  public interface RSAPublicKey extends java.security.PublicKey java.security.interfaces.RSAKey {
+    method public java.math.BigInteger getPublicExponent();
+    field public static final long serialVersionUID = -8727434096241101194L; // 0x86e1ecedeceab676L
+  }
+
+}
+
+package java.security.spec {
+
+  public interface AlgorithmParameterSpec {
+  }
+
+  public class DSAParameterSpec implements java.security.spec.AlgorithmParameterSpec java.security.interfaces.DSAParams {
+    ctor public DSAParameterSpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getQ();
+  }
+
+  public class DSAPrivateKeySpec implements java.security.spec.KeySpec {
+    ctor public DSAPrivateKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getQ();
+    method public java.math.BigInteger getX();
+  }
+
+  public class DSAPublicKeySpec implements java.security.spec.KeySpec {
+    ctor public DSAPublicKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getQ();
+    method public java.math.BigInteger getY();
+  }
+
+  public interface ECField {
+    method public int getFieldSize();
+  }
+
+  public class ECFieldF2m implements java.security.spec.ECField {
+    ctor public ECFieldF2m(int);
+    ctor public ECFieldF2m(int, java.math.BigInteger);
+    ctor public ECFieldF2m(int, int[]);
+    method public int getFieldSize();
+    method public int getM();
+    method public int[] getMidTermsOfReductionPolynomial();
+    method public java.math.BigInteger getReductionPolynomial();
+  }
+
+  public class ECFieldFp implements java.security.spec.ECField {
+    ctor public ECFieldFp(java.math.BigInteger);
+    method public int getFieldSize();
+    method public java.math.BigInteger getP();
+  }
+
+  public class ECGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public ECGenParameterSpec(String);
+    method public String getName();
+  }
+
+  public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public ECParameterSpec(java.security.spec.EllipticCurve, java.security.spec.ECPoint, java.math.BigInteger, int);
+    method public int getCofactor();
+    method public java.security.spec.EllipticCurve getCurve();
+    method public java.security.spec.ECPoint getGenerator();
+    method public java.math.BigInteger getOrder();
+  }
+
+  public class ECPoint {
+    ctor public ECPoint(java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getAffineX();
+    method public java.math.BigInteger getAffineY();
+    field public static final java.security.spec.ECPoint POINT_INFINITY;
+  }
+
+  public class ECPrivateKeySpec implements java.security.spec.KeySpec {
+    ctor public ECPrivateKeySpec(java.math.BigInteger, java.security.spec.ECParameterSpec);
+    method public java.security.spec.ECParameterSpec getParams();
+    method public java.math.BigInteger getS();
+  }
+
+  public class ECPublicKeySpec implements java.security.spec.KeySpec {
+    ctor public ECPublicKeySpec(java.security.spec.ECPoint, java.security.spec.ECParameterSpec);
+    method public java.security.spec.ECParameterSpec getParams();
+    method public java.security.spec.ECPoint getW();
+  }
+
+  public class EllipticCurve {
+    ctor public EllipticCurve(java.security.spec.ECField, java.math.BigInteger, java.math.BigInteger);
+    ctor public EllipticCurve(java.security.spec.ECField, java.math.BigInteger, java.math.BigInteger, byte[]);
+    method public java.math.BigInteger getA();
+    method public java.math.BigInteger getB();
+    method public java.security.spec.ECField getField();
+    method public byte[] getSeed();
+  }
+
+  public abstract class EncodedKeySpec implements java.security.spec.KeySpec {
+    ctor public EncodedKeySpec(byte[]);
+    method public byte[] getEncoded();
+    method public abstract String getFormat();
+  }
+
+  public class InvalidKeySpecException extends java.security.GeneralSecurityException {
+    ctor public InvalidKeySpecException();
+    ctor public InvalidKeySpecException(String);
+    ctor public InvalidKeySpecException(String, Throwable);
+    ctor public InvalidKeySpecException(Throwable);
+  }
+
+  public class InvalidParameterSpecException extends java.security.GeneralSecurityException {
+    ctor public InvalidParameterSpecException();
+    ctor public InvalidParameterSpecException(String);
+  }
+
+  public interface KeySpec {
+  }
+
+  public class MGF1ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public MGF1ParameterSpec(String);
+    method public String getDigestAlgorithm();
+    field public static final java.security.spec.MGF1ParameterSpec SHA1;
+    field public static final java.security.spec.MGF1ParameterSpec SHA224;
+    field public static final java.security.spec.MGF1ParameterSpec SHA256;
+    field public static final java.security.spec.MGF1ParameterSpec SHA384;
+    field public static final java.security.spec.MGF1ParameterSpec SHA512;
+  }
+
+  public class PKCS8EncodedKeySpec extends java.security.spec.EncodedKeySpec {
+    ctor public PKCS8EncodedKeySpec(byte[]);
+    method public final String getFormat();
+  }
+
+  public class PSSParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public PSSParameterSpec(String, String, java.security.spec.AlgorithmParameterSpec, int, int);
+    ctor public PSSParameterSpec(int);
+    method public String getDigestAlgorithm();
+    method public String getMGFAlgorithm();
+    method public java.security.spec.AlgorithmParameterSpec getMGFParameters();
+    method public int getSaltLength();
+    method public int getTrailerField();
+    field public static final java.security.spec.PSSParameterSpec DEFAULT;
+  }
+
+  public class RSAKeyGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public RSAKeyGenParameterSpec(int, java.math.BigInteger);
+    method public int getKeysize();
+    method public java.math.BigInteger getPublicExponent();
+    field public static final java.math.BigInteger F0;
+    field public static final java.math.BigInteger F4;
+  }
+
+  public class RSAMultiPrimePrivateCrtKeySpec extends java.security.spec.RSAPrivateKeySpec {
+    ctor public RSAMultiPrimePrivateCrtKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.security.spec.RSAOtherPrimeInfo[]);
+    method public java.math.BigInteger getCrtCoefficient();
+    method public java.security.spec.RSAOtherPrimeInfo[] getOtherPrimeInfo();
+    method public java.math.BigInteger getPrimeExponentP();
+    method public java.math.BigInteger getPrimeExponentQ();
+    method public java.math.BigInteger getPrimeP();
+    method public java.math.BigInteger getPrimeQ();
+    method public java.math.BigInteger getPublicExponent();
+  }
+
+  public class RSAOtherPrimeInfo {
+    ctor public RSAOtherPrimeInfo(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public final java.math.BigInteger getCrtCoefficient();
+    method public final java.math.BigInteger getExponent();
+    method public final java.math.BigInteger getPrime();
+  }
+
+  public class RSAPrivateCrtKeySpec extends java.security.spec.RSAPrivateKeySpec {
+    ctor public RSAPrivateCrtKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getCrtCoefficient();
+    method public java.math.BigInteger getPrimeExponentP();
+    method public java.math.BigInteger getPrimeExponentQ();
+    method public java.math.BigInteger getPrimeP();
+    method public java.math.BigInteger getPrimeQ();
+    method public java.math.BigInteger getPublicExponent();
+  }
+
+  public class RSAPrivateKeySpec implements java.security.spec.KeySpec {
+    ctor public RSAPrivateKeySpec(java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getModulus();
+    method public java.math.BigInteger getPrivateExponent();
+  }
+
+  public class RSAPublicKeySpec implements java.security.spec.KeySpec {
+    ctor public RSAPublicKeySpec(java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getModulus();
+    method public java.math.BigInteger getPublicExponent();
+  }
+
+  public class X509EncodedKeySpec extends java.security.spec.EncodedKeySpec {
+    ctor public X509EncodedKeySpec(byte[]);
+    method public final String getFormat();
+  }
+
+}
+
+package java.sql {
+
+  public interface Array {
+    method public void free() throws java.sql.SQLException;
+    method public Object getArray() throws java.sql.SQLException;
+    method public Object getArray(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public Object getArray(long, int) throws java.sql.SQLException;
+    method public Object getArray(long, int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public int getBaseType() throws java.sql.SQLException;
+    method public String getBaseTypeName() throws java.sql.SQLException;
+    method public java.sql.ResultSet getResultSet() throws java.sql.SQLException;
+    method public java.sql.ResultSet getResultSet(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public java.sql.ResultSet getResultSet(long, int) throws java.sql.SQLException;
+    method public java.sql.ResultSet getResultSet(long, int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+  }
+
+  public class BatchUpdateException extends java.sql.SQLException {
+    ctor public BatchUpdateException(String, String, int, int[]);
+    ctor public BatchUpdateException(String, String, int[]);
+    ctor public BatchUpdateException(String, int[]);
+    ctor public BatchUpdateException(int[]);
+    ctor public BatchUpdateException();
+    ctor public BatchUpdateException(Throwable);
+    ctor public BatchUpdateException(int[], Throwable);
+    ctor public BatchUpdateException(String, int[], Throwable);
+    ctor public BatchUpdateException(String, String, int[], Throwable);
+    ctor public BatchUpdateException(String, String, int, int[], Throwable);
+    method public int[] getUpdateCounts();
+  }
+
+  public interface Blob {
+    method public void free() throws java.sql.SQLException;
+    method public java.io.InputStream getBinaryStream() throws java.sql.SQLException;
+    method public java.io.InputStream getBinaryStream(long, long) throws java.sql.SQLException;
+    method public byte[] getBytes(long, int) throws java.sql.SQLException;
+    method public long length() throws java.sql.SQLException;
+    method public long position(byte[], long) throws java.sql.SQLException;
+    method public long position(java.sql.Blob, long) throws java.sql.SQLException;
+    method public java.io.OutputStream setBinaryStream(long) throws java.sql.SQLException;
+    method public int setBytes(long, byte[]) throws java.sql.SQLException;
+    method public int setBytes(long, byte[], int, int) throws java.sql.SQLException;
+    method public void truncate(long) throws java.sql.SQLException;
+  }
+
+  public interface CallableStatement extends java.sql.PreparedStatement {
+    method public java.sql.Array getArray(int) throws java.sql.SQLException;
+    method public java.sql.Array getArray(String) throws java.sql.SQLException;
+    method @Deprecated public java.math.BigDecimal getBigDecimal(int, int) throws java.sql.SQLException;
+    method public java.math.BigDecimal getBigDecimal(int) throws java.sql.SQLException;
+    method public java.math.BigDecimal getBigDecimal(String) throws java.sql.SQLException;
+    method public java.sql.Blob getBlob(int) throws java.sql.SQLException;
+    method public java.sql.Blob getBlob(String) throws java.sql.SQLException;
+    method public boolean getBoolean(int) throws java.sql.SQLException;
+    method public boolean getBoolean(String) throws java.sql.SQLException;
+    method public byte getByte(int) throws java.sql.SQLException;
+    method public byte getByte(String) throws java.sql.SQLException;
+    method public byte[] getBytes(int) throws java.sql.SQLException;
+    method public byte[] getBytes(String) throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream(int) throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream(String) throws java.sql.SQLException;
+    method public java.sql.Clob getClob(int) throws java.sql.SQLException;
+    method public java.sql.Clob getClob(String) throws java.sql.SQLException;
+    method public java.sql.Date getDate(int) throws java.sql.SQLException;
+    method public java.sql.Date getDate(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Date getDate(String) throws java.sql.SQLException;
+    method public java.sql.Date getDate(String, java.util.Calendar) throws java.sql.SQLException;
+    method public double getDouble(int) throws java.sql.SQLException;
+    method public double getDouble(String) throws java.sql.SQLException;
+    method public float getFloat(int) throws java.sql.SQLException;
+    method public float getFloat(String) throws java.sql.SQLException;
+    method public int getInt(int) throws java.sql.SQLException;
+    method public int getInt(String) throws java.sql.SQLException;
+    method public long getLong(int) throws java.sql.SQLException;
+    method public long getLong(String) throws java.sql.SQLException;
+    method public java.io.Reader getNCharacterStream(int) throws java.sql.SQLException;
+    method public java.io.Reader getNCharacterStream(String) throws java.sql.SQLException;
+    method public java.sql.NClob getNClob(int) throws java.sql.SQLException;
+    method public java.sql.NClob getNClob(String) throws java.sql.SQLException;
+    method public String getNString(int) throws java.sql.SQLException;
+    method public String getNString(String) throws java.sql.SQLException;
+    method public Object getObject(int) throws java.sql.SQLException;
+    method public Object getObject(int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public Object getObject(String) throws java.sql.SQLException;
+    method public Object getObject(String, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public java.sql.Ref getRef(int) throws java.sql.SQLException;
+    method public java.sql.Ref getRef(String) throws java.sql.SQLException;
+    method public java.sql.RowId getRowId(int) throws java.sql.SQLException;
+    method public java.sql.RowId getRowId(String) throws java.sql.SQLException;
+    method public java.sql.SQLXML getSQLXML(int) throws java.sql.SQLException;
+    method public java.sql.SQLXML getSQLXML(String) throws java.sql.SQLException;
+    method public short getShort(int) throws java.sql.SQLException;
+    method public short getShort(String) throws java.sql.SQLException;
+    method public String getString(int) throws java.sql.SQLException;
+    method public String getString(String) throws java.sql.SQLException;
+    method public java.sql.Time getTime(int) throws java.sql.SQLException;
+    method public java.sql.Time getTime(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Time getTime(String) throws java.sql.SQLException;
+    method public java.sql.Time getTime(String, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(int) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(String) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(String, java.util.Calendar) throws java.sql.SQLException;
+    method public java.net.URL getURL(int) throws java.sql.SQLException;
+    method public java.net.URL getURL(String) throws java.sql.SQLException;
+    method public void registerOutParameter(int, int) throws java.sql.SQLException;
+    method public void registerOutParameter(int, int, int) throws java.sql.SQLException;
+    method public void registerOutParameter(int, int, String) throws java.sql.SQLException;
+    method public void registerOutParameter(String, int) throws java.sql.SQLException;
+    method public void registerOutParameter(String, int, int) throws java.sql.SQLException;
+    method public void registerOutParameter(String, int, String) throws java.sql.SQLException;
+    method public void setAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setAsciiStream(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void setBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setBinaryStream(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBlob(String, java.sql.Blob) throws java.sql.SQLException;
+    method public void setBlob(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBoolean(String, boolean) throws java.sql.SQLException;
+    method public void setByte(String, byte) throws java.sql.SQLException;
+    method public void setBytes(String, byte[]) throws java.sql.SQLException;
+    method public void setCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
+    method public void setCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setClob(String, java.sql.Clob) throws java.sql.SQLException;
+    method public void setClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setDate(String, java.sql.Date) throws java.sql.SQLException;
+    method public void setDate(String, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
+    method public void setDouble(String, double) throws java.sql.SQLException;
+    method public void setFloat(String, float) throws java.sql.SQLException;
+    method public void setInt(String, int) throws java.sql.SQLException;
+    method public void setLong(String, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setNClob(String, java.sql.NClob) throws java.sql.SQLException;
+    method public void setNClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setNString(String, String) throws java.sql.SQLException;
+    method public void setNull(String, int) throws java.sql.SQLException;
+    method public void setNull(String, int, String) throws java.sql.SQLException;
+    method public void setObject(String, Object, int, int) throws java.sql.SQLException;
+    method public void setObject(String, Object, int) throws java.sql.SQLException;
+    method public void setObject(String, Object) throws java.sql.SQLException;
+    method public void setRowId(String, java.sql.RowId) throws java.sql.SQLException;
+    method public void setSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void setShort(String, short) throws java.sql.SQLException;
+    method public void setString(String, String) throws java.sql.SQLException;
+    method public void setTime(String, java.sql.Time) throws java.sql.SQLException;
+    method public void setTime(String, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
+    method public void setTimestamp(String, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
+    method public void setURL(String, java.net.URL) throws java.sql.SQLException;
+    method public boolean wasNull() throws java.sql.SQLException;
+  }
+
+  public enum ClientInfoStatus {
+    enum_constant public static final java.sql.ClientInfoStatus REASON_UNKNOWN;
+    enum_constant public static final java.sql.ClientInfoStatus REASON_UNKNOWN_PROPERTY;
+    enum_constant public static final java.sql.ClientInfoStatus REASON_VALUE_INVALID;
+    enum_constant public static final java.sql.ClientInfoStatus REASON_VALUE_TRUNCATED;
+  }
+
+  public interface Clob {
+    method public void free() throws java.sql.SQLException;
+    method public java.io.InputStream getAsciiStream() throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream() throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream(long, long) throws java.sql.SQLException;
+    method public String getSubString(long, int) throws java.sql.SQLException;
+    method public long length() throws java.sql.SQLException;
+    method public long position(String, long) throws java.sql.SQLException;
+    method public long position(java.sql.Clob, long) throws java.sql.SQLException;
+    method public java.io.OutputStream setAsciiStream(long) throws java.sql.SQLException;
+    method public java.io.Writer setCharacterStream(long) throws java.sql.SQLException;
+    method public int setString(long, String) throws java.sql.SQLException;
+    method public int setString(long, String, int, int) throws java.sql.SQLException;
+    method public void truncate(long) throws java.sql.SQLException;
+  }
+
+  public interface Connection extends java.sql.Wrapper java.lang.AutoCloseable {
+    method public void clearWarnings() throws java.sql.SQLException;
+    method public void close() throws java.sql.SQLException;
+    method public void commit() throws java.sql.SQLException;
+    method public java.sql.Array createArrayOf(String, Object[]) throws java.sql.SQLException;
+    method public java.sql.Blob createBlob() throws java.sql.SQLException;
+    method public java.sql.Clob createClob() throws java.sql.SQLException;
+    method public java.sql.NClob createNClob() throws java.sql.SQLException;
+    method public java.sql.SQLXML createSQLXML() throws java.sql.SQLException;
+    method public java.sql.Statement createStatement() throws java.sql.SQLException;
+    method public java.sql.Statement createStatement(int, int) throws java.sql.SQLException;
+    method public java.sql.Statement createStatement(int, int, int) throws java.sql.SQLException;
+    method public java.sql.Struct createStruct(String, Object[]) throws java.sql.SQLException;
+    method public boolean getAutoCommit() throws java.sql.SQLException;
+    method public String getCatalog() throws java.sql.SQLException;
+    method public String getClientInfo(String) throws java.sql.SQLException;
+    method public java.util.Properties getClientInfo() throws java.sql.SQLException;
+    method public int getHoldability() throws java.sql.SQLException;
+    method public java.sql.DatabaseMetaData getMetaData() throws java.sql.SQLException;
+    method public int getTransactionIsolation() throws java.sql.SQLException;
+    method public java.util.Map<java.lang.String,java.lang.Class<?>> getTypeMap() throws java.sql.SQLException;
+    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
+    method public boolean isClosed() throws java.sql.SQLException;
+    method public boolean isReadOnly() throws java.sql.SQLException;
+    method public boolean isValid(int) throws java.sql.SQLException;
+    method public String nativeSQL(String) throws java.sql.SQLException;
+    method public java.sql.CallableStatement prepareCall(String) throws java.sql.SQLException;
+    method public java.sql.CallableStatement prepareCall(String, int, int) throws java.sql.SQLException;
+    method public java.sql.CallableStatement prepareCall(String, int, int, int) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String, int, int) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String, int, int, int) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String, int) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String, int[]) throws java.sql.SQLException;
+    method public java.sql.PreparedStatement prepareStatement(String, String[]) throws java.sql.SQLException;
+    method public void releaseSavepoint(java.sql.Savepoint) throws java.sql.SQLException;
+    method public void rollback() throws java.sql.SQLException;
+    method public void rollback(java.sql.Savepoint) throws java.sql.SQLException;
+    method public void setAutoCommit(boolean) throws java.sql.SQLException;
+    method public void setCatalog(String) throws java.sql.SQLException;
+    method public void setClientInfo(String, String) throws java.sql.SQLClientInfoException;
+    method public void setClientInfo(java.util.Properties) throws java.sql.SQLClientInfoException;
+    method public void setHoldability(int) throws java.sql.SQLException;
+    method public void setReadOnly(boolean) throws java.sql.SQLException;
+    method public java.sql.Savepoint setSavepoint() throws java.sql.SQLException;
+    method public java.sql.Savepoint setSavepoint(String) throws java.sql.SQLException;
+    method public void setTransactionIsolation(int) throws java.sql.SQLException;
+    method public void setTypeMap(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    field public static final int TRANSACTION_NONE = 0; // 0x0
+    field public static final int TRANSACTION_READ_COMMITTED = 2; // 0x2
+    field public static final int TRANSACTION_READ_UNCOMMITTED = 1; // 0x1
+    field public static final int TRANSACTION_REPEATABLE_READ = 4; // 0x4
+    field public static final int TRANSACTION_SERIALIZABLE = 8; // 0x8
+  }
+
+  public class DataTruncation extends java.sql.SQLWarning {
+    ctor public DataTruncation(int, boolean, boolean, int, int);
+    ctor public DataTruncation(int, boolean, boolean, int, int, Throwable);
+    method public int getDataSize();
+    method public int getIndex();
+    method public boolean getParameter();
+    method public boolean getRead();
+    method public int getTransferSize();
+  }
+
+  public interface DatabaseMetaData extends java.sql.Wrapper {
+    method public boolean allProceduresAreCallable() throws java.sql.SQLException;
+    method public boolean allTablesAreSelectable() throws java.sql.SQLException;
+    method public boolean autoCommitFailureClosesAllResultSets() throws java.sql.SQLException;
+    method public boolean dataDefinitionCausesTransactionCommit() throws java.sql.SQLException;
+    method public boolean dataDefinitionIgnoredInTransactions() throws java.sql.SQLException;
+    method public boolean deletesAreDetected(int) throws java.sql.SQLException;
+    method public boolean doesMaxRowSizeIncludeBlobs() throws java.sql.SQLException;
+    method public java.sql.ResultSet getAttributes(String, String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getBestRowIdentifier(String, String, String, int, boolean) throws java.sql.SQLException;
+    method public String getCatalogSeparator() throws java.sql.SQLException;
+    method public String getCatalogTerm() throws java.sql.SQLException;
+    method public java.sql.ResultSet getCatalogs() throws java.sql.SQLException;
+    method public java.sql.ResultSet getClientInfoProperties() throws java.sql.SQLException;
+    method public java.sql.ResultSet getColumnPrivileges(String, String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getColumns(String, String, String, String) throws java.sql.SQLException;
+    method public java.sql.Connection getConnection() throws java.sql.SQLException;
+    method public java.sql.ResultSet getCrossReference(String, String, String, String, String, String) throws java.sql.SQLException;
+    method public int getDatabaseMajorVersion() throws java.sql.SQLException;
+    method public int getDatabaseMinorVersion() throws java.sql.SQLException;
+    method public String getDatabaseProductName() throws java.sql.SQLException;
+    method public String getDatabaseProductVersion() throws java.sql.SQLException;
+    method public int getDefaultTransactionIsolation() throws java.sql.SQLException;
+    method public int getDriverMajorVersion();
+    method public int getDriverMinorVersion();
+    method public String getDriverName() throws java.sql.SQLException;
+    method public String getDriverVersion() throws java.sql.SQLException;
+    method public java.sql.ResultSet getExportedKeys(String, String, String) throws java.sql.SQLException;
+    method public String getExtraNameCharacters() throws java.sql.SQLException;
+    method public java.sql.ResultSet getFunctionColumns(String, String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getFunctions(String, String, String) throws java.sql.SQLException;
+    method public String getIdentifierQuoteString() throws java.sql.SQLException;
+    method public java.sql.ResultSet getImportedKeys(String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getIndexInfo(String, String, String, boolean, boolean) throws java.sql.SQLException;
+    method public int getJDBCMajorVersion() throws java.sql.SQLException;
+    method public int getJDBCMinorVersion() throws java.sql.SQLException;
+    method public int getMaxBinaryLiteralLength() throws java.sql.SQLException;
+    method public int getMaxCatalogNameLength() throws java.sql.SQLException;
+    method public int getMaxCharLiteralLength() throws java.sql.SQLException;
+    method public int getMaxColumnNameLength() throws java.sql.SQLException;
+    method public int getMaxColumnsInGroupBy() throws java.sql.SQLException;
+    method public int getMaxColumnsInIndex() throws java.sql.SQLException;
+    method public int getMaxColumnsInOrderBy() throws java.sql.SQLException;
+    method public int getMaxColumnsInSelect() throws java.sql.SQLException;
+    method public int getMaxColumnsInTable() throws java.sql.SQLException;
+    method public int getMaxConnections() throws java.sql.SQLException;
+    method public int getMaxCursorNameLength() throws java.sql.SQLException;
+    method public int getMaxIndexLength() throws java.sql.SQLException;
+    method public int getMaxProcedureNameLength() throws java.sql.SQLException;
+    method public int getMaxRowSize() throws java.sql.SQLException;
+    method public int getMaxSchemaNameLength() throws java.sql.SQLException;
+    method public int getMaxStatementLength() throws java.sql.SQLException;
+    method public int getMaxStatements() throws java.sql.SQLException;
+    method public int getMaxTableNameLength() throws java.sql.SQLException;
+    method public int getMaxTablesInSelect() throws java.sql.SQLException;
+    method public int getMaxUserNameLength() throws java.sql.SQLException;
+    method public String getNumericFunctions() throws java.sql.SQLException;
+    method public java.sql.ResultSet getPrimaryKeys(String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getProcedureColumns(String, String, String, String) throws java.sql.SQLException;
+    method public String getProcedureTerm() throws java.sql.SQLException;
+    method public java.sql.ResultSet getProcedures(String, String, String) throws java.sql.SQLException;
+    method public int getResultSetHoldability() throws java.sql.SQLException;
+    method public java.sql.RowIdLifetime getRowIdLifetime() throws java.sql.SQLException;
+    method public String getSQLKeywords() throws java.sql.SQLException;
+    method public int getSQLStateType() throws java.sql.SQLException;
+    method public String getSchemaTerm() throws java.sql.SQLException;
+    method public java.sql.ResultSet getSchemas() throws java.sql.SQLException;
+    method public java.sql.ResultSet getSchemas(String, String) throws java.sql.SQLException;
+    method public String getSearchStringEscape() throws java.sql.SQLException;
+    method public String getStringFunctions() throws java.sql.SQLException;
+    method public java.sql.ResultSet getSuperTables(String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getSuperTypes(String, String, String) throws java.sql.SQLException;
+    method public String getSystemFunctions() throws java.sql.SQLException;
+    method public java.sql.ResultSet getTablePrivileges(String, String, String) throws java.sql.SQLException;
+    method public java.sql.ResultSet getTableTypes() throws java.sql.SQLException;
+    method public java.sql.ResultSet getTables(String, String, String, String[]) throws java.sql.SQLException;
+    method public String getTimeDateFunctions() throws java.sql.SQLException;
+    method public java.sql.ResultSet getTypeInfo() throws java.sql.SQLException;
+    method public java.sql.ResultSet getUDTs(String, String, String, int[]) throws java.sql.SQLException;
+    method public String getURL() throws java.sql.SQLException;
+    method public String getUserName() throws java.sql.SQLException;
+    method public java.sql.ResultSet getVersionColumns(String, String, String) throws java.sql.SQLException;
+    method public boolean insertsAreDetected(int) throws java.sql.SQLException;
+    method public boolean isCatalogAtStart() throws java.sql.SQLException;
+    method public boolean isReadOnly() throws java.sql.SQLException;
+    method public boolean locatorsUpdateCopy() throws java.sql.SQLException;
+    method public boolean nullPlusNonNullIsNull() throws java.sql.SQLException;
+    method public boolean nullsAreSortedAtEnd() throws java.sql.SQLException;
+    method public boolean nullsAreSortedAtStart() throws java.sql.SQLException;
+    method public boolean nullsAreSortedHigh() throws java.sql.SQLException;
+    method public boolean nullsAreSortedLow() throws java.sql.SQLException;
+    method public boolean othersDeletesAreVisible(int) throws java.sql.SQLException;
+    method public boolean othersInsertsAreVisible(int) throws java.sql.SQLException;
+    method public boolean othersUpdatesAreVisible(int) throws java.sql.SQLException;
+    method public boolean ownDeletesAreVisible(int) throws java.sql.SQLException;
+    method public boolean ownInsertsAreVisible(int) throws java.sql.SQLException;
+    method public boolean ownUpdatesAreVisible(int) throws java.sql.SQLException;
+    method public boolean storesLowerCaseIdentifiers() throws java.sql.SQLException;
+    method public boolean storesLowerCaseQuotedIdentifiers() throws java.sql.SQLException;
+    method public boolean storesMixedCaseIdentifiers() throws java.sql.SQLException;
+    method public boolean storesMixedCaseQuotedIdentifiers() throws java.sql.SQLException;
+    method public boolean storesUpperCaseIdentifiers() throws java.sql.SQLException;
+    method public boolean storesUpperCaseQuotedIdentifiers() throws java.sql.SQLException;
+    method public boolean supportsANSI92EntryLevelSQL() throws java.sql.SQLException;
+    method public boolean supportsANSI92FullSQL() throws java.sql.SQLException;
+    method public boolean supportsANSI92IntermediateSQL() throws java.sql.SQLException;
+    method public boolean supportsAlterTableWithAddColumn() throws java.sql.SQLException;
+    method public boolean supportsAlterTableWithDropColumn() throws java.sql.SQLException;
+    method public boolean supportsBatchUpdates() throws java.sql.SQLException;
+    method public boolean supportsCatalogsInDataManipulation() throws java.sql.SQLException;
+    method public boolean supportsCatalogsInIndexDefinitions() throws java.sql.SQLException;
+    method public boolean supportsCatalogsInPrivilegeDefinitions() throws java.sql.SQLException;
+    method public boolean supportsCatalogsInProcedureCalls() throws java.sql.SQLException;
+    method public boolean supportsCatalogsInTableDefinitions() throws java.sql.SQLException;
+    method public boolean supportsColumnAliasing() throws java.sql.SQLException;
+    method public boolean supportsConvert() throws java.sql.SQLException;
+    method public boolean supportsConvert(int, int) throws java.sql.SQLException;
+    method public boolean supportsCoreSQLGrammar() throws java.sql.SQLException;
+    method public boolean supportsCorrelatedSubqueries() throws java.sql.SQLException;
+    method public boolean supportsDataDefinitionAndDataManipulationTransactions() throws java.sql.SQLException;
+    method public boolean supportsDataManipulationTransactionsOnly() throws java.sql.SQLException;
+    method public boolean supportsDifferentTableCorrelationNames() throws java.sql.SQLException;
+    method public boolean supportsExpressionsInOrderBy() throws java.sql.SQLException;
+    method public boolean supportsExtendedSQLGrammar() throws java.sql.SQLException;
+    method public boolean supportsFullOuterJoins() throws java.sql.SQLException;
+    method public boolean supportsGetGeneratedKeys() throws java.sql.SQLException;
+    method public boolean supportsGroupBy() throws java.sql.SQLException;
+    method public boolean supportsGroupByBeyondSelect() throws java.sql.SQLException;
+    method public boolean supportsGroupByUnrelated() throws java.sql.SQLException;
+    method public boolean supportsIntegrityEnhancementFacility() throws java.sql.SQLException;
+    method public boolean supportsLikeEscapeClause() throws java.sql.SQLException;
+    method public boolean supportsLimitedOuterJoins() throws java.sql.SQLException;
+    method public boolean supportsMinimumSQLGrammar() throws java.sql.SQLException;
+    method public boolean supportsMixedCaseIdentifiers() throws java.sql.SQLException;
+    method public boolean supportsMixedCaseQuotedIdentifiers() throws java.sql.SQLException;
+    method public boolean supportsMultipleOpenResults() throws java.sql.SQLException;
+    method public boolean supportsMultipleResultSets() throws java.sql.SQLException;
+    method public boolean supportsMultipleTransactions() throws java.sql.SQLException;
+    method public boolean supportsNamedParameters() throws java.sql.SQLException;
+    method public boolean supportsNonNullableColumns() throws java.sql.SQLException;
+    method public boolean supportsOpenCursorsAcrossCommit() throws java.sql.SQLException;
+    method public boolean supportsOpenCursorsAcrossRollback() throws java.sql.SQLException;
+    method public boolean supportsOpenStatementsAcrossCommit() throws java.sql.SQLException;
+    method public boolean supportsOpenStatementsAcrossRollback() throws java.sql.SQLException;
+    method public boolean supportsOrderByUnrelated() throws java.sql.SQLException;
+    method public boolean supportsOuterJoins() throws java.sql.SQLException;
+    method public boolean supportsPositionedDelete() throws java.sql.SQLException;
+    method public boolean supportsPositionedUpdate() throws java.sql.SQLException;
+    method public boolean supportsResultSetConcurrency(int, int) throws java.sql.SQLException;
+    method public boolean supportsResultSetHoldability(int) throws java.sql.SQLException;
+    method public boolean supportsResultSetType(int) throws java.sql.SQLException;
+    method public boolean supportsSavepoints() throws java.sql.SQLException;
+    method public boolean supportsSchemasInDataManipulation() throws java.sql.SQLException;
+    method public boolean supportsSchemasInIndexDefinitions() throws java.sql.SQLException;
+    method public boolean supportsSchemasInPrivilegeDefinitions() throws java.sql.SQLException;
+    method public boolean supportsSchemasInProcedureCalls() throws java.sql.SQLException;
+    method public boolean supportsSchemasInTableDefinitions() throws java.sql.SQLException;
+    method public boolean supportsSelectForUpdate() throws java.sql.SQLException;
+    method public boolean supportsStatementPooling() throws java.sql.SQLException;
+    method public boolean supportsStoredFunctionsUsingCallSyntax() throws java.sql.SQLException;
+    method public boolean supportsStoredProcedures() throws java.sql.SQLException;
+    method public boolean supportsSubqueriesInComparisons() throws java.sql.SQLException;
+    method public boolean supportsSubqueriesInExists() throws java.sql.SQLException;
+    method public boolean supportsSubqueriesInIns() throws java.sql.SQLException;
+    method public boolean supportsSubqueriesInQuantifieds() throws java.sql.SQLException;
+    method public boolean supportsTableCorrelationNames() throws java.sql.SQLException;
+    method public boolean supportsTransactionIsolationLevel(int) throws java.sql.SQLException;
+    method public boolean supportsTransactions() throws java.sql.SQLException;
+    method public boolean supportsUnion() throws java.sql.SQLException;
+    method public boolean supportsUnionAll() throws java.sql.SQLException;
+    method public boolean updatesAreDetected(int) throws java.sql.SQLException;
+    method public boolean usesLocalFilePerTable() throws java.sql.SQLException;
+    method public boolean usesLocalFiles() throws java.sql.SQLException;
+    field public static final short attributeNoNulls = 0; // 0x0
+    field public static final short attributeNullable = 1; // 0x1
+    field public static final short attributeNullableUnknown = 2; // 0x2
+    field public static final int bestRowNotPseudo = 1; // 0x1
+    field public static final int bestRowPseudo = 2; // 0x2
+    field public static final int bestRowSession = 2; // 0x2
+    field public static final int bestRowTemporary = 0; // 0x0
+    field public static final int bestRowTransaction = 1; // 0x1
+    field public static final int bestRowUnknown = 0; // 0x0
+    field public static final int columnNoNulls = 0; // 0x0
+    field public static final int columnNullable = 1; // 0x1
+    field public static final int columnNullableUnknown = 2; // 0x2
+    field public static final int functionColumnIn = 1; // 0x1
+    field public static final int functionColumnInOut = 2; // 0x2
+    field public static final int functionColumnOut = 3; // 0x3
+    field public static final int functionColumnResult = 5; // 0x5
+    field public static final int functionColumnUnknown = 0; // 0x0
+    field public static final int functionNoNulls = 0; // 0x0
+    field public static final int functionNoTable = 1; // 0x1
+    field public static final int functionNullable = 1; // 0x1
+    field public static final int functionNullableUnknown = 2; // 0x2
+    field public static final int functionResultUnknown = 0; // 0x0
+    field public static final int functionReturn = 4; // 0x4
+    field public static final int functionReturnsTable = 2; // 0x2
+    field public static final int importedKeyCascade = 0; // 0x0
+    field public static final int importedKeyInitiallyDeferred = 5; // 0x5
+    field public static final int importedKeyInitiallyImmediate = 6; // 0x6
+    field public static final int importedKeyNoAction = 3; // 0x3
+    field public static final int importedKeyNotDeferrable = 7; // 0x7
+    field public static final int importedKeyRestrict = 1; // 0x1
+    field public static final int importedKeySetDefault = 4; // 0x4
+    field public static final int importedKeySetNull = 2; // 0x2
+    field public static final int procedureColumnIn = 1; // 0x1
+    field public static final int procedureColumnInOut = 2; // 0x2
+    field public static final int procedureColumnOut = 4; // 0x4
+    field public static final int procedureColumnResult = 3; // 0x3
+    field public static final int procedureColumnReturn = 5; // 0x5
+    field public static final int procedureColumnUnknown = 0; // 0x0
+    field public static final int procedureNoNulls = 0; // 0x0
+    field public static final int procedureNoResult = 1; // 0x1
+    field public static final int procedureNullable = 1; // 0x1
+    field public static final int procedureNullableUnknown = 2; // 0x2
+    field public static final int procedureResultUnknown = 0; // 0x0
+    field public static final int procedureReturnsResult = 2; // 0x2
+    field public static final int sqlStateSQL = 2; // 0x2
+    field public static final int sqlStateSQL99 = 2; // 0x2
+    field public static final int sqlStateXOpen = 1; // 0x1
+    field public static final short tableIndexClustered = 1; // 0x1
+    field public static final short tableIndexHashed = 2; // 0x2
+    field public static final short tableIndexOther = 3; // 0x3
+    field public static final short tableIndexStatistic = 0; // 0x0
+    field public static final int typeNoNulls = 0; // 0x0
+    field public static final int typeNullable = 1; // 0x1
+    field public static final int typeNullableUnknown = 2; // 0x2
+    field public static final int typePredBasic = 2; // 0x2
+    field public static final int typePredChar = 1; // 0x1
+    field public static final int typePredNone = 0; // 0x0
+    field public static final int typeSearchable = 3; // 0x3
+    field public static final int versionColumnNotPseudo = 1; // 0x1
+    field public static final int versionColumnPseudo = 2; // 0x2
+    field public static final int versionColumnUnknown = 0; // 0x0
+  }
+
+  public class Date extends java.util.Date {
+    ctor @Deprecated public Date(int, int, int);
+    ctor public Date(long);
+    method public static java.sql.Date valueOf(String);
+  }
+
+  public interface Driver {
+    method public boolean acceptsURL(String) throws java.sql.SQLException;
+    method public java.sql.Connection connect(String, java.util.Properties) throws java.sql.SQLException;
+    method public int getMajorVersion();
+    method public int getMinorVersion();
+    method public java.sql.DriverPropertyInfo[] getPropertyInfo(String, java.util.Properties) throws java.sql.SQLException;
+    method public boolean jdbcCompliant();
+  }
+
+  public class DriverManager {
+    method public static void deregisterDriver(java.sql.Driver) throws java.sql.SQLException;
+    method public static java.sql.Connection getConnection(String, java.util.Properties) throws java.sql.SQLException;
+    method public static java.sql.Connection getConnection(String, String, String) throws java.sql.SQLException;
+    method public static java.sql.Connection getConnection(String) throws java.sql.SQLException;
+    method public static java.sql.Driver getDriver(String) throws java.sql.SQLException;
+    method public static java.util.Enumeration<java.sql.Driver> getDrivers();
+    method @Deprecated public static java.io.PrintStream getLogStream();
+    method public static java.io.PrintWriter getLogWriter();
+    method public static int getLoginTimeout();
+    method public static void println(String);
+    method public static void registerDriver(java.sql.Driver) throws java.sql.SQLException;
+    method @Deprecated public static void setLogStream(java.io.PrintStream);
+    method public static void setLogWriter(java.io.PrintWriter);
+    method public static void setLoginTimeout(int);
+  }
+
+  public class DriverPropertyInfo {
+    ctor public DriverPropertyInfo(String, String);
+    field public String[] choices;
+    field public String description;
+    field public String name;
+    field public boolean required;
+    field public String value;
+  }
+
+  public interface NClob extends java.sql.Clob {
+  }
+
+  public interface ParameterMetaData extends java.sql.Wrapper {
+    method public String getParameterClassName(int) throws java.sql.SQLException;
+    method public int getParameterCount() throws java.sql.SQLException;
+    method public int getParameterMode(int) throws java.sql.SQLException;
+    method public int getParameterType(int) throws java.sql.SQLException;
+    method public String getParameterTypeName(int) throws java.sql.SQLException;
+    method public int getPrecision(int) throws java.sql.SQLException;
+    method public int getScale(int) throws java.sql.SQLException;
+    method public int isNullable(int) throws java.sql.SQLException;
+    method public boolean isSigned(int) throws java.sql.SQLException;
+    field public static final int parameterModeIn = 1; // 0x1
+    field public static final int parameterModeInOut = 2; // 0x2
+    field public static final int parameterModeOut = 4; // 0x4
+    field public static final int parameterModeUnknown = 0; // 0x0
+    field public static final int parameterNoNulls = 0; // 0x0
+    field public static final int parameterNullable = 1; // 0x1
+    field public static final int parameterNullableUnknown = 2; // 0x2
+  }
+
+  public interface PreparedStatement extends java.sql.Statement {
+    method public void addBatch() throws java.sql.SQLException;
+    method public void clearParameters() throws java.sql.SQLException;
+    method public boolean execute() throws java.sql.SQLException;
+    method public java.sql.ResultSet executeQuery() throws java.sql.SQLException;
+    method public int executeUpdate() throws java.sql.SQLException;
+    method public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException;
+    method public java.sql.ParameterMetaData getParameterMetaData() throws java.sql.SQLException;
+    method public void setArray(int, java.sql.Array) throws java.sql.SQLException;
+    method public void setAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setAsciiStream(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void setBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setBinaryStream(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBlob(int, java.sql.Blob) throws java.sql.SQLException;
+    method public void setBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBlob(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBoolean(int, boolean) throws java.sql.SQLException;
+    method public void setByte(int, byte) throws java.sql.SQLException;
+    method public void setBytes(int, byte[]) throws java.sql.SQLException;
+    method public void setCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
+    method public void setCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setClob(int, java.sql.Clob) throws java.sql.SQLException;
+    method public void setClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setDate(int, java.sql.Date) throws java.sql.SQLException;
+    method public void setDate(int, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
+    method public void setDouble(int, double) throws java.sql.SQLException;
+    method public void setFloat(int, float) throws java.sql.SQLException;
+    method public void setInt(int, int) throws java.sql.SQLException;
+    method public void setLong(int, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setNClob(int, java.sql.NClob) throws java.sql.SQLException;
+    method public void setNClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setNString(int, String) throws java.sql.SQLException;
+    method public void setNull(int, int) throws java.sql.SQLException;
+    method public void setNull(int, int, String) throws java.sql.SQLException;
+    method public void setObject(int, Object, int) throws java.sql.SQLException;
+    method public void setObject(int, Object) throws java.sql.SQLException;
+    method public void setObject(int, Object, int, int) throws java.sql.SQLException;
+    method public void setRef(int, java.sql.Ref) throws java.sql.SQLException;
+    method public void setRowId(int, java.sql.RowId) throws java.sql.SQLException;
+    method public void setSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void setShort(int, short) throws java.sql.SQLException;
+    method public void setString(int, String) throws java.sql.SQLException;
+    method public void setTime(int, java.sql.Time) throws java.sql.SQLException;
+    method public void setTime(int, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
+    method public void setTimestamp(int, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
+    method public void setURL(int, java.net.URL) throws java.sql.SQLException;
+    method @Deprecated public void setUnicodeStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+  }
+
+  public interface Ref {
+    method public String getBaseTypeName() throws java.sql.SQLException;
+    method public Object getObject(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public Object getObject() throws java.sql.SQLException;
+    method public void setObject(Object) throws java.sql.SQLException;
+  }
+
+  public interface ResultSet extends java.sql.Wrapper java.lang.AutoCloseable {
+    method public boolean absolute(int) throws java.sql.SQLException;
+    method public void afterLast() throws java.sql.SQLException;
+    method public void beforeFirst() throws java.sql.SQLException;
+    method public void cancelRowUpdates() throws java.sql.SQLException;
+    method public void clearWarnings() throws java.sql.SQLException;
+    method public void close() throws java.sql.SQLException;
+    method public void deleteRow() throws java.sql.SQLException;
+    method public int findColumn(String) throws java.sql.SQLException;
+    method public boolean first() throws java.sql.SQLException;
+    method public java.sql.Array getArray(int) throws java.sql.SQLException;
+    method public java.sql.Array getArray(String) throws java.sql.SQLException;
+    method public java.io.InputStream getAsciiStream(int) throws java.sql.SQLException;
+    method public java.io.InputStream getAsciiStream(String) throws java.sql.SQLException;
+    method @Deprecated public java.math.BigDecimal getBigDecimal(int, int) throws java.sql.SQLException;
+    method @Deprecated public java.math.BigDecimal getBigDecimal(String, int) throws java.sql.SQLException;
+    method public java.math.BigDecimal getBigDecimal(int) throws java.sql.SQLException;
+    method public java.math.BigDecimal getBigDecimal(String) throws java.sql.SQLException;
+    method public java.io.InputStream getBinaryStream(int) throws java.sql.SQLException;
+    method public java.io.InputStream getBinaryStream(String) throws java.sql.SQLException;
+    method public java.sql.Blob getBlob(int) throws java.sql.SQLException;
+    method public java.sql.Blob getBlob(String) throws java.sql.SQLException;
+    method public boolean getBoolean(int) throws java.sql.SQLException;
+    method public boolean getBoolean(String) throws java.sql.SQLException;
+    method public byte getByte(int) throws java.sql.SQLException;
+    method public byte getByte(String) throws java.sql.SQLException;
+    method public byte[] getBytes(int) throws java.sql.SQLException;
+    method public byte[] getBytes(String) throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream(int) throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream(String) throws java.sql.SQLException;
+    method public java.sql.Clob getClob(int) throws java.sql.SQLException;
+    method public java.sql.Clob getClob(String) throws java.sql.SQLException;
+    method public int getConcurrency() throws java.sql.SQLException;
+    method public String getCursorName() throws java.sql.SQLException;
+    method public java.sql.Date getDate(int) throws java.sql.SQLException;
+    method public java.sql.Date getDate(String) throws java.sql.SQLException;
+    method public java.sql.Date getDate(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Date getDate(String, java.util.Calendar) throws java.sql.SQLException;
+    method public double getDouble(int) throws java.sql.SQLException;
+    method public double getDouble(String) throws java.sql.SQLException;
+    method public int getFetchDirection() throws java.sql.SQLException;
+    method public int getFetchSize() throws java.sql.SQLException;
+    method public float getFloat(int) throws java.sql.SQLException;
+    method public float getFloat(String) throws java.sql.SQLException;
+    method public int getHoldability() throws java.sql.SQLException;
+    method public int getInt(int) throws java.sql.SQLException;
+    method public int getInt(String) throws java.sql.SQLException;
+    method public long getLong(int) throws java.sql.SQLException;
+    method public long getLong(String) throws java.sql.SQLException;
+    method public java.sql.ResultSetMetaData getMetaData() throws java.sql.SQLException;
+    method public java.io.Reader getNCharacterStream(int) throws java.sql.SQLException;
+    method public java.io.Reader getNCharacterStream(String) throws java.sql.SQLException;
+    method public java.sql.NClob getNClob(int) throws java.sql.SQLException;
+    method public java.sql.NClob getNClob(String) throws java.sql.SQLException;
+    method public String getNString(int) throws java.sql.SQLException;
+    method public String getNString(String) throws java.sql.SQLException;
+    method public Object getObject(int) throws java.sql.SQLException;
+    method public Object getObject(String) throws java.sql.SQLException;
+    method public Object getObject(int, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public Object getObject(String, java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public java.sql.Ref getRef(int) throws java.sql.SQLException;
+    method public java.sql.Ref getRef(String) throws java.sql.SQLException;
+    method public int getRow() throws java.sql.SQLException;
+    method public java.sql.RowId getRowId(int) throws java.sql.SQLException;
+    method public java.sql.RowId getRowId(String) throws java.sql.SQLException;
+    method public java.sql.SQLXML getSQLXML(int) throws java.sql.SQLException;
+    method public java.sql.SQLXML getSQLXML(String) throws java.sql.SQLException;
+    method public short getShort(int) throws java.sql.SQLException;
+    method public short getShort(String) throws java.sql.SQLException;
+    method public java.sql.Statement getStatement() throws java.sql.SQLException;
+    method public String getString(int) throws java.sql.SQLException;
+    method public String getString(String) throws java.sql.SQLException;
+    method public java.sql.Time getTime(int) throws java.sql.SQLException;
+    method public java.sql.Time getTime(String) throws java.sql.SQLException;
+    method public java.sql.Time getTime(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Time getTime(String, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(int) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(String) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(int, java.util.Calendar) throws java.sql.SQLException;
+    method public java.sql.Timestamp getTimestamp(String, java.util.Calendar) throws java.sql.SQLException;
+    method public int getType() throws java.sql.SQLException;
+    method public java.net.URL getURL(int) throws java.sql.SQLException;
+    method public java.net.URL getURL(String) throws java.sql.SQLException;
+    method @Deprecated public java.io.InputStream getUnicodeStream(int) throws java.sql.SQLException;
+    method @Deprecated public java.io.InputStream getUnicodeStream(String) throws java.sql.SQLException;
+    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
+    method public void insertRow() throws java.sql.SQLException;
+    method public boolean isAfterLast() throws java.sql.SQLException;
+    method public boolean isBeforeFirst() throws java.sql.SQLException;
+    method public boolean isClosed() throws java.sql.SQLException;
+    method public boolean isFirst() throws java.sql.SQLException;
+    method public boolean isLast() throws java.sql.SQLException;
+    method public boolean last() throws java.sql.SQLException;
+    method public void moveToCurrentRow() throws java.sql.SQLException;
+    method public void moveToInsertRow() throws java.sql.SQLException;
+    method public boolean next() throws java.sql.SQLException;
+    method public boolean previous() throws java.sql.SQLException;
+    method public void refreshRow() throws java.sql.SQLException;
+    method public boolean relative(int) throws java.sql.SQLException;
+    method public boolean rowDeleted() throws java.sql.SQLException;
+    method public boolean rowInserted() throws java.sql.SQLException;
+    method public boolean rowUpdated() throws java.sql.SQLException;
+    method public void setFetchDirection(int) throws java.sql.SQLException;
+    method public void setFetchSize(int) throws java.sql.SQLException;
+    method public void updateArray(int, java.sql.Array) throws java.sql.SQLException;
+    method public void updateArray(String, java.sql.Array) throws java.sql.SQLException;
+    method public void updateAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void updateAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void updateAsciiStream(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateAsciiStream(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void updateBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void updateBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void updateBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void updateBinaryStream(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateBinaryStream(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateBlob(int, java.sql.Blob) throws java.sql.SQLException;
+    method public void updateBlob(String, java.sql.Blob) throws java.sql.SQLException;
+    method public void updateBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void updateBlob(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateBlob(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void updateBoolean(int, boolean) throws java.sql.SQLException;
+    method public void updateBoolean(String, boolean) throws java.sql.SQLException;
+    method public void updateByte(int, byte) throws java.sql.SQLException;
+    method public void updateByte(String, byte) throws java.sql.SQLException;
+    method public void updateBytes(int, byte[]) throws java.sql.SQLException;
+    method public void updateBytes(String, byte[]) throws java.sql.SQLException;
+    method public void updateCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
+    method public void updateCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
+    method public void updateCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void updateCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void updateClob(int, java.sql.Clob) throws java.sql.SQLException;
+    method public void updateClob(String, java.sql.Clob) throws java.sql.SQLException;
+    method public void updateClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void updateClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void updateDate(int, java.sql.Date) throws java.sql.SQLException;
+    method public void updateDate(String, java.sql.Date) throws java.sql.SQLException;
+    method public void updateDouble(int, double) throws java.sql.SQLException;
+    method public void updateDouble(String, double) throws java.sql.SQLException;
+    method public void updateFloat(int, float) throws java.sql.SQLException;
+    method public void updateFloat(String, float) throws java.sql.SQLException;
+    method public void updateInt(int, int) throws java.sql.SQLException;
+    method public void updateInt(String, int) throws java.sql.SQLException;
+    method public void updateLong(int, long) throws java.sql.SQLException;
+    method public void updateLong(String, long) throws java.sql.SQLException;
+    method public void updateNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void updateNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void updateNClob(int, java.sql.NClob) throws java.sql.SQLException;
+    method public void updateNClob(String, java.sql.NClob) throws java.sql.SQLException;
+    method public void updateNClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateNClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void updateNClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void updateNClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void updateNString(int, String) throws java.sql.SQLException;
+    method public void updateNString(String, String) throws java.sql.SQLException;
+    method public void updateNull(int) throws java.sql.SQLException;
+    method public void updateNull(String) throws java.sql.SQLException;
+    method public void updateObject(int, Object, int) throws java.sql.SQLException;
+    method public void updateObject(int, Object) throws java.sql.SQLException;
+    method public void updateObject(String, Object, int) throws java.sql.SQLException;
+    method public void updateObject(String, Object) throws java.sql.SQLException;
+    method public void updateRef(int, java.sql.Ref) throws java.sql.SQLException;
+    method public void updateRef(String, java.sql.Ref) throws java.sql.SQLException;
+    method public void updateRow() throws java.sql.SQLException;
+    method public void updateRowId(int, java.sql.RowId) throws java.sql.SQLException;
+    method public void updateRowId(String, java.sql.RowId) throws java.sql.SQLException;
+    method public void updateSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void updateSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void updateShort(int, short) throws java.sql.SQLException;
+    method public void updateShort(String, short) throws java.sql.SQLException;
+    method public void updateString(int, String) throws java.sql.SQLException;
+    method public void updateString(String, String) throws java.sql.SQLException;
+    method public void updateTime(int, java.sql.Time) throws java.sql.SQLException;
+    method public void updateTime(String, java.sql.Time) throws java.sql.SQLException;
+    method public void updateTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
+    method public void updateTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
+    method public boolean wasNull() throws java.sql.SQLException;
+    field public static final int CLOSE_CURSORS_AT_COMMIT = 2; // 0x2
+    field public static final int CONCUR_READ_ONLY = 1007; // 0x3ef
+    field public static final int CONCUR_UPDATABLE = 1008; // 0x3f0
+    field public static final int FETCH_FORWARD = 1000; // 0x3e8
+    field public static final int FETCH_REVERSE = 1001; // 0x3e9
+    field public static final int FETCH_UNKNOWN = 1002; // 0x3ea
+    field public static final int HOLD_CURSORS_OVER_COMMIT = 1; // 0x1
+    field public static final int TYPE_FORWARD_ONLY = 1003; // 0x3eb
+    field public static final int TYPE_SCROLL_INSENSITIVE = 1004; // 0x3ec
+    field public static final int TYPE_SCROLL_SENSITIVE = 1005; // 0x3ed
+  }
+
+  public interface ResultSetMetaData extends java.sql.Wrapper {
+    method public String getCatalogName(int) throws java.sql.SQLException;
+    method public String getColumnClassName(int) throws java.sql.SQLException;
+    method public int getColumnCount() throws java.sql.SQLException;
+    method public int getColumnDisplaySize(int) throws java.sql.SQLException;
+    method public String getColumnLabel(int) throws java.sql.SQLException;
+    method public String getColumnName(int) throws java.sql.SQLException;
+    method public int getColumnType(int) throws java.sql.SQLException;
+    method public String getColumnTypeName(int) throws java.sql.SQLException;
+    method public int getPrecision(int) throws java.sql.SQLException;
+    method public int getScale(int) throws java.sql.SQLException;
+    method public String getSchemaName(int) throws java.sql.SQLException;
+    method public String getTableName(int) throws java.sql.SQLException;
+    method public boolean isAutoIncrement(int) throws java.sql.SQLException;
+    method public boolean isCaseSensitive(int) throws java.sql.SQLException;
+    method public boolean isCurrency(int) throws java.sql.SQLException;
+    method public boolean isDefinitelyWritable(int) throws java.sql.SQLException;
+    method public int isNullable(int) throws java.sql.SQLException;
+    method public boolean isReadOnly(int) throws java.sql.SQLException;
+    method public boolean isSearchable(int) throws java.sql.SQLException;
+    method public boolean isSigned(int) throws java.sql.SQLException;
+    method public boolean isWritable(int) throws java.sql.SQLException;
+    field public static final int columnNoNulls = 0; // 0x0
+    field public static final int columnNullable = 1; // 0x1
+    field public static final int columnNullableUnknown = 2; // 0x2
+  }
+
+  public interface RowId {
+    method public boolean equals(Object);
+    method public byte[] getBytes();
+    method public int hashCode();
+    method public String toString();
+  }
+
+  public enum RowIdLifetime {
+    enum_constant public static final java.sql.RowIdLifetime ROWID_UNSUPPORTED;
+    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_FOREVER;
+    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_OTHER;
+    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_SESSION;
+    enum_constant public static final java.sql.RowIdLifetime ROWID_VALID_TRANSACTION;
+  }
+
+  public class SQLClientInfoException extends java.sql.SQLException {
+    ctor public SQLClientInfoException();
+    ctor public SQLClientInfoException(java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
+    ctor public SQLClientInfoException(java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
+    ctor public SQLClientInfoException(String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
+    ctor public SQLClientInfoException(String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
+    ctor public SQLClientInfoException(String, String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
+    ctor public SQLClientInfoException(String, String, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
+    ctor public SQLClientInfoException(String, String, int, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>);
+    ctor public SQLClientInfoException(String, String, int, java.util.Map<java.lang.String,java.sql.ClientInfoStatus>, Throwable);
+    method public java.util.Map<java.lang.String,java.sql.ClientInfoStatus> getFailedProperties();
+  }
+
+  public interface SQLData {
+    method public String getSQLTypeName() throws java.sql.SQLException;
+    method public void readSQL(java.sql.SQLInput, String) throws java.sql.SQLException;
+    method public void writeSQL(java.sql.SQLOutput) throws java.sql.SQLException;
+  }
+
+  public class SQLDataException extends java.sql.SQLNonTransientException {
+    ctor public SQLDataException();
+    ctor public SQLDataException(String);
+    ctor public SQLDataException(String, String);
+    ctor public SQLDataException(String, String, int);
+    ctor public SQLDataException(Throwable);
+    ctor public SQLDataException(String, Throwable);
+    ctor public SQLDataException(String, String, Throwable);
+    ctor public SQLDataException(String, String, int, Throwable);
+  }
+
+  public class SQLException extends java.lang.Exception implements java.lang.Iterable<java.lang.Throwable> {
+    ctor public SQLException(String, String, int);
+    ctor public SQLException(String, String);
+    ctor public SQLException(String);
+    ctor public SQLException();
+    ctor public SQLException(Throwable);
+    ctor public SQLException(String, Throwable);
+    ctor public SQLException(String, String, Throwable);
+    ctor public SQLException(String, String, int, Throwable);
+    method public int getErrorCode();
+    method public java.sql.SQLException getNextException();
+    method public String getSQLState();
+    method public java.util.Iterator<java.lang.Throwable> iterator();
+    method public void setNextException(java.sql.SQLException);
+  }
+
+  public class SQLFeatureNotSupportedException extends java.sql.SQLNonTransientException {
+    ctor public SQLFeatureNotSupportedException();
+    ctor public SQLFeatureNotSupportedException(String);
+    ctor public SQLFeatureNotSupportedException(String, String);
+    ctor public SQLFeatureNotSupportedException(String, String, int);
+    ctor public SQLFeatureNotSupportedException(Throwable);
+    ctor public SQLFeatureNotSupportedException(String, Throwable);
+    ctor public SQLFeatureNotSupportedException(String, String, Throwable);
+    ctor public SQLFeatureNotSupportedException(String, String, int, Throwable);
+  }
+
+  public interface SQLInput {
+    method public java.sql.Array readArray() throws java.sql.SQLException;
+    method public java.io.InputStream readAsciiStream() throws java.sql.SQLException;
+    method public java.math.BigDecimal readBigDecimal() throws java.sql.SQLException;
+    method public java.io.InputStream readBinaryStream() throws java.sql.SQLException;
+    method public java.sql.Blob readBlob() throws java.sql.SQLException;
+    method public boolean readBoolean() throws java.sql.SQLException;
+    method public byte readByte() throws java.sql.SQLException;
+    method public byte[] readBytes() throws java.sql.SQLException;
+    method public java.io.Reader readCharacterStream() throws java.sql.SQLException;
+    method public java.sql.Clob readClob() throws java.sql.SQLException;
+    method public java.sql.Date readDate() throws java.sql.SQLException;
+    method public double readDouble() throws java.sql.SQLException;
+    method public float readFloat() throws java.sql.SQLException;
+    method public int readInt() throws java.sql.SQLException;
+    method public long readLong() throws java.sql.SQLException;
+    method public java.sql.NClob readNClob() throws java.sql.SQLException;
+    method public String readNString() throws java.sql.SQLException;
+    method public Object readObject() throws java.sql.SQLException;
+    method public java.sql.Ref readRef() throws java.sql.SQLException;
+    method public java.sql.RowId readRowId() throws java.sql.SQLException;
+    method public java.sql.SQLXML readSQLXML() throws java.sql.SQLException;
+    method public short readShort() throws java.sql.SQLException;
+    method public String readString() throws java.sql.SQLException;
+    method public java.sql.Time readTime() throws java.sql.SQLException;
+    method public java.sql.Timestamp readTimestamp() throws java.sql.SQLException;
+    method public java.net.URL readURL() throws java.sql.SQLException;
+    method public boolean wasNull() throws java.sql.SQLException;
+  }
+
+  public class SQLIntegrityConstraintViolationException extends java.sql.SQLNonTransientException {
+    ctor public SQLIntegrityConstraintViolationException();
+    ctor public SQLIntegrityConstraintViolationException(String);
+    ctor public SQLIntegrityConstraintViolationException(String, String);
+    ctor public SQLIntegrityConstraintViolationException(String, String, int);
+    ctor public SQLIntegrityConstraintViolationException(Throwable);
+    ctor public SQLIntegrityConstraintViolationException(String, Throwable);
+    ctor public SQLIntegrityConstraintViolationException(String, String, Throwable);
+    ctor public SQLIntegrityConstraintViolationException(String, String, int, Throwable);
+  }
+
+  public class SQLInvalidAuthorizationSpecException extends java.sql.SQLNonTransientException {
+    ctor public SQLInvalidAuthorizationSpecException();
+    ctor public SQLInvalidAuthorizationSpecException(String);
+    ctor public SQLInvalidAuthorizationSpecException(String, String);
+    ctor public SQLInvalidAuthorizationSpecException(String, String, int);
+    ctor public SQLInvalidAuthorizationSpecException(Throwable);
+    ctor public SQLInvalidAuthorizationSpecException(String, Throwable);
+    ctor public SQLInvalidAuthorizationSpecException(String, String, Throwable);
+    ctor public SQLInvalidAuthorizationSpecException(String, String, int, Throwable);
+  }
+
+  public class SQLNonTransientConnectionException extends java.sql.SQLNonTransientException {
+    ctor public SQLNonTransientConnectionException();
+    ctor public SQLNonTransientConnectionException(String);
+    ctor public SQLNonTransientConnectionException(String, String);
+    ctor public SQLNonTransientConnectionException(String, String, int);
+    ctor public SQLNonTransientConnectionException(Throwable);
+    ctor public SQLNonTransientConnectionException(String, Throwable);
+    ctor public SQLNonTransientConnectionException(String, String, Throwable);
+    ctor public SQLNonTransientConnectionException(String, String, int, Throwable);
+  }
+
+  public class SQLNonTransientException extends java.sql.SQLException {
+    ctor public SQLNonTransientException();
+    ctor public SQLNonTransientException(String);
+    ctor public SQLNonTransientException(String, String);
+    ctor public SQLNonTransientException(String, String, int);
+    ctor public SQLNonTransientException(Throwable);
+    ctor public SQLNonTransientException(String, Throwable);
+    ctor public SQLNonTransientException(String, String, Throwable);
+    ctor public SQLNonTransientException(String, String, int, Throwable);
+  }
+
+  public interface SQLOutput {
+    method public void writeArray(java.sql.Array) throws java.sql.SQLException;
+    method public void writeAsciiStream(java.io.InputStream) throws java.sql.SQLException;
+    method public void writeBigDecimal(java.math.BigDecimal) throws java.sql.SQLException;
+    method public void writeBinaryStream(java.io.InputStream) throws java.sql.SQLException;
+    method public void writeBlob(java.sql.Blob) throws java.sql.SQLException;
+    method public void writeBoolean(boolean) throws java.sql.SQLException;
+    method public void writeByte(byte) throws java.sql.SQLException;
+    method public void writeBytes(byte[]) throws java.sql.SQLException;
+    method public void writeCharacterStream(java.io.Reader) throws java.sql.SQLException;
+    method public void writeClob(java.sql.Clob) throws java.sql.SQLException;
+    method public void writeDate(java.sql.Date) throws java.sql.SQLException;
+    method public void writeDouble(double) throws java.sql.SQLException;
+    method public void writeFloat(float) throws java.sql.SQLException;
+    method public void writeInt(int) throws java.sql.SQLException;
+    method public void writeLong(long) throws java.sql.SQLException;
+    method public void writeNClob(java.sql.NClob) throws java.sql.SQLException;
+    method public void writeNString(String) throws java.sql.SQLException;
+    method public void writeObject(java.sql.SQLData) throws java.sql.SQLException;
+    method public void writeRef(java.sql.Ref) throws java.sql.SQLException;
+    method public void writeRowId(java.sql.RowId) throws java.sql.SQLException;
+    method public void writeSQLXML(java.sql.SQLXML) throws java.sql.SQLException;
+    method public void writeShort(short) throws java.sql.SQLException;
+    method public void writeString(String) throws java.sql.SQLException;
+    method public void writeStruct(java.sql.Struct) throws java.sql.SQLException;
+    method public void writeTime(java.sql.Time) throws java.sql.SQLException;
+    method public void writeTimestamp(java.sql.Timestamp) throws java.sql.SQLException;
+    method public void writeURL(java.net.URL) throws java.sql.SQLException;
+  }
+
+  public final class SQLPermission extends java.security.BasicPermission {
+    ctor public SQLPermission(String);
+    ctor public SQLPermission(String, String);
+  }
+
+  public class SQLRecoverableException extends java.sql.SQLException {
+    ctor public SQLRecoverableException();
+    ctor public SQLRecoverableException(String);
+    ctor public SQLRecoverableException(String, String);
+    ctor public SQLRecoverableException(String, String, int);
+    ctor public SQLRecoverableException(Throwable);
+    ctor public SQLRecoverableException(String, Throwable);
+    ctor public SQLRecoverableException(String, String, Throwable);
+    ctor public SQLRecoverableException(String, String, int, Throwable);
+  }
+
+  public class SQLSyntaxErrorException extends java.sql.SQLNonTransientException {
+    ctor public SQLSyntaxErrorException();
+    ctor public SQLSyntaxErrorException(String);
+    ctor public SQLSyntaxErrorException(String, String);
+    ctor public SQLSyntaxErrorException(String, String, int);
+    ctor public SQLSyntaxErrorException(Throwable);
+    ctor public SQLSyntaxErrorException(String, Throwable);
+    ctor public SQLSyntaxErrorException(String, String, Throwable);
+    ctor public SQLSyntaxErrorException(String, String, int, Throwable);
+  }
+
+  public class SQLTimeoutException extends java.sql.SQLTransientException {
+    ctor public SQLTimeoutException();
+    ctor public SQLTimeoutException(String);
+    ctor public SQLTimeoutException(String, String);
+    ctor public SQLTimeoutException(String, String, int);
+    ctor public SQLTimeoutException(Throwable);
+    ctor public SQLTimeoutException(String, Throwable);
+    ctor public SQLTimeoutException(String, String, Throwable);
+    ctor public SQLTimeoutException(String, String, int, Throwable);
+  }
+
+  public class SQLTransactionRollbackException extends java.sql.SQLTransientException {
+    ctor public SQLTransactionRollbackException();
+    ctor public SQLTransactionRollbackException(String);
+    ctor public SQLTransactionRollbackException(String, String);
+    ctor public SQLTransactionRollbackException(String, String, int);
+    ctor public SQLTransactionRollbackException(Throwable);
+    ctor public SQLTransactionRollbackException(String, Throwable);
+    ctor public SQLTransactionRollbackException(String, String, Throwable);
+    ctor public SQLTransactionRollbackException(String, String, int, Throwable);
+  }
+
+  public class SQLTransientConnectionException extends java.sql.SQLTransientException {
+    ctor public SQLTransientConnectionException();
+    ctor public SQLTransientConnectionException(String);
+    ctor public SQLTransientConnectionException(String, String);
+    ctor public SQLTransientConnectionException(String, String, int);
+    ctor public SQLTransientConnectionException(Throwable);
+    ctor public SQLTransientConnectionException(String, Throwable);
+    ctor public SQLTransientConnectionException(String, String, Throwable);
+    ctor public SQLTransientConnectionException(String, String, int, Throwable);
+  }
+
+  public class SQLTransientException extends java.sql.SQLException {
+    ctor public SQLTransientException();
+    ctor public SQLTransientException(String);
+    ctor public SQLTransientException(String, String);
+    ctor public SQLTransientException(String, String, int);
+    ctor public SQLTransientException(Throwable);
+    ctor public SQLTransientException(String, Throwable);
+    ctor public SQLTransientException(String, String, Throwable);
+    ctor public SQLTransientException(String, String, int, Throwable);
+  }
+
+  public class SQLWarning extends java.sql.SQLException {
+    ctor public SQLWarning(String, String, int);
+    ctor public SQLWarning(String, String);
+    ctor public SQLWarning(String);
+    ctor public SQLWarning();
+    ctor public SQLWarning(Throwable);
+    ctor public SQLWarning(String, Throwable);
+    ctor public SQLWarning(String, String, Throwable);
+    ctor public SQLWarning(String, String, int, Throwable);
+    method public java.sql.SQLWarning getNextWarning();
+    method public void setNextWarning(java.sql.SQLWarning);
+  }
+
+  public interface SQLXML {
+    method public void free() throws java.sql.SQLException;
+    method public java.io.InputStream getBinaryStream() throws java.sql.SQLException;
+    method public java.io.Reader getCharacterStream() throws java.sql.SQLException;
+    method public <T extends javax.xml.transform.Source> T getSource(Class<T>) throws java.sql.SQLException;
+    method public String getString() throws java.sql.SQLException;
+    method public java.io.OutputStream setBinaryStream() throws java.sql.SQLException;
+    method public java.io.Writer setCharacterStream() throws java.sql.SQLException;
+    method public <T extends javax.xml.transform.Result> T setResult(Class<T>) throws java.sql.SQLException;
+    method public void setString(String) throws java.sql.SQLException;
+  }
+
+  public interface Savepoint {
+    method public int getSavepointId() throws java.sql.SQLException;
+    method public String getSavepointName() throws java.sql.SQLException;
+  }
+
+  public interface Statement extends java.sql.Wrapper java.lang.AutoCloseable {
+    method public void addBatch(String) throws java.sql.SQLException;
+    method public void cancel() throws java.sql.SQLException;
+    method public void clearBatch() throws java.sql.SQLException;
+    method public void clearWarnings() throws java.sql.SQLException;
+    method public void close() throws java.sql.SQLException;
+    method public boolean execute(String) throws java.sql.SQLException;
+    method public boolean execute(String, int) throws java.sql.SQLException;
+    method public boolean execute(String, int[]) throws java.sql.SQLException;
+    method public boolean execute(String, String[]) throws java.sql.SQLException;
+    method public int[] executeBatch() throws java.sql.SQLException;
+    method public java.sql.ResultSet executeQuery(String) throws java.sql.SQLException;
+    method public int executeUpdate(String) throws java.sql.SQLException;
+    method public int executeUpdate(String, int) throws java.sql.SQLException;
+    method public int executeUpdate(String, int[]) throws java.sql.SQLException;
+    method public int executeUpdate(String, String[]) throws java.sql.SQLException;
+    method public java.sql.Connection getConnection() throws java.sql.SQLException;
+    method public int getFetchDirection() throws java.sql.SQLException;
+    method public int getFetchSize() throws java.sql.SQLException;
+    method public java.sql.ResultSet getGeneratedKeys() throws java.sql.SQLException;
+    method public int getMaxFieldSize() throws java.sql.SQLException;
+    method public int getMaxRows() throws java.sql.SQLException;
+    method public boolean getMoreResults() throws java.sql.SQLException;
+    method public boolean getMoreResults(int) throws java.sql.SQLException;
+    method public int getQueryTimeout() throws java.sql.SQLException;
+    method public java.sql.ResultSet getResultSet() throws java.sql.SQLException;
+    method public int getResultSetConcurrency() throws java.sql.SQLException;
+    method public int getResultSetHoldability() throws java.sql.SQLException;
+    method public int getResultSetType() throws java.sql.SQLException;
+    method public int getUpdateCount() throws java.sql.SQLException;
+    method public java.sql.SQLWarning getWarnings() throws java.sql.SQLException;
+    method public boolean isClosed() throws java.sql.SQLException;
+    method public boolean isPoolable() throws java.sql.SQLException;
+    method public void setCursorName(String) throws java.sql.SQLException;
+    method public void setEscapeProcessing(boolean) throws java.sql.SQLException;
+    method public void setFetchDirection(int) throws java.sql.SQLException;
+    method public void setFetchSize(int) throws java.sql.SQLException;
+    method public void setMaxFieldSize(int) throws java.sql.SQLException;
+    method public void setMaxRows(int) throws java.sql.SQLException;
+    method public void setPoolable(boolean) throws java.sql.SQLException;
+    method public void setQueryTimeout(int) throws java.sql.SQLException;
+    field public static final int CLOSE_ALL_RESULTS = 3; // 0x3
+    field public static final int CLOSE_CURRENT_RESULT = 1; // 0x1
+    field public static final int EXECUTE_FAILED = -3; // 0xfffffffd
+    field public static final int KEEP_CURRENT_RESULT = 2; // 0x2
+    field public static final int NO_GENERATED_KEYS = 2; // 0x2
+    field public static final int RETURN_GENERATED_KEYS = 1; // 0x1
+    field public static final int SUCCESS_NO_INFO = -2; // 0xfffffffe
+  }
+
+  public interface Struct {
+    method public Object[] getAttributes() throws java.sql.SQLException;
+    method public Object[] getAttributes(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public String getSQLTypeName() throws java.sql.SQLException;
+  }
+
+  public class Time extends java.util.Date {
+    ctor @Deprecated public Time(int, int, int);
+    ctor public Time(long);
+    method public static java.sql.Time valueOf(String);
+  }
+
+  public class Timestamp extends java.util.Date {
+    ctor @Deprecated public Timestamp(int, int, int, int, int, int, int);
+    ctor public Timestamp(long);
+    method public boolean after(java.sql.Timestamp);
+    method public boolean before(java.sql.Timestamp);
+    method public int compareTo(java.sql.Timestamp);
+    method public boolean equals(java.sql.Timestamp);
+    method public int getNanos();
+    method public void setNanos(int);
+    method public static java.sql.Timestamp valueOf(String);
+  }
+
+  public class Types {
+    field public static final int ARRAY = 2003; // 0x7d3
+    field public static final int BIGINT = -5; // 0xfffffffb
+    field public static final int BINARY = -2; // 0xfffffffe
+    field public static final int BIT = -7; // 0xfffffff9
+    field public static final int BLOB = 2004; // 0x7d4
+    field public static final int BOOLEAN = 16; // 0x10
+    field public static final int CHAR = 1; // 0x1
+    field public static final int CLOB = 2005; // 0x7d5
+    field public static final int DATALINK = 70; // 0x46
+    field public static final int DATE = 91; // 0x5b
+    field public static final int DECIMAL = 3; // 0x3
+    field public static final int DISTINCT = 2001; // 0x7d1
+    field public static final int DOUBLE = 8; // 0x8
+    field public static final int FLOAT = 6; // 0x6
+    field public static final int INTEGER = 4; // 0x4
+    field public static final int JAVA_OBJECT = 2000; // 0x7d0
+    field public static final int LONGNVARCHAR = -16; // 0xfffffff0
+    field public static final int LONGVARBINARY = -4; // 0xfffffffc
+    field public static final int LONGVARCHAR = -1; // 0xffffffff
+    field public static final int NCHAR = -15; // 0xfffffff1
+    field public static final int NCLOB = 2011; // 0x7db
+    field public static final int NULL = 0; // 0x0
+    field public static final int NUMERIC = 2; // 0x2
+    field public static final int NVARCHAR = -9; // 0xfffffff7
+    field public static final int OTHER = 1111; // 0x457
+    field public static final int REAL = 7; // 0x7
+    field public static final int REF = 2006; // 0x7d6
+    field public static final int ROWID = -8; // 0xfffffff8
+    field public static final int SMALLINT = 5; // 0x5
+    field public static final int SQLXML = 2009; // 0x7d9
+    field public static final int STRUCT = 2002; // 0x7d2
+    field public static final int TIME = 92; // 0x5c
+    field public static final int TIMESTAMP = 93; // 0x5d
+    field public static final int TINYINT = -6; // 0xfffffffa
+    field public static final int VARBINARY = -3; // 0xfffffffd
+    field public static final int VARCHAR = 12; // 0xc
+  }
+
+  public interface Wrapper {
+    method public boolean isWrapperFor(Class<?>) throws java.sql.SQLException;
+    method public <T> T unwrap(Class<T>) throws java.sql.SQLException;
+  }
+
+}
+
+package java.text {
+
+  public class Annotation {
+    ctor public Annotation(Object);
+    method public Object getValue();
+  }
+
+  public interface AttributedCharacterIterator extends java.text.CharacterIterator {
+    method public java.util.Set<java.text.AttributedCharacterIterator.Attribute> getAllAttributeKeys();
+    method public Object getAttribute(java.text.AttributedCharacterIterator.Attribute);
+    method public java.util.Map<java.text.AttributedCharacterIterator.Attribute,java.lang.Object> getAttributes();
+    method public int getRunLimit();
+    method public int getRunLimit(java.text.AttributedCharacterIterator.Attribute);
+    method public int getRunLimit(java.util.Set<? extends java.text.AttributedCharacterIterator.Attribute>);
+    method public int getRunStart();
+    method public int getRunStart(java.text.AttributedCharacterIterator.Attribute);
+    method public int getRunStart(java.util.Set<? extends java.text.AttributedCharacterIterator.Attribute>);
+  }
+
+  public static class AttributedCharacterIterator.Attribute implements java.io.Serializable {
+    ctor protected AttributedCharacterIterator.Attribute(String);
+    method public final boolean equals(Object);
+    method protected String getName();
+    method public final int hashCode();
+    method protected Object readResolve() throws java.io.InvalidObjectException;
+    field public static final java.text.AttributedCharacterIterator.Attribute INPUT_METHOD_SEGMENT;
+    field public static final java.text.AttributedCharacterIterator.Attribute LANGUAGE;
+    field public static final java.text.AttributedCharacterIterator.Attribute READING;
+  }
+
+  public class AttributedString {
+    ctor public AttributedString(String);
+    ctor public AttributedString(String, java.util.Map<? extends java.text.AttributedCharacterIterator.Attribute,?>);
+    ctor public AttributedString(java.text.AttributedCharacterIterator);
+    ctor public AttributedString(java.text.AttributedCharacterIterator, int, int);
+    ctor public AttributedString(java.text.AttributedCharacterIterator, int, int, java.text.AttributedCharacterIterator.Attribute[]);
+    method public void addAttribute(java.text.AttributedCharacterIterator.Attribute, Object);
+    method public void addAttribute(java.text.AttributedCharacterIterator.Attribute, Object, int, int);
+    method public void addAttributes(java.util.Map<? extends java.text.AttributedCharacterIterator.Attribute,?>, int, int);
+    method public java.text.AttributedCharacterIterator getIterator();
+    method public java.text.AttributedCharacterIterator getIterator(java.text.AttributedCharacterIterator.Attribute[]);
+    method public java.text.AttributedCharacterIterator getIterator(java.text.AttributedCharacterIterator.Attribute[], int, int);
+  }
+
+  public final class Bidi {
+    ctor public Bidi(String, int);
+    ctor public Bidi(java.text.AttributedCharacterIterator);
+    ctor public Bidi(char[], int, byte[], int, int, int);
+    method public boolean baseIsLeftToRight();
+    method public java.text.Bidi createLineBidi(int, int);
+    method public int getBaseLevel();
+    method public int getLength();
+    method public int getLevelAt(int);
+    method public int getRunCount();
+    method public int getRunLevel(int);
+    method public int getRunLimit(int);
+    method public int getRunStart(int);
+    method public boolean isLeftToRight();
+    method public boolean isMixed();
+    method public boolean isRightToLeft();
+    method public static void reorderVisually(byte[], int, Object[], int, int);
+    method public static boolean requiresBidi(char[], int, int);
+    field public static final int DIRECTION_DEFAULT_LEFT_TO_RIGHT = -2; // 0xfffffffe
+    field public static final int DIRECTION_DEFAULT_RIGHT_TO_LEFT = -1; // 0xffffffff
+    field public static final int DIRECTION_LEFT_TO_RIGHT = 0; // 0x0
+    field public static final int DIRECTION_RIGHT_TO_LEFT = 1; // 0x1
+  }
+
+  public abstract class BreakIterator implements java.lang.Cloneable {
+    ctor protected BreakIterator();
+    method public Object clone();
+    method public abstract int current();
+    method public abstract int first();
+    method public abstract int following(int);
+    method public static java.util.Locale[] getAvailableLocales();
+    method public static java.text.BreakIterator getCharacterInstance();
+    method public static java.text.BreakIterator getCharacterInstance(java.util.Locale);
+    method public static java.text.BreakIterator getLineInstance();
+    method public static java.text.BreakIterator getLineInstance(java.util.Locale);
+    method public static java.text.BreakIterator getSentenceInstance();
+    method public static java.text.BreakIterator getSentenceInstance(java.util.Locale);
+    method public abstract java.text.CharacterIterator getText();
+    method public static java.text.BreakIterator getWordInstance();
+    method public static java.text.BreakIterator getWordInstance(java.util.Locale);
+    method public boolean isBoundary(int);
+    method public abstract int last();
+    method public abstract int next(int);
+    method public abstract int next();
+    method public int preceding(int);
+    method public abstract int previous();
+    method public void setText(String);
+    method public abstract void setText(java.text.CharacterIterator);
+    field public static final int DONE = -1; // 0xffffffff
+  }
+
+  public interface CharacterIterator extends java.lang.Cloneable {
+    method public Object clone();
+    method public char current();
+    method public char first();
+    method public int getBeginIndex();
+    method public int getEndIndex();
+    method public int getIndex();
+    method public char last();
+    method public char next();
+    method public char previous();
+    method public char setIndex(int);
+    field public static final char DONE = 65535; // 0xffff '\uffff'
+  }
+
+  public class ChoiceFormat extends java.text.NumberFormat {
+    ctor public ChoiceFormat(String);
+    ctor public ChoiceFormat(double[], String[]);
+    method public void applyPattern(String);
+    method public StringBuffer format(long, StringBuffer, java.text.FieldPosition);
+    method public StringBuffer format(double, StringBuffer, java.text.FieldPosition);
+    method public Object[] getFormats();
+    method public double[] getLimits();
+    method public static final double nextDouble(double);
+    method public static double nextDouble(double, boolean);
+    method public Number parse(String, java.text.ParsePosition);
+    method public static final double previousDouble(double);
+    method public void setChoices(double[], String[]);
+    method public String toPattern();
+  }
+
+  public final class CollationElementIterator {
+    method public int getMaxExpansion(int);
+    method public int getOffset();
+    method public int next();
+    method public int previous();
+    method public static int primaryOrder(int);
+    method public void reset();
+    method public static short secondaryOrder(int);
+    method public void setOffset(int);
+    method public void setText(String);
+    method public void setText(java.text.CharacterIterator);
+    method public static short tertiaryOrder(int);
+    field public static final int NULLORDER = -1; // 0xffffffff
+  }
+
+  public abstract class CollationKey implements java.lang.Comparable<java.text.CollationKey> {
+    ctor protected CollationKey(String);
+    method public abstract int compareTo(java.text.CollationKey);
+    method public String getSourceString();
+    method public abstract byte[] toByteArray();
+  }
+
+  public abstract class Collator implements java.lang.Cloneable java.util.Comparator<java.lang.Object> {
+    ctor protected Collator();
+    method public Object clone();
+    method public abstract int compare(String, String);
+    method public int compare(Object, Object);
+    method public boolean equals(String, String);
+    method public static java.util.Locale[] getAvailableLocales();
+    method public abstract java.text.CollationKey getCollationKey(String);
+    method public int getDecomposition();
+    method public static java.text.Collator getInstance();
+    method public static java.text.Collator getInstance(java.util.Locale);
+    method public int getStrength();
+    method public abstract int hashCode();
+    method public void setDecomposition(int);
+    method public void setStrength(int);
+    field public static final int CANONICAL_DECOMPOSITION = 1; // 0x1
+    field public static final int FULL_DECOMPOSITION = 2; // 0x2
+    field public static final int IDENTICAL = 3; // 0x3
+    field public static final int NO_DECOMPOSITION = 0; // 0x0
+    field public static final int PRIMARY = 0; // 0x0
+    field public static final int SECONDARY = 1; // 0x1
+    field public static final int TERTIARY = 2; // 0x2
+  }
+
+  public abstract class DateFormat extends java.text.Format {
+    ctor protected DateFormat();
+    method @NonNull public final StringBuffer format(@NonNull Object, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
+    method @NonNull public abstract StringBuffer format(@NonNull java.util.Date, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
+    method @NonNull public final String format(@NonNull java.util.Date);
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public java.util.Calendar getCalendar();
+    method @NonNull public static final java.text.DateFormat getDateInstance();
+    method @NonNull public static final java.text.DateFormat getDateInstance(int);
+    method @NonNull public static final java.text.DateFormat getDateInstance(int, @NonNull java.util.Locale);
+    method @NonNull public static final java.text.DateFormat getDateTimeInstance();
+    method @NonNull public static final java.text.DateFormat getDateTimeInstance(int, int);
+    method @NonNull public static final java.text.DateFormat getDateTimeInstance(int, int, @NonNull java.util.Locale);
+    method @NonNull public static final java.text.DateFormat getInstance();
+    method @NonNull public java.text.NumberFormat getNumberFormat();
+    method @NonNull public static final java.text.DateFormat getTimeInstance();
+    method @NonNull public static final java.text.DateFormat getTimeInstance(int);
+    method @NonNull public static final java.text.DateFormat getTimeInstance(int, @NonNull java.util.Locale);
+    method @NonNull public java.util.TimeZone getTimeZone();
+    method public boolean isLenient();
+    method @Nullable public java.util.Date parse(@NonNull String) throws java.text.ParseException;
+    method @Nullable public abstract java.util.Date parse(@NonNull String, @NonNull java.text.ParsePosition);
+    method @Nullable public Object parseObject(@NonNull String, @NonNull java.text.ParsePosition);
+    method public void setCalendar(@NonNull java.util.Calendar);
+    method public void setLenient(boolean);
+    method public void setNumberFormat(@NonNull java.text.NumberFormat);
+    method public void setTimeZone(@NonNull java.util.TimeZone);
+    field public static final int AM_PM_FIELD = 14; // 0xe
+    field public static final int DATE_FIELD = 3; // 0x3
+    field public static final int DAY_OF_WEEK_FIELD = 9; // 0x9
+    field public static final int DAY_OF_WEEK_IN_MONTH_FIELD = 11; // 0xb
+    field public static final int DAY_OF_YEAR_FIELD = 10; // 0xa
+    field public static final int DEFAULT = 2; // 0x2
+    field public static final int ERA_FIELD = 0; // 0x0
+    field public static final int FULL = 0; // 0x0
+    field public static final int HOUR0_FIELD = 16; // 0x10
+    field public static final int HOUR1_FIELD = 15; // 0xf
+    field public static final int HOUR_OF_DAY0_FIELD = 5; // 0x5
+    field public static final int HOUR_OF_DAY1_FIELD = 4; // 0x4
+    field public static final int LONG = 1; // 0x1
+    field public static final int MEDIUM = 2; // 0x2
+    field public static final int MILLISECOND_FIELD = 8; // 0x8
+    field public static final int MINUTE_FIELD = 6; // 0x6
+    field public static final int MONTH_FIELD = 2; // 0x2
+    field public static final int SECOND_FIELD = 7; // 0x7
+    field public static final int SHORT = 3; // 0x3
+    field public static final int TIMEZONE_FIELD = 17; // 0x11
+    field public static final int WEEK_OF_MONTH_FIELD = 13; // 0xd
+    field public static final int WEEK_OF_YEAR_FIELD = 12; // 0xc
+    field public static final int YEAR_FIELD = 1; // 0x1
+    field @NonNull protected java.util.Calendar calendar;
+    field @NonNull protected java.text.NumberFormat numberFormat;
+  }
+
+  public static class DateFormat.Field extends java.text.Format.Field {
+    ctor protected DateFormat.Field(@NonNull String, int);
+    method public int getCalendarField();
+    method @NonNull public static java.text.DateFormat.Field ofCalendarField(int);
+    field @NonNull public static final java.text.DateFormat.Field AM_PM;
+    field @NonNull public static final java.text.DateFormat.Field DAY_OF_MONTH;
+    field @NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK;
+    field @NonNull public static final java.text.DateFormat.Field DAY_OF_WEEK_IN_MONTH;
+    field @NonNull public static final java.text.DateFormat.Field DAY_OF_YEAR;
+    field @NonNull public static final java.text.DateFormat.Field ERA;
+    field @NonNull public static final java.text.DateFormat.Field HOUR0;
+    field @NonNull public static final java.text.DateFormat.Field HOUR1;
+    field @NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY0;
+    field @NonNull public static final java.text.DateFormat.Field HOUR_OF_DAY1;
+    field @NonNull public static final java.text.DateFormat.Field MILLISECOND;
+    field @NonNull public static final java.text.DateFormat.Field MINUTE;
+    field @NonNull public static final java.text.DateFormat.Field MONTH;
+    field @NonNull public static final java.text.DateFormat.Field SECOND;
+    field @NonNull public static final java.text.DateFormat.Field TIME_ZONE;
+    field @NonNull public static final java.text.DateFormat.Field WEEK_OF_MONTH;
+    field @NonNull public static final java.text.DateFormat.Field WEEK_OF_YEAR;
+    field @NonNull public static final java.text.DateFormat.Field YEAR;
+  }
+
+  public class DateFormatSymbols implements java.lang.Cloneable java.io.Serializable {
+    ctor public DateFormatSymbols();
+    ctor public DateFormatSymbols(java.util.Locale);
+    method public Object clone();
+    method public String[] getAmPmStrings();
+    method public static java.util.Locale[] getAvailableLocales();
+    method public String[] getEras();
+    method public static final java.text.DateFormatSymbols getInstance();
+    method public static final java.text.DateFormatSymbols getInstance(java.util.Locale);
+    method public String getLocalPatternChars();
+    method public String[] getMonths();
+    method public String[] getShortMonths();
+    method public String[] getShortWeekdays();
+    method public String[] getWeekdays();
+    method public String[][] getZoneStrings();
+    method public void setAmPmStrings(String[]);
+    method public void setEras(String[]);
+    method public void setLocalPatternChars(String);
+    method public void setMonths(String[]);
+    method public void setShortMonths(String[]);
+    method public void setShortWeekdays(String[]);
+    method public void setWeekdays(String[]);
+    method public void setZoneStrings(String[][]);
+  }
+
+  public class DecimalFormat extends java.text.NumberFormat {
+    ctor public DecimalFormat();
+    ctor public DecimalFormat(String);
+    ctor public DecimalFormat(String, java.text.DecimalFormatSymbols);
+    method public void applyLocalizedPattern(String);
+    method public void applyPattern(String);
+    method public final StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
+    method public StringBuffer format(double, StringBuffer, java.text.FieldPosition);
+    method public StringBuffer format(long, StringBuffer, java.text.FieldPosition);
+    method public java.text.DecimalFormatSymbols getDecimalFormatSymbols();
+    method public int getGroupingSize();
+    method public int getMultiplier();
+    method public String getNegativePrefix();
+    method public String getNegativeSuffix();
+    method public String getPositivePrefix();
+    method public String getPositiveSuffix();
+    method public boolean isDecimalSeparatorAlwaysShown();
+    method public boolean isParseBigDecimal();
+    method public Number parse(String, java.text.ParsePosition);
+    method public void setDecimalFormatSymbols(java.text.DecimalFormatSymbols);
+    method public void setDecimalSeparatorAlwaysShown(boolean);
+    method public void setGroupingSize(int);
+    method public void setMultiplier(int);
+    method public void setNegativePrefix(String);
+    method public void setNegativeSuffix(String);
+    method public void setParseBigDecimal(boolean);
+    method public void setPositivePrefix(String);
+    method public void setPositiveSuffix(String);
+    method public String toLocalizedPattern();
+    method public String toPattern();
+  }
+
+  public class DecimalFormatSymbols implements java.lang.Cloneable java.io.Serializable {
+    ctor public DecimalFormatSymbols();
+    ctor public DecimalFormatSymbols(java.util.Locale);
+    method public Object clone();
+    method public static java.util.Locale[] getAvailableLocales();
+    method public java.util.Currency getCurrency();
+    method public String getCurrencySymbol();
+    method public char getDecimalSeparator();
+    method public char getDigit();
+    method public String getExponentSeparator();
+    method public char getGroupingSeparator();
+    method public String getInfinity();
+    method public static final java.text.DecimalFormatSymbols getInstance();
+    method public static final java.text.DecimalFormatSymbols getInstance(java.util.Locale);
+    method public String getInternationalCurrencySymbol();
+    method public char getMinusSign();
+    method public char getMonetaryDecimalSeparator();
+    method public String getNaN();
+    method public char getPatternSeparator();
+    method public char getPerMill();
+    method public char getPercent();
+    method public char getZeroDigit();
+    method public void setCurrency(java.util.Currency);
+    method public void setCurrencySymbol(String);
+    method public void setDecimalSeparator(char);
+    method public void setDigit(char);
+    method public void setExponentSeparator(String);
+    method public void setGroupingSeparator(char);
+    method public void setInfinity(String);
+    method public void setInternationalCurrencySymbol(String);
+    method public void setMinusSign(char);
+    method public void setMonetaryDecimalSeparator(char);
+    method public void setNaN(String);
+    method public void setPatternSeparator(char);
+    method public void setPerMill(char);
+    method public void setPercent(char);
+    method public void setZeroDigit(char);
+  }
+
+  public class FieldPosition {
+    ctor public FieldPosition(int);
+    ctor public FieldPosition(java.text.Format.Field);
+    ctor public FieldPosition(java.text.Format.Field, int);
+    method public int getBeginIndex();
+    method public int getEndIndex();
+    method public int getField();
+    method public java.text.Format.Field getFieldAttribute();
+    method public void setBeginIndex(int);
+    method public void setEndIndex(int);
+  }
+
+  public abstract class Format implements java.lang.Cloneable java.io.Serializable {
+    ctor protected Format();
+    method public Object clone();
+    method public final String format(Object);
+    method public abstract StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
+    method public java.text.AttributedCharacterIterator formatToCharacterIterator(Object);
+    method public abstract Object parseObject(String, java.text.ParsePosition);
+    method public Object parseObject(String) throws java.text.ParseException;
+  }
+
+  public static class Format.Field extends java.text.AttributedCharacterIterator.Attribute {
+    ctor protected Format.Field(String);
+  }
+
+  public class MessageFormat extends java.text.Format {
+    ctor public MessageFormat(String);
+    ctor public MessageFormat(String, java.util.Locale);
+    method public void applyPattern(String);
+    method public final StringBuffer format(Object[], StringBuffer, java.text.FieldPosition);
+    method public static String format(String, java.lang.Object...);
+    method public final StringBuffer format(Object, StringBuffer, java.text.FieldPosition);
+    method public java.text.Format[] getFormats();
+    method public java.text.Format[] getFormatsByArgumentIndex();
+    method public java.util.Locale getLocale();
+    method public Object[] parse(String, java.text.ParsePosition);
+    method public Object[] parse(String) throws java.text.ParseException;
+    method public Object parseObject(String, java.text.ParsePosition);
+    method public void setFormat(int, java.text.Format);
+    method public void setFormatByArgumentIndex(int, java.text.Format);
+    method public void setFormats(java.text.Format[]);
+    method public void setFormatsByArgumentIndex(java.text.Format[]);
+    method public void setLocale(java.util.Locale);
+    method public String toPattern();
+  }
+
+  public static class MessageFormat.Field extends java.text.Format.Field {
+    ctor protected MessageFormat.Field(String);
+    field public static final java.text.MessageFormat.Field ARGUMENT;
+  }
+
+  public final class Normalizer {
+    method public static boolean isNormalized(CharSequence, java.text.Normalizer.Form);
+    method public static String normalize(CharSequence, java.text.Normalizer.Form);
+  }
+
+  public enum Normalizer.Form {
+    enum_constant public static final java.text.Normalizer.Form NFC;
+    enum_constant public static final java.text.Normalizer.Form NFD;
+    enum_constant public static final java.text.Normalizer.Form NFKC;
+    enum_constant public static final java.text.Normalizer.Form NFKD;
+  }
+
+  public abstract class NumberFormat extends java.text.Format {
+    ctor protected NumberFormat();
+    method @NonNull public StringBuffer format(@NonNull Object, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
+    method @NonNull public final String format(double);
+    method @NonNull public final String format(long);
+    method @NonNull public abstract StringBuffer format(double, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
+    method @NonNull public abstract StringBuffer format(long, @NonNull StringBuffer, @NonNull java.text.FieldPosition);
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
+    method @Nullable public java.util.Currency getCurrency();
+    method @NonNull public static final java.text.NumberFormat getCurrencyInstance();
+    method @NonNull public static java.text.NumberFormat getCurrencyInstance(@NonNull java.util.Locale);
+    method @NonNull public static final java.text.NumberFormat getInstance();
+    method @NonNull public static java.text.NumberFormat getInstance(@NonNull java.util.Locale);
+    method @NonNull public static final java.text.NumberFormat getIntegerInstance();
+    method @NonNull public static java.text.NumberFormat getIntegerInstance(@NonNull java.util.Locale);
+    method public int getMaximumFractionDigits();
+    method public int getMaximumIntegerDigits();
+    method public int getMinimumFractionDigits();
+    method public int getMinimumIntegerDigits();
+    method @NonNull public static final java.text.NumberFormat getNumberInstance();
+    method @NonNull public static java.text.NumberFormat getNumberInstance(@NonNull java.util.Locale);
+    method @NonNull public static final java.text.NumberFormat getPercentInstance();
+    method @NonNull public static java.text.NumberFormat getPercentInstance(@NonNull java.util.Locale);
+    method @NonNull public java.math.RoundingMode getRoundingMode();
+    method public boolean isGroupingUsed();
+    method public boolean isParseIntegerOnly();
+    method @Nullable public abstract Number parse(@NonNull String, @NonNull java.text.ParsePosition);
+    method @Nullable public Number parse(@NonNull String) throws java.text.ParseException;
+    method @Nullable public final Object parseObject(@NonNull String, @NonNull java.text.ParsePosition);
+    method public void setCurrency(@NonNull java.util.Currency);
+    method public void setGroupingUsed(boolean);
+    method public void setMaximumFractionDigits(int);
+    method public void setMaximumIntegerDigits(int);
+    method public void setMinimumFractionDigits(int);
+    method public void setMinimumIntegerDigits(int);
+    method public void setParseIntegerOnly(boolean);
+    method public void setRoundingMode(@Nullable java.math.RoundingMode);
+    field public static final int FRACTION_FIELD = 1; // 0x1
+    field public static final int INTEGER_FIELD = 0; // 0x0
+  }
+
+  public static class NumberFormat.Field extends java.text.Format.Field {
+    ctor protected NumberFormat.Field(@NonNull String);
+    field @NonNull public static final java.text.NumberFormat.Field CURRENCY;
+    field @NonNull public static final java.text.NumberFormat.Field DECIMAL_SEPARATOR;
+    field @NonNull public static final java.text.NumberFormat.Field EXPONENT;
+    field @NonNull public static final java.text.NumberFormat.Field EXPONENT_SIGN;
+    field @NonNull public static final java.text.NumberFormat.Field EXPONENT_SYMBOL;
+    field @NonNull public static final java.text.NumberFormat.Field FRACTION;
+    field @NonNull public static final java.text.NumberFormat.Field GROUPING_SEPARATOR;
+    field @NonNull public static final java.text.NumberFormat.Field INTEGER;
+    field @NonNull public static final java.text.NumberFormat.Field PERCENT;
+    field @NonNull public static final java.text.NumberFormat.Field PERMILLE;
+    field @NonNull public static final java.text.NumberFormat.Field SIGN;
+  }
+
+  public class ParseException extends java.lang.Exception {
+    ctor public ParseException(String, int);
+    method public int getErrorOffset();
+  }
+
+  public class ParsePosition {
+    ctor public ParsePosition(int);
+    method public int getErrorIndex();
+    method public int getIndex();
+    method public void setErrorIndex(int);
+    method public void setIndex(int);
+  }
+
+  public class RuleBasedCollator extends java.text.Collator {
+    ctor public RuleBasedCollator(String) throws java.text.ParseException;
+    method public int compare(String, String);
+    method public java.text.CollationElementIterator getCollationElementIterator(String);
+    method public java.text.CollationElementIterator getCollationElementIterator(java.text.CharacterIterator);
+    method public java.text.CollationKey getCollationKey(String);
+    method public String getRules();
+  }
+
+  public class SimpleDateFormat extends java.text.DateFormat {
+    ctor public SimpleDateFormat();
+    ctor public SimpleDateFormat(String);
+    ctor public SimpleDateFormat(String, java.util.Locale);
+    ctor public SimpleDateFormat(String, java.text.DateFormatSymbols);
+    method public void applyLocalizedPattern(String);
+    method public void applyPattern(String);
+    method public StringBuffer format(java.util.Date, StringBuffer, java.text.FieldPosition);
+    method public java.util.Date get2DigitYearStart();
+    method public java.text.DateFormatSymbols getDateFormatSymbols();
+    method public java.util.Date parse(String, java.text.ParsePosition);
+    method public void set2DigitYearStart(java.util.Date);
+    method public void setDateFormatSymbols(java.text.DateFormatSymbols);
+    method public String toLocalizedPattern();
+    method public String toPattern();
+  }
+
+  public final class StringCharacterIterator implements java.text.CharacterIterator {
+    ctor public StringCharacterIterator(String);
+    ctor public StringCharacterIterator(String, int);
+    ctor public StringCharacterIterator(String, int, int, int);
+    method public Object clone();
+    method public char current();
+    method public char first();
+    method public int getBeginIndex();
+    method public int getEndIndex();
+    method public int getIndex();
+    method public char last();
+    method public char next();
+    method public char previous();
+    method public char setIndex(int);
+    method public void setText(String);
+  }
+
+}
+
+package java.time {
+
+  public abstract class Clock {
+    ctor protected Clock();
+    method public static java.time.Clock fixed(java.time.Instant, java.time.ZoneId);
+    method public abstract java.time.ZoneId getZone();
+    method public abstract java.time.Instant instant();
+    method public long millis();
+    method public static java.time.Clock offset(java.time.Clock, java.time.Duration);
+    method public static java.time.Clock system(java.time.ZoneId);
+    method public static java.time.Clock systemDefaultZone();
+    method public static java.time.Clock systemUTC();
+    method public static java.time.Clock tick(java.time.Clock, java.time.Duration);
+    method public static java.time.Clock tickMinutes(java.time.ZoneId);
+    method public static java.time.Clock tickSeconds(java.time.ZoneId);
+    method public abstract java.time.Clock withZone(java.time.ZoneId);
+  }
+
+  public class DateTimeException extends java.lang.RuntimeException {
+    ctor public DateTimeException(String);
+    ctor public DateTimeException(String, Throwable);
+  }
+
+  public enum DayOfWeek implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public static java.time.DayOfWeek from(java.time.temporal.TemporalAccessor);
+    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getValue();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.DayOfWeek minus(long);
+    method public static java.time.DayOfWeek of(int);
+    method public java.time.DayOfWeek plus(long);
+    enum_constant public static final java.time.DayOfWeek FRIDAY;
+    enum_constant public static final java.time.DayOfWeek MONDAY;
+    enum_constant public static final java.time.DayOfWeek SATURDAY;
+    enum_constant public static final java.time.DayOfWeek SUNDAY;
+    enum_constant public static final java.time.DayOfWeek THURSDAY;
+    enum_constant public static final java.time.DayOfWeek TUESDAY;
+    enum_constant public static final java.time.DayOfWeek WEDNESDAY;
+  }
+
+  public final class Duration implements java.lang.Comparable<java.time.Duration> java.io.Serializable java.time.temporal.TemporalAmount {
+    method public java.time.Duration abs();
+    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
+    method public static java.time.Duration between(java.time.temporal.Temporal, java.time.temporal.Temporal);
+    method public int compareTo(java.time.Duration);
+    method public java.time.Duration dividedBy(long);
+    method public long dividedBy(java.time.Duration);
+    method public static java.time.Duration from(java.time.temporal.TemporalAmount);
+    method public long get(java.time.temporal.TemporalUnit);
+    method public int getNano();
+    method public long getSeconds();
+    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
+    method public boolean isNegative();
+    method public boolean isZero();
+    method public java.time.Duration minus(java.time.Duration);
+    method public java.time.Duration minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Duration minusDays(long);
+    method public java.time.Duration minusHours(long);
+    method public java.time.Duration minusMillis(long);
+    method public java.time.Duration minusMinutes(long);
+    method public java.time.Duration minusNanos(long);
+    method public java.time.Duration minusSeconds(long);
+    method public java.time.Duration multipliedBy(long);
+    method public java.time.Duration negated();
+    method public static java.time.Duration of(long, java.time.temporal.TemporalUnit);
+    method public static java.time.Duration ofDays(long);
+    method public static java.time.Duration ofHours(long);
+    method public static java.time.Duration ofMillis(long);
+    method public static java.time.Duration ofMinutes(long);
+    method public static java.time.Duration ofNanos(long);
+    method public static java.time.Duration ofSeconds(long);
+    method public static java.time.Duration ofSeconds(long, long);
+    method public static java.time.Duration parse(CharSequence);
+    method public java.time.Duration plus(java.time.Duration);
+    method public java.time.Duration plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Duration plusDays(long);
+    method public java.time.Duration plusHours(long);
+    method public java.time.Duration plusMillis(long);
+    method public java.time.Duration plusMinutes(long);
+    method public java.time.Duration plusNanos(long);
+    method public java.time.Duration plusSeconds(long);
+    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
+    method public long toDays();
+    method public long toDaysPart();
+    method public long toHours();
+    method public int toHoursPart();
+    method public long toMillis();
+    method public int toMillisPart();
+    method public long toMinutes();
+    method public int toMinutesPart();
+    method public long toNanos();
+    method public int toNanosPart();
+    method public long toSeconds();
+    method public int toSecondsPart();
+    method public java.time.Duration truncatedTo(java.time.temporal.TemporalUnit);
+    method public java.time.Duration withNanos(int);
+    method public java.time.Duration withSeconds(long);
+    field public static final java.time.Duration ZERO;
+  }
+
+  public final class Instant implements java.lang.Comparable<java.time.Instant> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.OffsetDateTime atOffset(java.time.ZoneOffset);
+    method public java.time.ZonedDateTime atZone(java.time.ZoneId);
+    method public int compareTo(java.time.Instant);
+    method public static java.time.Instant from(java.time.temporal.TemporalAccessor);
+    method public long getEpochSecond();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getNano();
+    method public boolean isAfter(java.time.Instant);
+    method public boolean isBefore(java.time.Instant);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.Instant minus(java.time.temporal.TemporalAmount);
+    method public java.time.Instant minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Instant minusMillis(long);
+    method public java.time.Instant minusNanos(long);
+    method public java.time.Instant minusSeconds(long);
+    method public static java.time.Instant now();
+    method public static java.time.Instant now(java.time.Clock);
+    method public static java.time.Instant ofEpochMilli(long);
+    method public static java.time.Instant ofEpochSecond(long);
+    method public static java.time.Instant ofEpochSecond(long, long);
+    method public static java.time.Instant parse(CharSequence);
+    method public java.time.Instant plus(java.time.temporal.TemporalAmount);
+    method public java.time.Instant plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Instant plusMillis(long);
+    method public java.time.Instant plusNanos(long);
+    method public java.time.Instant plusSeconds(long);
+    method public long toEpochMilli();
+    method public java.time.Instant truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Instant with(java.time.temporal.TemporalAdjuster);
+    method public java.time.Instant with(java.time.temporal.TemporalField, long);
+    field public static final java.time.Instant EPOCH;
+    field public static final java.time.Instant MAX;
+    field public static final java.time.Instant MIN;
+  }
+
+  public final class LocalDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.LocalDateTime atStartOfDay();
+    method public java.time.ZonedDateTime atStartOfDay(java.time.ZoneId);
+    method public java.time.LocalDateTime atTime(java.time.LocalTime);
+    method public java.time.LocalDateTime atTime(int, int);
+    method public java.time.LocalDateTime atTime(int, int, int);
+    method public java.time.LocalDateTime atTime(int, int, int, int);
+    method public java.time.OffsetDateTime atTime(java.time.OffsetTime);
+    method public static java.time.LocalDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.IsoChronology getChronology();
+    method public int getDayOfMonth();
+    method public java.time.DayOfWeek getDayOfWeek();
+    method public int getDayOfYear();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public int getYear();
+    method public int lengthOfMonth();
+    method public java.time.LocalDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDate minusDays(long);
+    method public java.time.LocalDate minusMonths(long);
+    method public java.time.LocalDate minusWeeks(long);
+    method public java.time.LocalDate minusYears(long);
+    method public static java.time.LocalDate now();
+    method public static java.time.LocalDate now(java.time.ZoneId);
+    method public static java.time.LocalDate now(java.time.Clock);
+    method public static java.time.LocalDate of(int, java.time.Month, int);
+    method public static java.time.LocalDate of(int, int, int);
+    method public static java.time.LocalDate ofEpochDay(long);
+    method public static java.time.LocalDate ofYearDay(int, int);
+    method public static java.time.LocalDate parse(CharSequence);
+    method public static java.time.LocalDate parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDate plusDays(long);
+    method public java.time.LocalDate plusMonths(long);
+    method public java.time.LocalDate plusWeeks(long);
+    method public java.time.LocalDate plusYears(long);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Period until(java.time.chrono.ChronoLocalDate);
+    method public java.time.LocalDate with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalDate with(java.time.temporal.TemporalField, long);
+    method public java.time.LocalDate withDayOfMonth(int);
+    method public java.time.LocalDate withDayOfYear(int);
+    method public java.time.LocalDate withMonth(int);
+    method public java.time.LocalDate withYear(int);
+    field public static final java.time.LocalDate MAX;
+    field public static final java.time.LocalDate MIN;
+  }
+
+  public final class LocalDateTime implements java.time.chrono.ChronoLocalDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.OffsetDateTime atOffset(java.time.ZoneOffset);
+    method public java.time.ZonedDateTime atZone(java.time.ZoneId);
+    method public static java.time.LocalDateTime from(java.time.temporal.TemporalAccessor);
+    method public int getDayOfMonth();
+    method public java.time.DayOfWeek getDayOfWeek();
+    method public int getDayOfYear();
+    method public int getHour();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getMinute();
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public int getNano();
+    method public int getSecond();
+    method public int getYear();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.LocalDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDateTime minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime minusDays(long);
+    method public java.time.LocalDateTime minusHours(long);
+    method public java.time.LocalDateTime minusMinutes(long);
+    method public java.time.LocalDateTime minusMonths(long);
+    method public java.time.LocalDateTime minusNanos(long);
+    method public java.time.LocalDateTime minusSeconds(long);
+    method public java.time.LocalDateTime minusWeeks(long);
+    method public java.time.LocalDateTime minusYears(long);
+    method public static java.time.LocalDateTime now();
+    method public static java.time.LocalDateTime now(java.time.ZoneId);
+    method public static java.time.LocalDateTime now(java.time.Clock);
+    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int);
+    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int, int);
+    method public static java.time.LocalDateTime of(int, java.time.Month, int, int, int, int, int);
+    method public static java.time.LocalDateTime of(int, int, int, int, int);
+    method public static java.time.LocalDateTime of(int, int, int, int, int, int);
+    method public static java.time.LocalDateTime of(int, int, int, int, int, int, int);
+    method public static java.time.LocalDateTime of(java.time.LocalDate, java.time.LocalTime);
+    method public static java.time.LocalDateTime ofEpochSecond(long, int, java.time.ZoneOffset);
+    method public static java.time.LocalDateTime ofInstant(java.time.Instant, java.time.ZoneId);
+    method public static java.time.LocalDateTime parse(CharSequence);
+    method public static java.time.LocalDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalDateTime plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalDateTime plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime plusDays(long);
+    method public java.time.LocalDateTime plusHours(long);
+    method public java.time.LocalDateTime plusMinutes(long);
+    method public java.time.LocalDateTime plusMonths(long);
+    method public java.time.LocalDateTime plusNanos(long);
+    method public java.time.LocalDateTime plusSeconds(long);
+    method public java.time.LocalDateTime plusWeeks(long);
+    method public java.time.LocalDateTime plusYears(long);
+    method public java.time.LocalDate toLocalDate();
+    method public java.time.LocalTime toLocalTime();
+    method public java.time.LocalDateTime truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalDateTime with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalDateTime with(java.time.temporal.TemporalField, long);
+    method public java.time.LocalDateTime withDayOfMonth(int);
+    method public java.time.LocalDateTime withDayOfYear(int);
+    method public java.time.LocalDateTime withHour(int);
+    method public java.time.LocalDateTime withMinute(int);
+    method public java.time.LocalDateTime withMonth(int);
+    method public java.time.LocalDateTime withNano(int);
+    method public java.time.LocalDateTime withSecond(int);
+    method public java.time.LocalDateTime withYear(int);
+    field public static final java.time.LocalDateTime MAX;
+    field public static final java.time.LocalDateTime MIN;
+  }
+
+  public final class LocalTime implements java.lang.Comparable<java.time.LocalTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.LocalDateTime atDate(java.time.LocalDate);
+    method public java.time.OffsetTime atOffset(java.time.ZoneOffset);
+    method public int compareTo(java.time.LocalTime);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.LocalTime from(java.time.temporal.TemporalAccessor);
+    method public int getHour();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getMinute();
+    method public int getNano();
+    method public int getSecond();
+    method public boolean isAfter(java.time.LocalTime);
+    method public boolean isBefore(java.time.LocalTime);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalTime minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime minusHours(long);
+    method public java.time.LocalTime minusMinutes(long);
+    method public java.time.LocalTime minusNanos(long);
+    method public java.time.LocalTime minusSeconds(long);
+    method public static java.time.LocalTime now();
+    method public static java.time.LocalTime now(java.time.ZoneId);
+    method public static java.time.LocalTime now(java.time.Clock);
+    method public static java.time.LocalTime of(int, int);
+    method public static java.time.LocalTime of(int, int, int);
+    method public static java.time.LocalTime of(int, int, int, int);
+    method public static java.time.LocalTime ofInstant(java.time.Instant, java.time.ZoneId);
+    method public static java.time.LocalTime ofNanoOfDay(long);
+    method public static java.time.LocalTime ofSecondOfDay(long);
+    method public static java.time.LocalTime parse(CharSequence);
+    method public static java.time.LocalTime parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.LocalTime plus(java.time.temporal.TemporalAmount);
+    method public java.time.LocalTime plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime plusHours(long);
+    method public java.time.LocalTime plusMinutes(long);
+    method public java.time.LocalTime plusNanos(long);
+    method public java.time.LocalTime plusSeconds(long);
+    method public long toEpochSecond(java.time.LocalDate, java.time.ZoneOffset);
+    method public long toNanoOfDay();
+    method public int toSecondOfDay();
+    method public java.time.LocalTime truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.LocalTime with(java.time.temporal.TemporalAdjuster);
+    method public java.time.LocalTime with(java.time.temporal.TemporalField, long);
+    method public java.time.LocalTime withHour(int);
+    method public java.time.LocalTime withMinute(int);
+    method public java.time.LocalTime withNano(int);
+    method public java.time.LocalTime withSecond(int);
+    field public static final java.time.LocalTime MAX;
+    field public static final java.time.LocalTime MIDNIGHT;
+    field public static final java.time.LocalTime MIN;
+    field public static final java.time.LocalTime NOON;
+  }
+
+  public enum Month implements java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public int firstDayOfYear(boolean);
+    method public java.time.Month firstMonthOfQuarter();
+    method public static java.time.Month from(java.time.temporal.TemporalAccessor);
+    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getValue();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public int length(boolean);
+    method public int maxLength();
+    method public int minLength();
+    method public java.time.Month minus(long);
+    method public static java.time.Month of(int);
+    method public java.time.Month plus(long);
+    enum_constant public static final java.time.Month APRIL;
+    enum_constant public static final java.time.Month AUGUST;
+    enum_constant public static final java.time.Month DECEMBER;
+    enum_constant public static final java.time.Month FEBRUARY;
+    enum_constant public static final java.time.Month JANUARY;
+    enum_constant public static final java.time.Month JULY;
+    enum_constant public static final java.time.Month JUNE;
+    enum_constant public static final java.time.Month MARCH;
+    enum_constant public static final java.time.Month MAY;
+    enum_constant public static final java.time.Month NOVEMBER;
+    enum_constant public static final java.time.Month OCTOBER;
+    enum_constant public static final java.time.Month SEPTEMBER;
+  }
+
+  public final class MonthDay implements java.lang.Comparable<java.time.MonthDay> java.io.Serializable java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.LocalDate atYear(int);
+    method public int compareTo(java.time.MonthDay);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.MonthDay from(java.time.temporal.TemporalAccessor);
+    method public int getDayOfMonth();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public boolean isAfter(java.time.MonthDay);
+    method public boolean isBefore(java.time.MonthDay);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isValidYear(int);
+    method public static java.time.MonthDay now();
+    method public static java.time.MonthDay now(java.time.ZoneId);
+    method public static java.time.MonthDay now(java.time.Clock);
+    method public static java.time.MonthDay of(java.time.Month, int);
+    method public static java.time.MonthDay of(int, int);
+    method public static java.time.MonthDay parse(CharSequence);
+    method public static java.time.MonthDay parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.MonthDay with(java.time.Month);
+    method public java.time.MonthDay withDayOfMonth(int);
+    method public java.time.MonthDay withMonth(int);
+  }
+
+  public final class OffsetDateTime implements java.lang.Comparable<java.time.OffsetDateTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.ZonedDateTime atZoneSameInstant(java.time.ZoneId);
+    method public java.time.ZonedDateTime atZoneSimilarLocal(java.time.ZoneId);
+    method public int compareTo(java.time.OffsetDateTime);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.OffsetDateTime from(java.time.temporal.TemporalAccessor);
+    method public int getDayOfMonth();
+    method public java.time.DayOfWeek getDayOfWeek();
+    method public int getDayOfYear();
+    method public int getHour();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getMinute();
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public int getNano();
+    method public java.time.ZoneOffset getOffset();
+    method public int getSecond();
+    method public int getYear();
+    method public boolean isAfter(java.time.OffsetDateTime);
+    method public boolean isBefore(java.time.OffsetDateTime);
+    method public boolean isEqual(java.time.OffsetDateTime);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetDateTime minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime minusDays(long);
+    method public java.time.OffsetDateTime minusHours(long);
+    method public java.time.OffsetDateTime minusMinutes(long);
+    method public java.time.OffsetDateTime minusMonths(long);
+    method public java.time.OffsetDateTime minusNanos(long);
+    method public java.time.OffsetDateTime minusSeconds(long);
+    method public java.time.OffsetDateTime minusWeeks(long);
+    method public java.time.OffsetDateTime minusYears(long);
+    method public static java.time.OffsetDateTime now();
+    method public static java.time.OffsetDateTime now(java.time.ZoneId);
+    method public static java.time.OffsetDateTime now(java.time.Clock);
+    method public static java.time.OffsetDateTime of(java.time.LocalDate, java.time.LocalTime, java.time.ZoneOffset);
+    method public static java.time.OffsetDateTime of(java.time.LocalDateTime, java.time.ZoneOffset);
+    method public static java.time.OffsetDateTime of(int, int, int, int, int, int, int, java.time.ZoneOffset);
+    method public static java.time.OffsetDateTime ofInstant(java.time.Instant, java.time.ZoneId);
+    method public static java.time.OffsetDateTime parse(CharSequence);
+    method public static java.time.OffsetDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetDateTime plus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetDateTime plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime plusDays(long);
+    method public java.time.OffsetDateTime plusHours(long);
+    method public java.time.OffsetDateTime plusMinutes(long);
+    method public java.time.OffsetDateTime plusMonths(long);
+    method public java.time.OffsetDateTime plusNanos(long);
+    method public java.time.OffsetDateTime plusSeconds(long);
+    method public java.time.OffsetDateTime plusWeeks(long);
+    method public java.time.OffsetDateTime plusYears(long);
+    method public static java.util.Comparator<java.time.OffsetDateTime> timeLineOrder();
+    method public long toEpochSecond();
+    method public java.time.Instant toInstant();
+    method public java.time.LocalDate toLocalDate();
+    method public java.time.LocalDateTime toLocalDateTime();
+    method public java.time.LocalTime toLocalTime();
+    method public java.time.OffsetTime toOffsetTime();
+    method public java.time.ZonedDateTime toZonedDateTime();
+    method public java.time.OffsetDateTime truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetDateTime with(java.time.temporal.TemporalAdjuster);
+    method public java.time.OffsetDateTime with(java.time.temporal.TemporalField, long);
+    method public java.time.OffsetDateTime withDayOfMonth(int);
+    method public java.time.OffsetDateTime withDayOfYear(int);
+    method public java.time.OffsetDateTime withHour(int);
+    method public java.time.OffsetDateTime withMinute(int);
+    method public java.time.OffsetDateTime withMonth(int);
+    method public java.time.OffsetDateTime withNano(int);
+    method public java.time.OffsetDateTime withOffsetSameInstant(java.time.ZoneOffset);
+    method public java.time.OffsetDateTime withOffsetSameLocal(java.time.ZoneOffset);
+    method public java.time.OffsetDateTime withSecond(int);
+    method public java.time.OffsetDateTime withYear(int);
+    field public static final java.time.OffsetDateTime MAX;
+    field public static final java.time.OffsetDateTime MIN;
+  }
+
+  public final class OffsetTime implements java.lang.Comparable<java.time.OffsetTime> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.OffsetDateTime atDate(java.time.LocalDate);
+    method public int compareTo(java.time.OffsetTime);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.OffsetTime from(java.time.temporal.TemporalAccessor);
+    method public int getHour();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getMinute();
+    method public int getNano();
+    method public java.time.ZoneOffset getOffset();
+    method public int getSecond();
+    method public boolean isAfter(java.time.OffsetTime);
+    method public boolean isBefore(java.time.OffsetTime);
+    method public boolean isEqual(java.time.OffsetTime);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetTime minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime minusHours(long);
+    method public java.time.OffsetTime minusMinutes(long);
+    method public java.time.OffsetTime minusNanos(long);
+    method public java.time.OffsetTime minusSeconds(long);
+    method public static java.time.OffsetTime now();
+    method public static java.time.OffsetTime now(java.time.ZoneId);
+    method public static java.time.OffsetTime now(java.time.Clock);
+    method public static java.time.OffsetTime of(java.time.LocalTime, java.time.ZoneOffset);
+    method public static java.time.OffsetTime of(int, int, int, int, java.time.ZoneOffset);
+    method public static java.time.OffsetTime ofInstant(java.time.Instant, java.time.ZoneId);
+    method public static java.time.OffsetTime parse(CharSequence);
+    method public static java.time.OffsetTime parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.OffsetTime plus(java.time.temporal.TemporalAmount);
+    method public java.time.OffsetTime plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime plusHours(long);
+    method public java.time.OffsetTime plusMinutes(long);
+    method public java.time.OffsetTime plusNanos(long);
+    method public java.time.OffsetTime plusSeconds(long);
+    method public java.time.LocalTime toLocalTime();
+    method public java.time.OffsetTime truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.OffsetTime with(java.time.temporal.TemporalAdjuster);
+    method public java.time.OffsetTime with(java.time.temporal.TemporalField, long);
+    method public java.time.OffsetTime withHour(int);
+    method public java.time.OffsetTime withMinute(int);
+    method public java.time.OffsetTime withNano(int);
+    method public java.time.OffsetTime withOffsetSameInstant(java.time.ZoneOffset);
+    method public java.time.OffsetTime withOffsetSameLocal(java.time.ZoneOffset);
+    method public java.time.OffsetTime withSecond(int);
+    field public static final java.time.OffsetTime MAX;
+    field public static final java.time.OffsetTime MIN;
+  }
+
+  public final class Period implements java.time.chrono.ChronoPeriod java.io.Serializable {
+    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
+    method public static java.time.Period between(java.time.LocalDate, java.time.LocalDate);
+    method public static java.time.Period from(java.time.temporal.TemporalAmount);
+    method public long get(java.time.temporal.TemporalUnit);
+    method public java.time.chrono.IsoChronology getChronology();
+    method public int getDays();
+    method public int getMonths();
+    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
+    method public int getYears();
+    method public java.time.Period minus(java.time.temporal.TemporalAmount);
+    method public java.time.Period minusDays(long);
+    method public java.time.Period minusMonths(long);
+    method public java.time.Period minusYears(long);
+    method public java.time.Period multipliedBy(int);
+    method public java.time.Period negated();
+    method public java.time.Period normalized();
+    method public static java.time.Period of(int, int, int);
+    method public static java.time.Period ofDays(int);
+    method public static java.time.Period ofMonths(int);
+    method public static java.time.Period ofWeeks(int);
+    method public static java.time.Period ofYears(int);
+    method public static java.time.Period parse(CharSequence);
+    method public java.time.Period plus(java.time.temporal.TemporalAmount);
+    method public java.time.Period plusDays(long);
+    method public java.time.Period plusMonths(long);
+    method public java.time.Period plusYears(long);
+    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
+    method public long toTotalMonths();
+    method public java.time.Period withDays(int);
+    method public java.time.Period withMonths(int);
+    method public java.time.Period withYears(int);
+    field public static final java.time.Period ZERO;
+  }
+
+  public final class Year implements java.lang.Comparable<java.time.Year> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.LocalDate atDay(int);
+    method public java.time.YearMonth atMonth(java.time.Month);
+    method public java.time.YearMonth atMonth(int);
+    method public java.time.LocalDate atMonthDay(java.time.MonthDay);
+    method public int compareTo(java.time.Year);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.Year from(java.time.temporal.TemporalAccessor);
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int getValue();
+    method public boolean isAfter(java.time.Year);
+    method public boolean isBefore(java.time.Year);
+    method public static boolean isLeap(long);
+    method public boolean isLeap();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public boolean isValidMonthDay(java.time.MonthDay);
+    method public int length();
+    method public java.time.Year minus(java.time.temporal.TemporalAmount);
+    method public java.time.Year minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Year minusYears(long);
+    method public static java.time.Year now();
+    method public static java.time.Year now(java.time.ZoneId);
+    method public static java.time.Year now(java.time.Clock);
+    method public static java.time.Year of(int);
+    method public static java.time.Year parse(CharSequence);
+    method public static java.time.Year parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.Year plus(java.time.temporal.TemporalAmount);
+    method public java.time.Year plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.Year plusYears(long);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.Year with(java.time.temporal.TemporalAdjuster);
+    method public java.time.Year with(java.time.temporal.TemporalField, long);
+    field public static final int MAX_VALUE = 999999999; // 0x3b9ac9ff
+    field public static final int MIN_VALUE = -999999999; // 0xc4653601
+  }
+
+  public final class YearMonth implements java.lang.Comparable<java.time.YearMonth> java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.LocalDate atDay(int);
+    method public java.time.LocalDate atEndOfMonth();
+    method public int compareTo(java.time.YearMonth);
+    method public String format(java.time.format.DateTimeFormatter);
+    method public static java.time.YearMonth from(java.time.temporal.TemporalAccessor);
+    method public long getLong(java.time.temporal.TemporalField);
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public int getYear();
+    method public boolean isAfter(java.time.YearMonth);
+    method public boolean isBefore(java.time.YearMonth);
+    method public boolean isLeapYear();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public boolean isValidDay(int);
+    method public int lengthOfMonth();
+    method public int lengthOfYear();
+    method public java.time.YearMonth minus(java.time.temporal.TemporalAmount);
+    method public java.time.YearMonth minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth minusMonths(long);
+    method public java.time.YearMonth minusYears(long);
+    method public static java.time.YearMonth now();
+    method public static java.time.YearMonth now(java.time.ZoneId);
+    method public static java.time.YearMonth now(java.time.Clock);
+    method public static java.time.YearMonth of(int, java.time.Month);
+    method public static java.time.YearMonth of(int, int);
+    method public static java.time.YearMonth parse(CharSequence);
+    method public static java.time.YearMonth parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.YearMonth plus(java.time.temporal.TemporalAmount);
+    method public java.time.YearMonth plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth plusMonths(long);
+    method public java.time.YearMonth plusYears(long);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.YearMonth with(java.time.temporal.TemporalAdjuster);
+    method public java.time.YearMonth with(java.time.temporal.TemporalField, long);
+    method public java.time.YearMonth withMonth(int);
+    method public java.time.YearMonth withYear(int);
+  }
+
+  public abstract class ZoneId implements java.io.Serializable {
+    method public static java.time.ZoneId from(java.time.temporal.TemporalAccessor);
+    method public static java.util.Set<java.lang.String> getAvailableZoneIds();
+    method public String getDisplayName(java.time.format.TextStyle, java.util.Locale);
+    method public abstract String getId();
+    method public abstract java.time.zone.ZoneRules getRules();
+    method public java.time.ZoneId normalized();
+    method public static java.time.ZoneId of(String, java.util.Map<java.lang.String,java.lang.String>);
+    method public static java.time.ZoneId of(String);
+    method public static java.time.ZoneId ofOffset(String, java.time.ZoneOffset);
+    method public static java.time.ZoneId systemDefault();
+    field public static final java.util.Map<java.lang.String,java.lang.String> SHORT_IDS;
+  }
+
+  public final class ZoneOffset extends java.time.ZoneId implements java.lang.Comparable<java.time.ZoneOffset> java.io.Serializable java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public int compareTo(java.time.ZoneOffset);
+    method public static java.time.ZoneOffset from(java.time.temporal.TemporalAccessor);
+    method public String getId();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public java.time.zone.ZoneRules getRules();
+    method public int getTotalSeconds();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public static java.time.ZoneOffset of(String);
+    method public static java.time.ZoneOffset ofHours(int);
+    method public static java.time.ZoneOffset ofHoursMinutes(int, int);
+    method public static java.time.ZoneOffset ofHoursMinutesSeconds(int, int, int);
+    method public static java.time.ZoneOffset ofTotalSeconds(int);
+    field public static final java.time.ZoneOffset MAX;
+    field public static final java.time.ZoneOffset MIN;
+    field public static final java.time.ZoneOffset UTC;
+  }
+
+  public final class ZonedDateTime implements java.time.chrono.ChronoZonedDateTime<java.time.LocalDate> java.io.Serializable java.time.temporal.Temporal {
+    method public static java.time.ZonedDateTime from(java.time.temporal.TemporalAccessor);
+    method public int getDayOfMonth();
+    method public java.time.DayOfWeek getDayOfWeek();
+    method public int getDayOfYear();
+    method public int getHour();
+    method public int getMinute();
+    method public java.time.Month getMonth();
+    method public int getMonthValue();
+    method public int getNano();
+    method public java.time.ZoneOffset getOffset();
+    method public int getSecond();
+    method public int getYear();
+    method public java.time.ZoneId getZone();
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public java.time.ZonedDateTime minus(java.time.temporal.TemporalAmount);
+    method public java.time.ZonedDateTime minus(long, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime minusDays(long);
+    method public java.time.ZonedDateTime minusHours(long);
+    method public java.time.ZonedDateTime minusMinutes(long);
+    method public java.time.ZonedDateTime minusMonths(long);
+    method public java.time.ZonedDateTime minusNanos(long);
+    method public java.time.ZonedDateTime minusSeconds(long);
+    method public java.time.ZonedDateTime minusWeeks(long);
+    method public java.time.ZonedDateTime minusYears(long);
+    method public static java.time.ZonedDateTime now();
+    method public static java.time.ZonedDateTime now(java.time.ZoneId);
+    method public static java.time.ZonedDateTime now(java.time.Clock);
+    method public static java.time.ZonedDateTime of(java.time.LocalDate, java.time.LocalTime, java.time.ZoneId);
+    method public static java.time.ZonedDateTime of(java.time.LocalDateTime, java.time.ZoneId);
+    method public static java.time.ZonedDateTime of(int, int, int, int, int, int, int, java.time.ZoneId);
+    method public static java.time.ZonedDateTime ofInstant(java.time.Instant, java.time.ZoneId);
+    method public static java.time.ZonedDateTime ofInstant(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
+    method public static java.time.ZonedDateTime ofLocal(java.time.LocalDateTime, java.time.ZoneId, java.time.ZoneOffset);
+    method public static java.time.ZonedDateTime ofStrict(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneId);
+    method public static java.time.ZonedDateTime parse(CharSequence);
+    method public static java.time.ZonedDateTime parse(CharSequence, java.time.format.DateTimeFormatter);
+    method public java.time.ZonedDateTime plus(java.time.temporal.TemporalAmount);
+    method public java.time.ZonedDateTime plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime plusDays(long);
+    method public java.time.ZonedDateTime plusHours(long);
+    method public java.time.ZonedDateTime plusMinutes(long);
+    method public java.time.ZonedDateTime plusMonths(long);
+    method public java.time.ZonedDateTime plusNanos(long);
+    method public java.time.ZonedDateTime plusSeconds(long);
+    method public java.time.ZonedDateTime plusWeeks(long);
+    method public java.time.ZonedDateTime plusYears(long);
+    method public java.time.LocalDate toLocalDate();
+    method public java.time.LocalDateTime toLocalDateTime();
+    method public java.time.OffsetDateTime toOffsetDateTime();
+    method public java.time.ZonedDateTime truncatedTo(java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.ZonedDateTime with(java.time.temporal.TemporalAdjuster);
+    method public java.time.ZonedDateTime with(java.time.temporal.TemporalField, long);
+    method public java.time.ZonedDateTime withDayOfMonth(int);
+    method public java.time.ZonedDateTime withDayOfYear(int);
+    method public java.time.ZonedDateTime withEarlierOffsetAtOverlap();
+    method public java.time.ZonedDateTime withFixedOffsetZone();
+    method public java.time.ZonedDateTime withHour(int);
+    method public java.time.ZonedDateTime withLaterOffsetAtOverlap();
+    method public java.time.ZonedDateTime withMinute(int);
+    method public java.time.ZonedDateTime withMonth(int);
+    method public java.time.ZonedDateTime withNano(int);
+    method public java.time.ZonedDateTime withSecond(int);
+    method public java.time.ZonedDateTime withYear(int);
+    method public java.time.ZonedDateTime withZoneSameInstant(java.time.ZoneId);
+    method public java.time.ZonedDateTime withZoneSameLocal(java.time.ZoneId);
+  }
+
+}
+
+package java.time.chrono {
+
+  public abstract class AbstractChronology implements java.time.chrono.Chronology {
+    ctor protected AbstractChronology();
+    method public int compareTo(java.time.chrono.Chronology);
+    method public java.time.chrono.ChronoLocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+  }
+
+  public interface ChronoLocalDate extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoLocalDate> java.time.temporal.TemporalAdjuster {
+    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public default java.time.chrono.ChronoLocalDateTime<?> atTime(java.time.LocalTime);
+    method public default int compareTo(java.time.chrono.ChronoLocalDate);
+    method public boolean equals(Object);
+    method public default String format(java.time.format.DateTimeFormatter);
+    method public static java.time.chrono.ChronoLocalDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.Chronology getChronology();
+    method public default java.time.chrono.Era getEra();
+    method public int hashCode();
+    method public default boolean isAfter(java.time.chrono.ChronoLocalDate);
+    method public default boolean isBefore(java.time.chrono.ChronoLocalDate);
+    method public default boolean isEqual(java.time.chrono.ChronoLocalDate);
+    method public default boolean isLeapYear();
+    method public default boolean isSupported(java.time.temporal.TemporalField);
+    method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public int lengthOfMonth();
+    method public default int lengthOfYear();
+    method public default java.time.chrono.ChronoLocalDate minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDate minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDate plus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDate plus(long, java.time.temporal.TemporalUnit);
+    method public static java.util.Comparator<java.time.chrono.ChronoLocalDate> timeLineOrder();
+    method public default long toEpochDay();
+    method public String toString();
+    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalAdjuster);
+    method public default java.time.chrono.ChronoLocalDate with(java.time.temporal.TemporalField, long);
+  }
+
+  public interface ChronoLocalDateTime<D extends java.time.chrono.ChronoLocalDate> extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoLocalDateTime<?>> java.time.temporal.TemporalAdjuster {
+    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public java.time.chrono.ChronoZonedDateTime<D> atZone(java.time.ZoneId);
+    method public default int compareTo(java.time.chrono.ChronoLocalDateTime<?>);
+    method public boolean equals(Object);
+    method public default String format(java.time.format.DateTimeFormatter);
+    method public static java.time.chrono.ChronoLocalDateTime<?> from(java.time.temporal.TemporalAccessor);
+    method public default java.time.chrono.Chronology getChronology();
+    method public int hashCode();
+    method public default boolean isAfter(java.time.chrono.ChronoLocalDateTime<?>);
+    method public default boolean isBefore(java.time.chrono.ChronoLocalDateTime<?>);
+    method public default boolean isEqual(java.time.chrono.ChronoLocalDateTime<?>);
+    method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoLocalDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoLocalDateTime<D> plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ChronoLocalDateTime<D> plus(long, java.time.temporal.TemporalUnit);
+    method public static java.util.Comparator<java.time.chrono.ChronoLocalDateTime<?>> timeLineOrder();
+    method public default long toEpochSecond(java.time.ZoneOffset);
+    method public default java.time.Instant toInstant(java.time.ZoneOffset);
+    method public D toLocalDate();
+    method public java.time.LocalTime toLocalTime();
+    method public String toString();
+    method public default java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalAdjuster);
+    method public java.time.chrono.ChronoLocalDateTime<D> with(java.time.temporal.TemporalField, long);
+  }
+
+  public interface ChronoPeriod extends java.time.temporal.TemporalAmount {
+    method public static java.time.chrono.ChronoPeriod between(java.time.chrono.ChronoLocalDate, java.time.chrono.ChronoLocalDate);
+    method public boolean equals(Object);
+    method public java.time.chrono.Chronology getChronology();
+    method public int hashCode();
+    method public default boolean isNegative();
+    method public default boolean isZero();
+    method public java.time.chrono.ChronoPeriod minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ChronoPeriod multipliedBy(int);
+    method public default java.time.chrono.ChronoPeriod negated();
+    method public java.time.chrono.ChronoPeriod normalized();
+    method public java.time.chrono.ChronoPeriod plus(java.time.temporal.TemporalAmount);
+    method public String toString();
+  }
+
+  public interface ChronoZonedDateTime<D extends java.time.chrono.ChronoLocalDate> extends java.time.temporal.Temporal java.lang.Comparable<java.time.chrono.ChronoZonedDateTime<?>> {
+    method public default int compareTo(java.time.chrono.ChronoZonedDateTime<?>);
+    method public boolean equals(Object);
+    method public default String format(java.time.format.DateTimeFormatter);
+    method public static java.time.chrono.ChronoZonedDateTime<?> from(java.time.temporal.TemporalAccessor);
+    method public default java.time.chrono.Chronology getChronology();
+    method public default long getLong(java.time.temporal.TemporalField);
+    method public java.time.ZoneOffset getOffset();
+    method public java.time.ZoneId getZone();
+    method public int hashCode();
+    method public default boolean isAfter(java.time.chrono.ChronoZonedDateTime<?>);
+    method public default boolean isBefore(java.time.chrono.ChronoZonedDateTime<?>);
+    method public default boolean isEqual(java.time.chrono.ChronoZonedDateTime<?>);
+    method public default boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(java.time.temporal.TemporalAmount);
+    method public default java.time.chrono.ChronoZonedDateTime<D> minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.chrono.ChronoZonedDateTime<D> plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ChronoZonedDateTime<D> plus(long, java.time.temporal.TemporalUnit);
+    method public static java.util.Comparator<java.time.chrono.ChronoZonedDateTime<?>> timeLineOrder();
+    method public default long toEpochSecond();
+    method public default java.time.Instant toInstant();
+    method public default D toLocalDate();
+    method public java.time.chrono.ChronoLocalDateTime<D> toLocalDateTime();
+    method public default java.time.LocalTime toLocalTime();
+    method public String toString();
+    method public default java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalAdjuster);
+    method public java.time.chrono.ChronoZonedDateTime<D> with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.ChronoZonedDateTime<D> withEarlierOffsetAtOverlap();
+    method public java.time.chrono.ChronoZonedDateTime<D> withLaterOffsetAtOverlap();
+    method public java.time.chrono.ChronoZonedDateTime<D> withZoneSameInstant(java.time.ZoneId);
+    method public java.time.chrono.ChronoZonedDateTime<D> withZoneSameLocal(java.time.ZoneId);
+  }
+
+  public interface Chronology extends java.lang.Comparable<java.time.chrono.Chronology> {
+    method public int compareTo(java.time.chrono.Chronology);
+    method public default java.time.chrono.ChronoLocalDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.chrono.ChronoLocalDate date(int, int, int);
+    method public java.time.chrono.ChronoLocalDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ChronoLocalDate dateEpochDay(long);
+    method public default java.time.chrono.ChronoLocalDate dateNow();
+    method public default java.time.chrono.ChronoLocalDate dateNow(java.time.ZoneId);
+    method public default java.time.chrono.ChronoLocalDate dateNow(java.time.Clock);
+    method public default java.time.chrono.ChronoLocalDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.chrono.ChronoLocalDate dateYearDay(int, int);
+    method public boolean equals(Object);
+    method public java.time.chrono.Era eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public static java.time.chrono.Chronology from(java.time.temporal.TemporalAccessor);
+    method public static java.util.Set<java.time.chrono.Chronology> getAvailableChronologies();
+    method public String getCalendarType();
+    method public default String getDisplayName(java.time.format.TextStyle, java.util.Locale);
+    method public String getId();
+    method public int hashCode();
+    method public boolean isLeapYear(long);
+    method public default java.time.chrono.ChronoLocalDateTime<? extends java.time.chrono.ChronoLocalDate> localDateTime(java.time.temporal.TemporalAccessor);
+    method public static java.time.chrono.Chronology of(String);
+    method public static java.time.chrono.Chronology ofLocale(java.util.Locale);
+    method public default java.time.chrono.ChronoPeriod period(int, int, int);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.ChronoLocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public String toString();
+    method public default java.time.chrono.ChronoZonedDateTime<? extends java.time.chrono.ChronoLocalDate> zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public default java.time.chrono.ChronoZonedDateTime<? extends java.time.chrono.ChronoLocalDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
+  }
+
+  public interface Era extends java.time.temporal.TemporalAccessor java.time.temporal.TemporalAdjuster {
+    method public default java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+    method public default String getDisplayName(java.time.format.TextStyle, java.util.Locale);
+    method public default long getLong(java.time.temporal.TemporalField);
+    method public int getValue();
+    method public default boolean isSupported(java.time.temporal.TemporalField);
+  }
+
+  public final class HijrahChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
+    method public java.time.chrono.HijrahDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.chrono.HijrahDate date(int, int, int);
+    method public java.time.chrono.HijrahDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.HijrahDate dateEpochDay(long);
+    method public java.time.chrono.HijrahDate dateNow();
+    method public java.time.chrono.HijrahDate dateNow(java.time.ZoneId);
+    method public java.time.chrono.HijrahDate dateNow(java.time.Clock);
+    method public java.time.chrono.HijrahDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.chrono.HijrahDate dateYearDay(int, int);
+    method public java.time.chrono.HijrahEra eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public String getCalendarType();
+    method public String getId();
+    method public boolean isLeapYear(long);
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> localDateTime(java.time.temporal.TemporalAccessor);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.HijrahDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.HijrahDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
+    field public static final java.time.chrono.HijrahChronology INSTANCE;
+  }
+
+  public final class HijrahDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.HijrahDate> atTime(java.time.LocalTime);
+    method public static java.time.chrono.HijrahDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.HijrahChronology getChronology();
+    method public java.time.chrono.HijrahEra getEra();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int lengthOfMonth();
+    method public java.time.chrono.HijrahDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate minus(long, java.time.temporal.TemporalUnit);
+    method public static java.time.chrono.HijrahDate now();
+    method public static java.time.chrono.HijrahDate now(java.time.ZoneId);
+    method public static java.time.chrono.HijrahDate now(java.time.Clock);
+    method public static java.time.chrono.HijrahDate of(int, int, int);
+    method public java.time.chrono.HijrahDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.HijrahDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.HijrahDate with(java.time.temporal.TemporalAdjuster);
+    method public java.time.chrono.HijrahDate withVariant(java.time.chrono.HijrahChronology);
+  }
+
+  public enum HijrahEra implements java.time.chrono.Era {
+    method public int getValue();
+    method public static java.time.chrono.HijrahEra of(int);
+    enum_constant public static final java.time.chrono.HijrahEra AH;
+  }
+
+  public final class IsoChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
+    method public java.time.LocalDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.LocalDate date(int, int, int);
+    method public java.time.LocalDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.LocalDate dateEpochDay(long);
+    method public java.time.LocalDate dateNow();
+    method public java.time.LocalDate dateNow(java.time.ZoneId);
+    method public java.time.LocalDate dateNow(java.time.Clock);
+    method public java.time.LocalDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.LocalDate dateYearDay(int, int);
+    method public java.time.chrono.IsoEra eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public String getCalendarType();
+    method public String getId();
+    method public boolean isLeapYear(long);
+    method public java.time.LocalDateTime localDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.Period period(int, int, int);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.LocalDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public java.time.ZonedDateTime zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.ZonedDateTime zonedDateTime(java.time.Instant, java.time.ZoneId);
+    field public static final java.time.chrono.IsoChronology INSTANCE;
+  }
+
+  public enum IsoEra implements java.time.chrono.Era {
+    method public int getValue();
+    method public static java.time.chrono.IsoEra of(int);
+    enum_constant public static final java.time.chrono.IsoEra BCE;
+    enum_constant public static final java.time.chrono.IsoEra CE;
+  }
+
+  public final class JapaneseChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
+    method public java.time.chrono.JapaneseDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.chrono.JapaneseDate date(int, int, int);
+    method public java.time.chrono.JapaneseDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.JapaneseDate dateEpochDay(long);
+    method public java.time.chrono.JapaneseDate dateNow();
+    method public java.time.chrono.JapaneseDate dateNow(java.time.ZoneId);
+    method public java.time.chrono.JapaneseDate dateNow(java.time.Clock);
+    method public java.time.chrono.JapaneseDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.chrono.JapaneseDate dateYearDay(int, int);
+    method public java.time.chrono.JapaneseEra eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public String getCalendarType();
+    method public String getId();
+    method public boolean isLeapYear(long);
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> localDateTime(java.time.temporal.TemporalAccessor);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.JapaneseDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.JapaneseDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
+    field public static final java.time.chrono.JapaneseChronology INSTANCE;
+  }
+
+  public final class JapaneseDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.JapaneseDate> atTime(java.time.LocalTime);
+    method public static java.time.chrono.JapaneseDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.JapaneseChronology getChronology();
+    method public java.time.chrono.JapaneseEra getEra();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int lengthOfMonth();
+    method public java.time.chrono.JapaneseDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate minus(long, java.time.temporal.TemporalUnit);
+    method public static java.time.chrono.JapaneseDate now();
+    method public static java.time.chrono.JapaneseDate now(java.time.ZoneId);
+    method public static java.time.chrono.JapaneseDate now(java.time.Clock);
+    method public static java.time.chrono.JapaneseDate of(java.time.chrono.JapaneseEra, int, int, int);
+    method public static java.time.chrono.JapaneseDate of(int, int, int);
+    method public java.time.chrono.JapaneseDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.JapaneseDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.JapaneseDate with(java.time.temporal.TemporalAdjuster);
+  }
+
+  public final class JapaneseEra implements java.time.chrono.Era java.io.Serializable {
+    method public int getValue();
+    method public static java.time.chrono.JapaneseEra of(int);
+    method public static java.time.chrono.JapaneseEra valueOf(String);
+    method public static java.time.chrono.JapaneseEra[] values();
+    field public static final java.time.chrono.JapaneseEra HEISEI;
+    field public static final java.time.chrono.JapaneseEra MEIJI;
+    field public static final java.time.chrono.JapaneseEra REIWA;
+    field public static final java.time.chrono.JapaneseEra SHOWA;
+    field public static final java.time.chrono.JapaneseEra TAISHO;
+  }
+
+  public final class MinguoChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
+    method public java.time.chrono.MinguoDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.chrono.MinguoDate date(int, int, int);
+    method public java.time.chrono.MinguoDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.MinguoDate dateEpochDay(long);
+    method public java.time.chrono.MinguoDate dateNow();
+    method public java.time.chrono.MinguoDate dateNow(java.time.ZoneId);
+    method public java.time.chrono.MinguoDate dateNow(java.time.Clock);
+    method public java.time.chrono.MinguoDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.chrono.MinguoDate dateYearDay(int, int);
+    method public java.time.chrono.MinguoEra eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public String getCalendarType();
+    method public String getId();
+    method public boolean isLeapYear(long);
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> localDateTime(java.time.temporal.TemporalAccessor);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.MinguoDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.MinguoDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
+    field public static final java.time.chrono.MinguoChronology INSTANCE;
+  }
+
+  public final class MinguoDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.MinguoDate> atTime(java.time.LocalTime);
+    method public static java.time.chrono.MinguoDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.MinguoChronology getChronology();
+    method public java.time.chrono.MinguoEra getEra();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int lengthOfMonth();
+    method public java.time.chrono.MinguoDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate minus(long, java.time.temporal.TemporalUnit);
+    method public static java.time.chrono.MinguoDate now();
+    method public static java.time.chrono.MinguoDate now(java.time.ZoneId);
+    method public static java.time.chrono.MinguoDate now(java.time.Clock);
+    method public static java.time.chrono.MinguoDate of(int, int, int);
+    method public java.time.chrono.MinguoDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.MinguoDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.MinguoDate with(java.time.temporal.TemporalAdjuster);
+  }
+
+  public enum MinguoEra implements java.time.chrono.Era {
+    method public int getValue();
+    method public static java.time.chrono.MinguoEra of(int);
+    enum_constant public static final java.time.chrono.MinguoEra BEFORE_ROC;
+    enum_constant public static final java.time.chrono.MinguoEra ROC;
+  }
+
+  public final class ThaiBuddhistChronology extends java.time.chrono.AbstractChronology implements java.io.Serializable {
+    method public java.time.chrono.ThaiBuddhistDate date(java.time.chrono.Era, int, int, int);
+    method public java.time.chrono.ThaiBuddhistDate date(int, int, int);
+    method public java.time.chrono.ThaiBuddhistDate date(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ThaiBuddhistDate dateEpochDay(long);
+    method public java.time.chrono.ThaiBuddhistDate dateNow();
+    method public java.time.chrono.ThaiBuddhistDate dateNow(java.time.ZoneId);
+    method public java.time.chrono.ThaiBuddhistDate dateNow(java.time.Clock);
+    method public java.time.chrono.ThaiBuddhistDate dateYearDay(java.time.chrono.Era, int, int);
+    method public java.time.chrono.ThaiBuddhistDate dateYearDay(int, int);
+    method public java.time.chrono.ThaiBuddhistEra eraOf(int);
+    method public java.util.List<java.time.chrono.Era> eras();
+    method public String getCalendarType();
+    method public String getId();
+    method public boolean isLeapYear(long);
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> localDateTime(java.time.temporal.TemporalAccessor);
+    method public int prolepticYear(java.time.chrono.Era, int);
+    method public java.time.temporal.ValueRange range(java.time.temporal.ChronoField);
+    method public java.time.chrono.ThaiBuddhistDate resolveDate(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.format.ResolverStyle);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ChronoZonedDateTime<java.time.chrono.ThaiBuddhistDate> zonedDateTime(java.time.Instant, java.time.ZoneId);
+    field public static final java.time.chrono.ThaiBuddhistChronology INSTANCE;
+  }
+
+  public final class ThaiBuddhistDate implements java.time.chrono.ChronoLocalDate java.io.Serializable java.time.temporal.Temporal java.time.temporal.TemporalAdjuster {
+    method public java.time.chrono.ChronoLocalDateTime<java.time.chrono.ThaiBuddhistDate> atTime(java.time.LocalTime);
+    method public static java.time.chrono.ThaiBuddhistDate from(java.time.temporal.TemporalAccessor);
+    method public java.time.chrono.ThaiBuddhistChronology getChronology();
+    method public java.time.chrono.ThaiBuddhistEra getEra();
+    method public long getLong(java.time.temporal.TemporalField);
+    method public int lengthOfMonth();
+    method public java.time.chrono.ThaiBuddhistDate minus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate minus(long, java.time.temporal.TemporalUnit);
+    method public static java.time.chrono.ThaiBuddhistDate now();
+    method public static java.time.chrono.ThaiBuddhistDate now(java.time.ZoneId);
+    method public static java.time.chrono.ThaiBuddhistDate now(java.time.Clock);
+    method public static java.time.chrono.ThaiBuddhistDate of(int, int, int);
+    method public java.time.chrono.ThaiBuddhistDate plus(java.time.temporal.TemporalAmount);
+    method public java.time.chrono.ThaiBuddhistDate plus(long, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.ChronoPeriod until(java.time.chrono.ChronoLocalDate);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalField, long);
+    method public java.time.chrono.ThaiBuddhistDate with(java.time.temporal.TemporalAdjuster);
+  }
+
+  public enum ThaiBuddhistEra implements java.time.chrono.Era {
+    method public int getValue();
+    method public static java.time.chrono.ThaiBuddhistEra of(int);
+    enum_constant public static final java.time.chrono.ThaiBuddhistEra BE;
+    enum_constant public static final java.time.chrono.ThaiBuddhistEra BEFORE_BE;
+  }
+
+}
+
+package java.time.format {
+
+  public final class DateTimeFormatter {
+    method public String format(java.time.temporal.TemporalAccessor);
+    method public void formatTo(java.time.temporal.TemporalAccessor, Appendable);
+    method public java.time.chrono.Chronology getChronology();
+    method public java.time.format.DecimalStyle getDecimalStyle();
+    method public java.util.Locale getLocale();
+    method public java.util.Set<java.time.temporal.TemporalField> getResolverFields();
+    method public java.time.format.ResolverStyle getResolverStyle();
+    method public java.time.ZoneId getZone();
+    method public static java.time.format.DateTimeFormatter ofLocalizedDate(java.time.format.FormatStyle);
+    method public static java.time.format.DateTimeFormatter ofLocalizedDateTime(java.time.format.FormatStyle);
+    method public static java.time.format.DateTimeFormatter ofLocalizedDateTime(java.time.format.FormatStyle, java.time.format.FormatStyle);
+    method public static java.time.format.DateTimeFormatter ofLocalizedTime(java.time.format.FormatStyle);
+    method public static java.time.format.DateTimeFormatter ofPattern(String);
+    method public static java.time.format.DateTimeFormatter ofPattern(String, java.util.Locale);
+    method public java.time.temporal.TemporalAccessor parse(CharSequence);
+    method public java.time.temporal.TemporalAccessor parse(CharSequence, java.text.ParsePosition);
+    method public <T> T parse(CharSequence, java.time.temporal.TemporalQuery<T>);
+    method public java.time.temporal.TemporalAccessor parseBest(CharSequence, java.time.temporal.TemporalQuery<?>...);
+    method public java.time.temporal.TemporalAccessor parseUnresolved(CharSequence, java.text.ParsePosition);
+    method public static java.time.temporal.TemporalQuery<java.time.Period> parsedExcessDays();
+    method public static java.time.temporal.TemporalQuery<java.lang.Boolean> parsedLeapSecond();
+    method public java.text.Format toFormat();
+    method public java.text.Format toFormat(java.time.temporal.TemporalQuery<?>);
+    method public java.time.format.DateTimeFormatter withChronology(java.time.chrono.Chronology);
+    method public java.time.format.DateTimeFormatter withDecimalStyle(java.time.format.DecimalStyle);
+    method public java.time.format.DateTimeFormatter withLocale(java.util.Locale);
+    method public java.time.format.DateTimeFormatter withResolverFields(java.time.temporal.TemporalField...);
+    method public java.time.format.DateTimeFormatter withResolverFields(java.util.Set<java.time.temporal.TemporalField>);
+    method public java.time.format.DateTimeFormatter withResolverStyle(java.time.format.ResolverStyle);
+    method public java.time.format.DateTimeFormatter withZone(java.time.ZoneId);
+    field public static final java.time.format.DateTimeFormatter BASIC_ISO_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_DATE_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_INSTANT;
+    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_DATE_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_LOCAL_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_DATE_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_OFFSET_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_ORDINAL_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_TIME;
+    field public static final java.time.format.DateTimeFormatter ISO_WEEK_DATE;
+    field public static final java.time.format.DateTimeFormatter ISO_ZONED_DATE_TIME;
+    field public static final java.time.format.DateTimeFormatter RFC_1123_DATE_TIME;
+  }
+
+  public final class DateTimeFormatterBuilder {
+    ctor public DateTimeFormatterBuilder();
+    method public java.time.format.DateTimeFormatterBuilder append(java.time.format.DateTimeFormatter);
+    method public java.time.format.DateTimeFormatterBuilder appendChronologyId();
+    method public java.time.format.DateTimeFormatterBuilder appendChronologyText(java.time.format.TextStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendFraction(java.time.temporal.TemporalField, int, int, boolean);
+    method public java.time.format.DateTimeFormatterBuilder appendInstant();
+    method public java.time.format.DateTimeFormatterBuilder appendInstant(int);
+    method public java.time.format.DateTimeFormatterBuilder appendLiteral(char);
+    method public java.time.format.DateTimeFormatterBuilder appendLiteral(String);
+    method public java.time.format.DateTimeFormatterBuilder appendLocalized(java.time.format.FormatStyle, java.time.format.FormatStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendLocalizedOffset(java.time.format.TextStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendOffset(String, String);
+    method public java.time.format.DateTimeFormatterBuilder appendOffsetId();
+    method public java.time.format.DateTimeFormatterBuilder appendOptional(java.time.format.DateTimeFormatter);
+    method public java.time.format.DateTimeFormatterBuilder appendPattern(String);
+    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField);
+    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField, java.time.format.TextStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendText(java.time.temporal.TemporalField, java.util.Map<java.lang.Long,java.lang.String>);
+    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField);
+    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField, int);
+    method public java.time.format.DateTimeFormatterBuilder appendValue(java.time.temporal.TemporalField, int, int, java.time.format.SignStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendValueReduced(java.time.temporal.TemporalField, int, int, int);
+    method public java.time.format.DateTimeFormatterBuilder appendValueReduced(java.time.temporal.TemporalField, int, int, java.time.chrono.ChronoLocalDate);
+    method public java.time.format.DateTimeFormatterBuilder appendZoneId();
+    method public java.time.format.DateTimeFormatterBuilder appendZoneOrOffsetId();
+    method public java.time.format.DateTimeFormatterBuilder appendZoneRegionId();
+    method public java.time.format.DateTimeFormatterBuilder appendZoneText(java.time.format.TextStyle);
+    method public java.time.format.DateTimeFormatterBuilder appendZoneText(java.time.format.TextStyle, java.util.Set<java.time.ZoneId>);
+    method public static String getLocalizedDateTimePattern(java.time.format.FormatStyle, java.time.format.FormatStyle, java.time.chrono.Chronology, java.util.Locale);
+    method public java.time.format.DateTimeFormatterBuilder optionalEnd();
+    method public java.time.format.DateTimeFormatterBuilder optionalStart();
+    method public java.time.format.DateTimeFormatterBuilder padNext(int);
+    method public java.time.format.DateTimeFormatterBuilder padNext(int, char);
+    method public java.time.format.DateTimeFormatterBuilder parseCaseInsensitive();
+    method public java.time.format.DateTimeFormatterBuilder parseCaseSensitive();
+    method public java.time.format.DateTimeFormatterBuilder parseDefaulting(java.time.temporal.TemporalField, long);
+    method public java.time.format.DateTimeFormatterBuilder parseLenient();
+    method public java.time.format.DateTimeFormatterBuilder parseStrict();
+    method public java.time.format.DateTimeFormatter toFormatter();
+    method public java.time.format.DateTimeFormatter toFormatter(java.util.Locale);
+  }
+
+  public class DateTimeParseException extends java.time.DateTimeException {
+    ctor public DateTimeParseException(String, CharSequence, int);
+    ctor public DateTimeParseException(String, CharSequence, int, Throwable);
+    method public int getErrorIndex();
+    method public String getParsedString();
+  }
+
+  public final class DecimalStyle {
+    method public static java.util.Set<java.util.Locale> getAvailableLocales();
+    method public char getDecimalSeparator();
+    method public char getNegativeSign();
+    method public char getPositiveSign();
+    method public char getZeroDigit();
+    method public static java.time.format.DecimalStyle of(java.util.Locale);
+    method public static java.time.format.DecimalStyle ofDefaultLocale();
+    method public java.time.format.DecimalStyle withDecimalSeparator(char);
+    method public java.time.format.DecimalStyle withNegativeSign(char);
+    method public java.time.format.DecimalStyle withPositiveSign(char);
+    method public java.time.format.DecimalStyle withZeroDigit(char);
+    field public static final java.time.format.DecimalStyle STANDARD;
+  }
+
+  public enum FormatStyle {
+    enum_constant public static final java.time.format.FormatStyle FULL;
+    enum_constant public static final java.time.format.FormatStyle LONG;
+    enum_constant public static final java.time.format.FormatStyle MEDIUM;
+    enum_constant public static final java.time.format.FormatStyle SHORT;
+  }
+
+  public enum ResolverStyle {
+    enum_constant public static final java.time.format.ResolverStyle LENIENT;
+    enum_constant public static final java.time.format.ResolverStyle SMART;
+    enum_constant public static final java.time.format.ResolverStyle STRICT;
+  }
+
+  public enum SignStyle {
+    enum_constant public static final java.time.format.SignStyle ALWAYS;
+    enum_constant public static final java.time.format.SignStyle EXCEEDS_PAD;
+    enum_constant public static final java.time.format.SignStyle NEVER;
+    enum_constant public static final java.time.format.SignStyle NORMAL;
+    enum_constant public static final java.time.format.SignStyle NOT_NEGATIVE;
+  }
+
+  public enum TextStyle {
+    method public java.time.format.TextStyle asNormal();
+    method public java.time.format.TextStyle asStandalone();
+    method public boolean isStandalone();
+    enum_constant public static final java.time.format.TextStyle FULL;
+    enum_constant public static final java.time.format.TextStyle FULL_STANDALONE;
+    enum_constant public static final java.time.format.TextStyle NARROW;
+    enum_constant public static final java.time.format.TextStyle NARROW_STANDALONE;
+    enum_constant public static final java.time.format.TextStyle SHORT;
+    enum_constant public static final java.time.format.TextStyle SHORT_STANDALONE;
+  }
+
+}
+
+package java.time.temporal {
+
+  public enum ChronoField implements java.time.temporal.TemporalField {
+    method public <R extends java.time.temporal.Temporal> R adjustInto(R, long);
+    method public int checkValidIntValue(long);
+    method public long checkValidValue(long);
+    method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public long getFrom(java.time.temporal.TemporalAccessor);
+    method public java.time.temporal.TemporalUnit getRangeUnit();
+    method public boolean isDateBased();
+    method public boolean isSupportedBy(java.time.temporal.TemporalAccessor);
+    method public boolean isTimeBased();
+    method public java.time.temporal.ValueRange range();
+    method public java.time.temporal.ValueRange rangeRefinedBy(java.time.temporal.TemporalAccessor);
+    enum_constant public static final java.time.temporal.ChronoField ALIGNED_DAY_OF_WEEK_IN_MONTH;
+    enum_constant public static final java.time.temporal.ChronoField ALIGNED_DAY_OF_WEEK_IN_YEAR;
+    enum_constant public static final java.time.temporal.ChronoField ALIGNED_WEEK_OF_MONTH;
+    enum_constant public static final java.time.temporal.ChronoField ALIGNED_WEEK_OF_YEAR;
+    enum_constant public static final java.time.temporal.ChronoField AMPM_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField CLOCK_HOUR_OF_AMPM;
+    enum_constant public static final java.time.temporal.ChronoField CLOCK_HOUR_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField DAY_OF_MONTH;
+    enum_constant public static final java.time.temporal.ChronoField DAY_OF_WEEK;
+    enum_constant public static final java.time.temporal.ChronoField DAY_OF_YEAR;
+    enum_constant public static final java.time.temporal.ChronoField EPOCH_DAY;
+    enum_constant public static final java.time.temporal.ChronoField ERA;
+    enum_constant public static final java.time.temporal.ChronoField HOUR_OF_AMPM;
+    enum_constant public static final java.time.temporal.ChronoField HOUR_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField INSTANT_SECONDS;
+    enum_constant public static final java.time.temporal.ChronoField MICRO_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField MICRO_OF_SECOND;
+    enum_constant public static final java.time.temporal.ChronoField MILLI_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField MILLI_OF_SECOND;
+    enum_constant public static final java.time.temporal.ChronoField MINUTE_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField MINUTE_OF_HOUR;
+    enum_constant public static final java.time.temporal.ChronoField MONTH_OF_YEAR;
+    enum_constant public static final java.time.temporal.ChronoField NANO_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField NANO_OF_SECOND;
+    enum_constant public static final java.time.temporal.ChronoField OFFSET_SECONDS;
+    enum_constant public static final java.time.temporal.ChronoField PROLEPTIC_MONTH;
+    enum_constant public static final java.time.temporal.ChronoField SECOND_OF_DAY;
+    enum_constant public static final java.time.temporal.ChronoField SECOND_OF_MINUTE;
+    enum_constant public static final java.time.temporal.ChronoField YEAR;
+    enum_constant public static final java.time.temporal.ChronoField YEAR_OF_ERA;
+  }
+
+  public enum ChronoUnit implements java.time.temporal.TemporalUnit {
+    method public <R extends java.time.temporal.Temporal> R addTo(R, long);
+    method public long between(java.time.temporal.Temporal, java.time.temporal.Temporal);
+    method public java.time.Duration getDuration();
+    method public boolean isDateBased();
+    method public boolean isDurationEstimated();
+    method public boolean isTimeBased();
+    enum_constant public static final java.time.temporal.ChronoUnit CENTURIES;
+    enum_constant public static final java.time.temporal.ChronoUnit DAYS;
+    enum_constant public static final java.time.temporal.ChronoUnit DECADES;
+    enum_constant public static final java.time.temporal.ChronoUnit ERAS;
+    enum_constant public static final java.time.temporal.ChronoUnit FOREVER;
+    enum_constant public static final java.time.temporal.ChronoUnit HALF_DAYS;
+    enum_constant public static final java.time.temporal.ChronoUnit HOURS;
+    enum_constant public static final java.time.temporal.ChronoUnit MICROS;
+    enum_constant public static final java.time.temporal.ChronoUnit MILLENNIA;
+    enum_constant public static final java.time.temporal.ChronoUnit MILLIS;
+    enum_constant public static final java.time.temporal.ChronoUnit MINUTES;
+    enum_constant public static final java.time.temporal.ChronoUnit MONTHS;
+    enum_constant public static final java.time.temporal.ChronoUnit NANOS;
+    enum_constant public static final java.time.temporal.ChronoUnit SECONDS;
+    enum_constant public static final java.time.temporal.ChronoUnit WEEKS;
+    enum_constant public static final java.time.temporal.ChronoUnit YEARS;
+  }
+
+  public final class IsoFields {
+    field public static final java.time.temporal.TemporalField DAY_OF_QUARTER;
+    field public static final java.time.temporal.TemporalField QUARTER_OF_YEAR;
+    field public static final java.time.temporal.TemporalUnit QUARTER_YEARS;
+    field public static final java.time.temporal.TemporalField WEEK_BASED_YEAR;
+    field public static final java.time.temporal.TemporalUnit WEEK_BASED_YEARS;
+    field public static final java.time.temporal.TemporalField WEEK_OF_WEEK_BASED_YEAR;
+  }
+
+  public final class JulianFields {
+    field public static final java.time.temporal.TemporalField JULIAN_DAY;
+    field public static final java.time.temporal.TemporalField MODIFIED_JULIAN_DAY;
+    field public static final java.time.temporal.TemporalField RATA_DIE;
+  }
+
+  public interface Temporal extends java.time.temporal.TemporalAccessor {
+    method public boolean isSupported(java.time.temporal.TemporalUnit);
+    method public default java.time.temporal.Temporal minus(java.time.temporal.TemporalAmount);
+    method public default java.time.temporal.Temporal minus(long, java.time.temporal.TemporalUnit);
+    method public default java.time.temporal.Temporal plus(java.time.temporal.TemporalAmount);
+    method public java.time.temporal.Temporal plus(long, java.time.temporal.TemporalUnit);
+    method public long until(java.time.temporal.Temporal, java.time.temporal.TemporalUnit);
+    method public default java.time.temporal.Temporal with(java.time.temporal.TemporalAdjuster);
+    method public java.time.temporal.Temporal with(java.time.temporal.TemporalField, long);
+  }
+
+  public interface TemporalAccessor {
+    method public default int get(java.time.temporal.TemporalField);
+    method public long getLong(java.time.temporal.TemporalField);
+    method public boolean isSupported(java.time.temporal.TemporalField);
+    method public default <R> R query(java.time.temporal.TemporalQuery<R>);
+    method public default java.time.temporal.ValueRange range(java.time.temporal.TemporalField);
+  }
+
+  @java.lang.FunctionalInterface public interface TemporalAdjuster {
+    method public java.time.temporal.Temporal adjustInto(java.time.temporal.Temporal);
+  }
+
+  public final class TemporalAdjusters {
+    method public static java.time.temporal.TemporalAdjuster dayOfWeekInMonth(int, java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster firstDayOfMonth();
+    method public static java.time.temporal.TemporalAdjuster firstDayOfNextMonth();
+    method public static java.time.temporal.TemporalAdjuster firstDayOfNextYear();
+    method public static java.time.temporal.TemporalAdjuster firstDayOfYear();
+    method public static java.time.temporal.TemporalAdjuster firstInMonth(java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster lastDayOfMonth();
+    method public static java.time.temporal.TemporalAdjuster lastDayOfYear();
+    method public static java.time.temporal.TemporalAdjuster lastInMonth(java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster next(java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster nextOrSame(java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster ofDateAdjuster(java.util.function.UnaryOperator<java.time.LocalDate>);
+    method public static java.time.temporal.TemporalAdjuster previous(java.time.DayOfWeek);
+    method public static java.time.temporal.TemporalAdjuster previousOrSame(java.time.DayOfWeek);
+  }
+
+  public interface TemporalAmount {
+    method public java.time.temporal.Temporal addTo(java.time.temporal.Temporal);
+    method public long get(java.time.temporal.TemporalUnit);
+    method public java.util.List<java.time.temporal.TemporalUnit> getUnits();
+    method public java.time.temporal.Temporal subtractFrom(java.time.temporal.Temporal);
+  }
+
+  public interface TemporalField {
+    method public <R extends java.time.temporal.Temporal> R adjustInto(R, long);
+    method public java.time.temporal.TemporalUnit getBaseUnit();
+    method public default String getDisplayName(java.util.Locale);
+    method public long getFrom(java.time.temporal.TemporalAccessor);
+    method public java.time.temporal.TemporalUnit getRangeUnit();
+    method public boolean isDateBased();
+    method public boolean isSupportedBy(java.time.temporal.TemporalAccessor);
+    method public boolean isTimeBased();
+    method public java.time.temporal.ValueRange range();
+    method public java.time.temporal.ValueRange rangeRefinedBy(java.time.temporal.TemporalAccessor);
+    method public default java.time.temporal.TemporalAccessor resolve(java.util.Map<java.time.temporal.TemporalField,java.lang.Long>, java.time.temporal.TemporalAccessor, java.time.format.ResolverStyle);
+    method public String toString();
+  }
+
+  public final class TemporalQueries {
+    method public static java.time.temporal.TemporalQuery<java.time.chrono.Chronology> chronology();
+    method public static java.time.temporal.TemporalQuery<java.time.LocalDate> localDate();
+    method public static java.time.temporal.TemporalQuery<java.time.LocalTime> localTime();
+    method public static java.time.temporal.TemporalQuery<java.time.ZoneOffset> offset();
+    method public static java.time.temporal.TemporalQuery<java.time.temporal.TemporalUnit> precision();
+    method public static java.time.temporal.TemporalQuery<java.time.ZoneId> zone();
+    method public static java.time.temporal.TemporalQuery<java.time.ZoneId> zoneId();
+  }
+
+  @java.lang.FunctionalInterface public interface TemporalQuery<R> {
+    method public R queryFrom(java.time.temporal.TemporalAccessor);
+  }
+
+  public interface TemporalUnit {
+    method public <R extends java.time.temporal.Temporal> R addTo(R, long);
+    method public long between(java.time.temporal.Temporal, java.time.temporal.Temporal);
+    method public java.time.Duration getDuration();
+    method public boolean isDateBased();
+    method public boolean isDurationEstimated();
+    method public default boolean isSupportedBy(java.time.temporal.Temporal);
+    method public boolean isTimeBased();
+    method public String toString();
+  }
+
+  public class UnsupportedTemporalTypeException extends java.time.DateTimeException {
+    ctor public UnsupportedTemporalTypeException(String);
+    ctor public UnsupportedTemporalTypeException(String, Throwable);
+  }
+
+  public final class ValueRange implements java.io.Serializable {
+    method public int checkValidIntValue(long, java.time.temporal.TemporalField);
+    method public long checkValidValue(long, java.time.temporal.TemporalField);
+    method public long getLargestMinimum();
+    method public long getMaximum();
+    method public long getMinimum();
+    method public long getSmallestMaximum();
+    method public boolean isFixed();
+    method public boolean isIntValue();
+    method public boolean isValidIntValue(long);
+    method public boolean isValidValue(long);
+    method public static java.time.temporal.ValueRange of(long, long);
+    method public static java.time.temporal.ValueRange of(long, long, long);
+    method public static java.time.temporal.ValueRange of(long, long, long, long);
+  }
+
+  public final class WeekFields implements java.io.Serializable {
+    method public java.time.temporal.TemporalField dayOfWeek();
+    method public java.time.DayOfWeek getFirstDayOfWeek();
+    method public int getMinimalDaysInFirstWeek();
+    method public static java.time.temporal.WeekFields of(java.util.Locale);
+    method public static java.time.temporal.WeekFields of(java.time.DayOfWeek, int);
+    method public java.time.temporal.TemporalField weekBasedYear();
+    method public java.time.temporal.TemporalField weekOfMonth();
+    method public java.time.temporal.TemporalField weekOfWeekBasedYear();
+    method public java.time.temporal.TemporalField weekOfYear();
+    field public static final java.time.temporal.WeekFields ISO;
+    field public static final java.time.temporal.WeekFields SUNDAY_START;
+    field public static final java.time.temporal.TemporalUnit WEEK_BASED_YEARS;
+  }
+
+}
+
+package java.time.zone {
+
+  public final class ZoneOffsetTransition implements java.lang.Comparable<java.time.zone.ZoneOffsetTransition> java.io.Serializable {
+    method public int compareTo(java.time.zone.ZoneOffsetTransition);
+    method public java.time.LocalDateTime getDateTimeAfter();
+    method public java.time.LocalDateTime getDateTimeBefore();
+    method public java.time.Duration getDuration();
+    method public java.time.Instant getInstant();
+    method public java.time.ZoneOffset getOffsetAfter();
+    method public java.time.ZoneOffset getOffsetBefore();
+    method public boolean isGap();
+    method public boolean isOverlap();
+    method public boolean isValidOffset(java.time.ZoneOffset);
+    method public static java.time.zone.ZoneOffsetTransition of(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneOffset);
+    method public long toEpochSecond();
+  }
+
+  public final class ZoneOffsetTransitionRule implements java.io.Serializable {
+    method public java.time.zone.ZoneOffsetTransition createTransition(int);
+    method public int getDayOfMonthIndicator();
+    method public java.time.DayOfWeek getDayOfWeek();
+    method public java.time.LocalTime getLocalTime();
+    method public java.time.Month getMonth();
+    method public java.time.ZoneOffset getOffsetAfter();
+    method public java.time.ZoneOffset getOffsetBefore();
+    method public java.time.ZoneOffset getStandardOffset();
+    method public java.time.zone.ZoneOffsetTransitionRule.TimeDefinition getTimeDefinition();
+    method public boolean isMidnightEndOfDay();
+    method public static java.time.zone.ZoneOffsetTransitionRule of(java.time.Month, int, java.time.DayOfWeek, java.time.LocalTime, boolean, java.time.zone.ZoneOffsetTransitionRule.TimeDefinition, java.time.ZoneOffset, java.time.ZoneOffset, java.time.ZoneOffset);
+  }
+
+  public enum ZoneOffsetTransitionRule.TimeDefinition {
+    method public java.time.LocalDateTime createDateTime(java.time.LocalDateTime, java.time.ZoneOffset, java.time.ZoneOffset);
+    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition STANDARD;
+    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition UTC;
+    enum_constant public static final java.time.zone.ZoneOffsetTransitionRule.TimeDefinition WALL;
+  }
+
+  public final class ZoneRules implements java.io.Serializable {
+    method public java.time.Duration getDaylightSavings(java.time.Instant);
+    method public java.time.ZoneOffset getOffset(java.time.Instant);
+    method public java.time.ZoneOffset getOffset(java.time.LocalDateTime);
+    method public java.time.ZoneOffset getStandardOffset(java.time.Instant);
+    method public java.time.zone.ZoneOffsetTransition getTransition(java.time.LocalDateTime);
+    method public java.util.List<java.time.zone.ZoneOffsetTransitionRule> getTransitionRules();
+    method public java.util.List<java.time.zone.ZoneOffsetTransition> getTransitions();
+    method public java.util.List<java.time.ZoneOffset> getValidOffsets(java.time.LocalDateTime);
+    method public boolean isDaylightSavings(java.time.Instant);
+    method public boolean isFixedOffset();
+    method public boolean isValidOffset(java.time.LocalDateTime, java.time.ZoneOffset);
+    method public java.time.zone.ZoneOffsetTransition nextTransition(java.time.Instant);
+    method public static java.time.zone.ZoneRules of(java.time.ZoneOffset, java.time.ZoneOffset, java.util.List<java.time.zone.ZoneOffsetTransition>, java.util.List<java.time.zone.ZoneOffsetTransition>, java.util.List<java.time.zone.ZoneOffsetTransitionRule>);
+    method public static java.time.zone.ZoneRules of(java.time.ZoneOffset);
+    method public java.time.zone.ZoneOffsetTransition previousTransition(java.time.Instant);
+  }
+
+  public class ZoneRulesException extends java.time.DateTimeException {
+    ctor public ZoneRulesException(String);
+    ctor public ZoneRulesException(String, Throwable);
+  }
+
+}
+
+package java.util {
+
+  public abstract class AbstractCollection<E> implements java.util.Collection<E> {
+    ctor protected AbstractCollection();
+    method public boolean add(E);
+    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
+    method public void clear();
+    method public boolean contains(@Nullable Object);
+    method public boolean containsAll(@NonNull java.util.Collection<?>);
+    method public boolean isEmpty();
+    method public boolean remove(@Nullable Object);
+    method public boolean removeAll(@NonNull java.util.Collection<?>);
+    method public boolean retainAll(@NonNull java.util.Collection<?>);
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
+  }
+
+  public abstract class AbstractList<E> extends java.util.AbstractCollection<E> implements java.util.List<E> {
+    ctor protected AbstractList();
+    method public void add(int, E);
+    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
+    method public int indexOf(@Nullable Object);
+    method @NonNull public java.util.Iterator<E> iterator();
+    method public int lastIndexOf(@Nullable Object);
+    method @NonNull public java.util.ListIterator<E> listIterator();
+    method @NonNull public java.util.ListIterator<E> listIterator(int);
+    method public E remove(int);
+    method protected void removeRange(int, int);
+    method public E set(int, E);
+    method @NonNull public java.util.List<E> subList(int, int);
+    field protected transient int modCount;
+  }
+
+  public abstract class AbstractMap<K, V> implements java.util.Map<K,V> {
+    ctor protected AbstractMap();
+    method public void clear();
+    method public boolean containsKey(@Nullable Object);
+    method public boolean containsValue(@Nullable Object);
+    method @Nullable public V get(@Nullable Object);
+    method public boolean isEmpty();
+    method @NonNull public java.util.Set<K> keySet();
+    method @Nullable public V put(K, V);
+    method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
+    method @Nullable public V remove(@Nullable Object);
+    method public int size();
+    method @NonNull public java.util.Collection<V> values();
+  }
+
+  public static class AbstractMap.SimpleEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
+    ctor public AbstractMap.SimpleEntry(K, V);
+    ctor public AbstractMap.SimpleEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
+    method public K getKey();
+    method public V getValue();
+    method public V setValue(V);
+  }
+
+  public static class AbstractMap.SimpleImmutableEntry<K, V> implements java.util.Map.Entry<K,V> java.io.Serializable {
+    ctor public AbstractMap.SimpleImmutableEntry(K, V);
+    ctor public AbstractMap.SimpleImmutableEntry(@NonNull java.util.Map.Entry<? extends K,? extends V>);
+    method public K getKey();
+    method public V getValue();
+    method public V setValue(V);
+  }
+
+  public abstract class AbstractQueue<E> extends java.util.AbstractCollection<E> implements java.util.Queue<E> {
+    ctor protected AbstractQueue();
+    method public E element();
+    method public E remove();
+  }
+
+  public abstract class AbstractSequentialList<E> extends java.util.AbstractList<E> {
+    ctor protected AbstractSequentialList();
+    method public E get(int);
+  }
+
+  public abstract class AbstractSet<E> extends java.util.AbstractCollection<E> implements java.util.Set<E> {
+    ctor protected AbstractSet();
+  }
+
+  public class ArrayDeque<E> extends java.util.AbstractCollection<E> implements java.lang.Cloneable java.util.Deque<E> java.io.Serializable {
+    ctor public ArrayDeque();
+    ctor public ArrayDeque(int);
+    ctor public ArrayDeque(@NonNull java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method @NonNull public java.util.ArrayDeque<E> clone();
+    method @NonNull public java.util.Iterator<E> descendingIterator();
+    method public E element();
+    method public E getFirst();
+    method public E getLast();
+    method @NonNull public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method @Nullable public E peek();
+    method @Nullable public E peekFirst();
+    method @Nullable public E peekLast();
+    method @Nullable public E poll();
+    method @Nullable public E pollFirst();
+    method @Nullable public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E remove();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(@Nullable Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(@Nullable Object);
+    method public int size();
+  }
+
+  public class ArrayList<E> extends java.util.AbstractList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
+    ctor public ArrayList(int);
+    ctor public ArrayList();
+    ctor public ArrayList(@NonNull java.util.Collection<? extends E>);
+    method @NonNull public Object clone();
+    method public void ensureCapacity(int);
+    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
+    method public E get(int);
+    method public int size();
+    method public void trimToSize();
+  }
+
+  public class Arrays {
+    method @NonNull @java.lang.SafeVarargs public static <T> java.util.List<T> asList(@NonNull T...);
+    method public static int binarySearch(@NonNull long[], long);
+    method public static int binarySearch(@NonNull long[], int, int, long);
+    method public static int binarySearch(@NonNull int[], int);
+    method public static int binarySearch(@NonNull int[], int, int, int);
+    method public static int binarySearch(@NonNull short[], short);
+    method public static int binarySearch(@NonNull short[], int, int, short);
+    method public static int binarySearch(@NonNull char[], char);
+    method public static int binarySearch(@NonNull char[], int, int, char);
+    method public static int binarySearch(@NonNull byte[], byte);
+    method public static int binarySearch(@NonNull byte[], int, int, byte);
+    method public static int binarySearch(@NonNull double[], double);
+    method public static int binarySearch(@NonNull double[], int, int, double);
+    method public static int binarySearch(@NonNull float[], float);
+    method public static int binarySearch(@NonNull float[], int, int, float);
+    method public static int binarySearch(@NonNull Object[], @NonNull Object);
+    method public static int binarySearch(@NonNull Object[], int, int, @NonNull Object);
+    method public static <T> int binarySearch(@NonNull T[], T, @Nullable java.util.Comparator<? super T>);
+    method public static <T> int binarySearch(@NonNull T[], int, int, T, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T> T[] copyOf(@NonNull T[], int);
+    method @NonNull public static <T, U> T[] copyOf(@NonNull U[], int, @NonNull Class<? extends T[]>);
+    method @NonNull public static byte[] copyOf(@NonNull byte[], int);
+    method @NonNull public static short[] copyOf(@NonNull short[], int);
+    method @NonNull public static int[] copyOf(@NonNull int[], int);
+    method @NonNull public static long[] copyOf(@NonNull long[], int);
+    method @NonNull public static char[] copyOf(@NonNull char[], int);
+    method @NonNull public static float[] copyOf(@NonNull float[], int);
+    method @NonNull public static double[] copyOf(@NonNull double[], int);
+    method @NonNull public static boolean[] copyOf(@NonNull boolean[], int);
+    method @NonNull public static <T> T[] copyOfRange(@NonNull T[], int, int);
+    method @NonNull public static <T, U> T[] copyOfRange(@NonNull U[], int, int, @NonNull Class<? extends T[]>);
+    method @NonNull public static byte[] copyOfRange(@NonNull byte[], int, int);
+    method @NonNull public static short[] copyOfRange(@NonNull short[], int, int);
+    method @NonNull public static int[] copyOfRange(@NonNull int[], int, int);
+    method @NonNull public static long[] copyOfRange(@NonNull long[], int, int);
+    method @NonNull public static char[] copyOfRange(@NonNull char[], int, int);
+    method @NonNull public static float[] copyOfRange(@NonNull float[], int, int);
+    method @NonNull public static double[] copyOfRange(@NonNull double[], int, int);
+    method @NonNull public static boolean[] copyOfRange(@NonNull boolean[], int, int);
+    method public static boolean deepEquals(@Nullable Object[], @Nullable Object[]);
+    method public static int deepHashCode(@Nullable Object[]);
+    method @NonNull public static String deepToString(@Nullable Object[]);
+    method public static boolean equals(@Nullable long[], @Nullable long[]);
+    method public static boolean equals(@Nullable int[], @Nullable int[]);
+    method public static boolean equals(@Nullable short[], @Nullable short[]);
+    method public static boolean equals(@Nullable char[], @Nullable char[]);
+    method public static boolean equals(@Nullable byte[], @Nullable byte[]);
+    method public static boolean equals(@Nullable boolean[], @Nullable boolean[]);
+    method public static boolean equals(@Nullable double[], @Nullable double[]);
+    method public static boolean equals(@Nullable float[], @Nullable float[]);
+    method public static boolean equals(@Nullable Object[], @Nullable Object[]);
+    method public static void fill(@NonNull long[], long);
+    method public static void fill(@NonNull long[], int, int, long);
+    method public static void fill(@NonNull int[], int);
+    method public static void fill(@NonNull int[], int, int, int);
+    method public static void fill(@NonNull short[], short);
+    method public static void fill(@NonNull short[], int, int, short);
+    method public static void fill(@NonNull char[], char);
+    method public static void fill(@NonNull char[], int, int, char);
+    method public static void fill(@NonNull byte[], byte);
+    method public static void fill(@NonNull byte[], int, int, byte);
+    method public static void fill(@NonNull boolean[], boolean);
+    method public static void fill(@NonNull boolean[], int, int, boolean);
+    method public static void fill(@NonNull double[], double);
+    method public static void fill(@NonNull double[], int, int, double);
+    method public static void fill(@NonNull float[], float);
+    method public static void fill(@NonNull float[], int, int, float);
+    method public static void fill(@NonNull Object[], @Nullable Object);
+    method public static void fill(@NonNull Object[], int, int, @Nullable Object);
+    method public static int hashCode(@Nullable long[]);
+    method public static int hashCode(@Nullable int[]);
+    method public static int hashCode(@Nullable short[]);
+    method public static int hashCode(@Nullable char[]);
+    method public static int hashCode(@Nullable byte[]);
+    method public static int hashCode(@Nullable boolean[]);
+    method public static int hashCode(@Nullable float[]);
+    method public static int hashCode(@Nullable double[]);
+    method public static int hashCode(@Nullable Object[]);
+    method public static <T> void parallelPrefix(@NonNull T[], @NonNull java.util.function.BinaryOperator<T>);
+    method public static <T> void parallelPrefix(@NonNull T[], int, int, @NonNull java.util.function.BinaryOperator<T>);
+    method public static void parallelPrefix(@NonNull long[], @NonNull java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(@NonNull long[], int, int, @NonNull java.util.function.LongBinaryOperator);
+    method public static void parallelPrefix(@NonNull double[], @NonNull java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(@NonNull double[], int, int, @NonNull java.util.function.DoubleBinaryOperator);
+    method public static void parallelPrefix(@NonNull int[], @NonNull java.util.function.IntBinaryOperator);
+    method public static void parallelPrefix(@NonNull int[], int, int, @NonNull java.util.function.IntBinaryOperator);
+    method public static <T> void parallelSetAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
+    method public static void parallelSetAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
+    method public static void parallelSetAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
+    method public static void parallelSetAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
+    method public static void parallelSort(@NonNull byte[]);
+    method public static void parallelSort(@NonNull byte[], int, int);
+    method public static void parallelSort(@NonNull char[]);
+    method public static void parallelSort(@NonNull char[], int, int);
+    method public static void parallelSort(@NonNull short[]);
+    method public static void parallelSort(@NonNull short[], int, int);
+    method public static void parallelSort(@NonNull int[]);
+    method public static void parallelSort(@NonNull int[], int, int);
+    method public static void parallelSort(@NonNull long[]);
+    method public static void parallelSort(@NonNull long[], int, int);
+    method public static void parallelSort(@NonNull float[]);
+    method public static void parallelSort(@NonNull float[], int, int);
+    method public static void parallelSort(@NonNull double[]);
+    method public static void parallelSort(@NonNull double[], int, int);
+    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[]);
+    method public static <T extends java.lang.Comparable<? super T>> void parallelSort(@NonNull T[], int, int);
+    method public static <T> void parallelSort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
+    method public static <T> void parallelSort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
+    method public static <T> void setAll(@NonNull T[], @NonNull java.util.function.IntFunction<? extends T>);
+    method public static void setAll(@NonNull int[], @NonNull java.util.function.IntUnaryOperator);
+    method public static void setAll(@NonNull long[], @NonNull java.util.function.IntToLongFunction);
+    method public static void setAll(@NonNull double[], @NonNull java.util.function.IntToDoubleFunction);
+    method public static void sort(@NonNull int[]);
+    method public static void sort(@NonNull int[], int, int);
+    method public static void sort(@NonNull long[]);
+    method public static void sort(@NonNull long[], int, int);
+    method public static void sort(@NonNull short[]);
+    method public static void sort(@NonNull short[], int, int);
+    method public static void sort(@NonNull char[]);
+    method public static void sort(@NonNull char[], int, int);
+    method public static void sort(@NonNull byte[]);
+    method public static void sort(@NonNull byte[], int, int);
+    method public static void sort(@NonNull float[]);
+    method public static void sort(@NonNull float[], int, int);
+    method public static void sort(@NonNull double[]);
+    method public static void sort(@NonNull double[], int, int);
+    method public static void sort(@NonNull Object[]);
+    method public static void sort(@NonNull Object[], int, int);
+    method public static <T> void sort(@NonNull T[], @Nullable java.util.Comparator<? super T>);
+    method public static <T> void sort(@NonNull T[], int, int, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[]);
+    method @NonNull public static <T> java.util.Spliterator<T> spliterator(@NonNull T[], int, int);
+    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[]);
+    method @NonNull public static java.util.Spliterator.OfInt spliterator(@NonNull int[], int, int);
+    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[]);
+    method @NonNull public static java.util.Spliterator.OfLong spliterator(@NonNull long[], int, int);
+    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[]);
+    method @NonNull public static java.util.Spliterator.OfDouble spliterator(@NonNull double[], int, int);
+    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[]);
+    method @NonNull public static <T> java.util.stream.Stream<T> stream(@NonNull T[], int, int);
+    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[]);
+    method @NonNull public static java.util.stream.IntStream stream(@NonNull int[], int, int);
+    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[]);
+    method @NonNull public static java.util.stream.LongStream stream(@NonNull long[], int, int);
+    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[]);
+    method @NonNull public static java.util.stream.DoubleStream stream(@NonNull double[], int, int);
+    method @NonNull public static String toString(@Nullable long[]);
+    method @NonNull public static String toString(@Nullable int[]);
+    method @NonNull public static String toString(@Nullable short[]);
+    method @NonNull public static String toString(@Nullable char[]);
+    method @NonNull public static String toString(@Nullable byte[]);
+    method @NonNull public static String toString(@Nullable boolean[]);
+    method @NonNull public static String toString(@Nullable float[]);
+    method @NonNull public static String toString(@Nullable double[]);
+    method @NonNull public static String toString(@Nullable Object[]);
+  }
+
+  public class Base64 {
+    method public static java.util.Base64.Decoder getDecoder();
+    method public static java.util.Base64.Encoder getEncoder();
+    method public static java.util.Base64.Decoder getMimeDecoder();
+    method public static java.util.Base64.Encoder getMimeEncoder();
+    method public static java.util.Base64.Encoder getMimeEncoder(int, byte[]);
+    method public static java.util.Base64.Decoder getUrlDecoder();
+    method public static java.util.Base64.Encoder getUrlEncoder();
+  }
+
+  public static class Base64.Decoder {
+    method public byte[] decode(byte[]);
+    method public byte[] decode(String);
+    method public int decode(byte[], byte[]);
+    method public java.nio.ByteBuffer decode(java.nio.ByteBuffer);
+    method public java.io.InputStream wrap(java.io.InputStream);
+  }
+
+  public static class Base64.Encoder {
+    method public byte[] encode(byte[]);
+    method public int encode(byte[], byte[]);
+    method public java.nio.ByteBuffer encode(java.nio.ByteBuffer);
+    method public String encodeToString(byte[]);
+    method public java.util.Base64.Encoder withoutPadding();
+    method public java.io.OutputStream wrap(java.io.OutputStream);
+  }
+
+  public class BitSet implements java.lang.Cloneable java.io.Serializable {
+    ctor public BitSet();
+    ctor public BitSet(int);
+    method public void and(java.util.BitSet);
+    method public void andNot(java.util.BitSet);
+    method public int cardinality();
+    method public void clear(int);
+    method public void clear(int, int);
+    method public void clear();
+    method public Object clone();
+    method public void flip(int);
+    method public void flip(int, int);
+    method public boolean get(int);
+    method public java.util.BitSet get(int, int);
+    method public boolean intersects(java.util.BitSet);
+    method public boolean isEmpty();
+    method public int length();
+    method public int nextClearBit(int);
+    method public int nextSetBit(int);
+    method public void or(java.util.BitSet);
+    method public int previousClearBit(int);
+    method public int previousSetBit(int);
+    method public void set(int);
+    method public void set(int, boolean);
+    method public void set(int, int);
+    method public void set(int, int, boolean);
+    method public int size();
+    method public java.util.stream.IntStream stream();
+    method public byte[] toByteArray();
+    method public long[] toLongArray();
+    method public static java.util.BitSet valueOf(long[]);
+    method public static java.util.BitSet valueOf(java.nio.LongBuffer);
+    method public static java.util.BitSet valueOf(byte[]);
+    method public static java.util.BitSet valueOf(java.nio.ByteBuffer);
+    method public void xor(java.util.BitSet);
+  }
+
+  public abstract class Calendar implements java.lang.Cloneable java.lang.Comparable<java.util.Calendar> java.io.Serializable {
+    ctor protected Calendar();
+    ctor protected Calendar(@NonNull java.util.TimeZone, @NonNull java.util.Locale);
+    method public abstract void add(int, int);
+    method public boolean after(@Nullable Object);
+    method public boolean before(@Nullable Object);
+    method public final void clear();
+    method public final void clear(int);
+    method @NonNull public Object clone();
+    method public int compareTo(@NonNull java.util.Calendar);
+    method protected void complete();
+    method protected abstract void computeFields();
+    method protected abstract void computeTime();
+    method public int get(int);
+    method public int getActualMaximum(int);
+    method public int getActualMinimum(int);
+    method @NonNull public static java.util.Set<java.lang.String> getAvailableCalendarTypes();
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public String getCalendarType();
+    method @Nullable public String getDisplayName(int, int, @NonNull java.util.Locale);
+    method @Nullable public java.util.Map<java.lang.String,java.lang.Integer> getDisplayNames(int, int, @NonNull java.util.Locale);
+    method public int getFirstDayOfWeek();
+    method public abstract int getGreatestMinimum(int);
+    method @NonNull public static java.util.Calendar getInstance();
+    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.TimeZone);
+    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.Locale);
+    method @NonNull public static java.util.Calendar getInstance(@NonNull java.util.TimeZone, @NonNull java.util.Locale);
+    method public abstract int getLeastMaximum(int);
+    method public abstract int getMaximum(int);
+    method public int getMinimalDaysInFirstWeek();
+    method public abstract int getMinimum(int);
+    method @NonNull public final java.util.Date getTime();
+    method public long getTimeInMillis();
+    method @NonNull public java.util.TimeZone getTimeZone();
+    method public int getWeekYear();
+    method public int getWeeksInWeekYear();
+    method protected final int internalGet(int);
+    method public boolean isLenient();
+    method public final boolean isSet(int);
+    method public boolean isWeekDateSupported();
+    method public abstract void roll(int, boolean);
+    method public void roll(int, int);
+    method public void set(int, int);
+    method public final void set(int, int, int);
+    method public final void set(int, int, int, int, int);
+    method public final void set(int, int, int, int, int, int);
+    method public void setFirstDayOfWeek(int);
+    method public void setLenient(boolean);
+    method public void setMinimalDaysInFirstWeek(int);
+    method public final void setTime(@NonNull java.util.Date);
+    method public void setTimeInMillis(long);
+    method public void setTimeZone(@NonNull java.util.TimeZone);
+    method public void setWeekDate(int, int, int);
+    method @NonNull public final java.time.Instant toInstant();
+    field public static final int ALL_STYLES = 0; // 0x0
+    field public static final int AM = 0; // 0x0
+    field public static final int AM_PM = 9; // 0x9
+    field public static final int APRIL = 3; // 0x3
+    field public static final int AUGUST = 7; // 0x7
+    field public static final int DATE = 5; // 0x5
+    field public static final int DAY_OF_MONTH = 5; // 0x5
+    field public static final int DAY_OF_WEEK = 7; // 0x7
+    field public static final int DAY_OF_WEEK_IN_MONTH = 8; // 0x8
+    field public static final int DAY_OF_YEAR = 6; // 0x6
+    field public static final int DECEMBER = 11; // 0xb
+    field public static final int DST_OFFSET = 16; // 0x10
+    field public static final int ERA = 0; // 0x0
+    field public static final int FEBRUARY = 1; // 0x1
+    field public static final int FIELD_COUNT = 17; // 0x11
+    field public static final int FRIDAY = 6; // 0x6
+    field public static final int HOUR = 10; // 0xa
+    field public static final int HOUR_OF_DAY = 11; // 0xb
+    field public static final int JANUARY = 0; // 0x0
+    field public static final int JULY = 6; // 0x6
+    field public static final int JUNE = 5; // 0x5
+    field public static final int LONG = 2; // 0x2
+    field public static final int LONG_FORMAT = 2; // 0x2
+    field public static final int LONG_STANDALONE = 32770; // 0x8002
+    field public static final int MARCH = 2; // 0x2
+    field public static final int MAY = 4; // 0x4
+    field public static final int MILLISECOND = 14; // 0xe
+    field public static final int MINUTE = 12; // 0xc
+    field public static final int MONDAY = 2; // 0x2
+    field public static final int MONTH = 2; // 0x2
+    field public static final int NARROW_FORMAT = 4; // 0x4
+    field public static final int NARROW_STANDALONE = 32772; // 0x8004
+    field public static final int NOVEMBER = 10; // 0xa
+    field public static final int OCTOBER = 9; // 0x9
+    field public static final int PM = 1; // 0x1
+    field public static final int SATURDAY = 7; // 0x7
+    field public static final int SECOND = 13; // 0xd
+    field public static final int SEPTEMBER = 8; // 0x8
+    field public static final int SHORT = 1; // 0x1
+    field public static final int SHORT_FORMAT = 1; // 0x1
+    field public static final int SHORT_STANDALONE = 32769; // 0x8001
+    field public static final int SUNDAY = 1; // 0x1
+    field public static final int THURSDAY = 5; // 0x5
+    field public static final int TUESDAY = 3; // 0x3
+    field public static final int UNDECIMBER = 12; // 0xc
+    field public static final int WEDNESDAY = 4; // 0x4
+    field public static final int WEEK_OF_MONTH = 4; // 0x4
+    field public static final int WEEK_OF_YEAR = 3; // 0x3
+    field public static final int YEAR = 1; // 0x1
+    field public static final int ZONE_OFFSET = 15; // 0xf
+    field protected boolean areFieldsSet;
+    field @NonNull protected int[] fields;
+    field @NonNull protected boolean[] isSet;
+    field protected boolean isTimeSet;
+    field protected long time;
+  }
+
+  public static class Calendar.Builder {
+    ctor public Calendar.Builder();
+    method @NonNull public java.util.Calendar build();
+    method @NonNull public java.util.Calendar.Builder set(int, int);
+    method @NonNull public java.util.Calendar.Builder setCalendarType(@NonNull String);
+    method @NonNull public java.util.Calendar.Builder setDate(int, int, int);
+    method @NonNull public java.util.Calendar.Builder setFields(@NonNull int...);
+    method @NonNull public java.util.Calendar.Builder setInstant(long);
+    method @NonNull public java.util.Calendar.Builder setInstant(@NonNull java.util.Date);
+    method @NonNull public java.util.Calendar.Builder setLenient(boolean);
+    method @NonNull public java.util.Calendar.Builder setLocale(@NonNull java.util.Locale);
+    method @NonNull public java.util.Calendar.Builder setTimeOfDay(int, int, int);
+    method @NonNull public java.util.Calendar.Builder setTimeOfDay(int, int, int, int);
+    method @NonNull public java.util.Calendar.Builder setTimeZone(@NonNull java.util.TimeZone);
+    method @NonNull public java.util.Calendar.Builder setWeekDate(int, int, int);
+    method @NonNull public java.util.Calendar.Builder setWeekDefinition(int, int);
+  }
+
+  public interface Collection<E> extends java.lang.Iterable<E> {
+    method public boolean add(E);
+    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
+    method public void clear();
+    method public boolean contains(@Nullable Object);
+    method public boolean containsAll(@NonNull java.util.Collection<?>);
+    method public boolean equals(@Nullable Object);
+    method public int hashCode();
+    method public boolean isEmpty();
+    method @NonNull public java.util.Iterator<E> iterator();
+    method @NonNull public default java.util.stream.Stream<E> parallelStream();
+    method public boolean remove(@Nullable Object);
+    method public boolean removeAll(@NonNull java.util.Collection<?>);
+    method public default boolean removeIf(@NonNull java.util.function.Predicate<? super E>);
+    method public boolean retainAll(@NonNull java.util.Collection<?>);
+    method public int size();
+    method @NonNull public default java.util.Spliterator<E> spliterator();
+    method @NonNull public default java.util.stream.Stream<E> stream();
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
+  }
+
+  public class Collections {
+    method @java.lang.SafeVarargs public static <T> boolean addAll(@NonNull java.util.Collection<? super T>, @NonNull T...);
+    method @NonNull public static <T> java.util.Queue<T> asLifoQueue(@NonNull java.util.Deque<T>);
+    method public static <T> int binarySearch(@NonNull java.util.List<? extends java.lang.Comparable<? super T>>, @NonNull T);
+    method public static <T> int binarySearch(@NonNull java.util.List<? extends T>, T, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <E> java.util.Collection<E> checkedCollection(@NonNull java.util.Collection<E>, @NonNull Class<E>);
+    method @NonNull public static <E> java.util.List<E> checkedList(@NonNull java.util.List<E>, @NonNull Class<E>);
+    method @NonNull public static <K, V> java.util.Map<K,V> checkedMap(@NonNull java.util.Map<K,V>, @NonNull Class<K>, @NonNull Class<V>);
+    method @NonNull public static <K, V> java.util.NavigableMap<K,V> checkedNavigableMap(@NonNull java.util.NavigableMap<K,V>, @NonNull Class<K>, @NonNull Class<V>);
+    method @NonNull public static <E> java.util.NavigableSet<E> checkedNavigableSet(@NonNull java.util.NavigableSet<E>, @NonNull Class<E>);
+    method @NonNull public static <E> java.util.Queue<E> checkedQueue(@NonNull java.util.Queue<E>, @NonNull Class<E>);
+    method @NonNull public static <E> java.util.Set<E> checkedSet(@NonNull java.util.Set<E>, @NonNull Class<E>);
+    method @NonNull public static <K, V> java.util.SortedMap<K,V> checkedSortedMap(@NonNull java.util.SortedMap<K,V>, @NonNull Class<K>, @NonNull Class<V>);
+    method @NonNull public static <E> java.util.SortedSet<E> checkedSortedSet(@NonNull java.util.SortedSet<E>, @NonNull Class<E>);
+    method public static <T> void copy(@NonNull java.util.List<? super T>, @NonNull java.util.List<? extends T>);
+    method public static boolean disjoint(@NonNull java.util.Collection<?>, @NonNull java.util.Collection<?>);
+    method @NonNull public static <T> java.util.Enumeration<T> emptyEnumeration();
+    method @NonNull public static <T> java.util.Iterator<T> emptyIterator();
+    method @NonNull public static final <T> java.util.List<T> emptyList();
+    method @NonNull public static <T> java.util.ListIterator<T> emptyListIterator();
+    method @NonNull public static final <K, V> java.util.Map<K,V> emptyMap();
+    method @NonNull public static final <K, V> java.util.NavigableMap<K,V> emptyNavigableMap();
+    method @NonNull public static <E> java.util.NavigableSet<E> emptyNavigableSet();
+    method @NonNull public static final <T> java.util.Set<T> emptySet();
+    method @NonNull public static final <K, V> java.util.SortedMap<K,V> emptySortedMap();
+    method @NonNull public static <E> java.util.SortedSet<E> emptySortedSet();
+    method @NonNull public static <T> java.util.Enumeration<T> enumeration(@NonNull java.util.Collection<T>);
+    method public static <T> void fill(@NonNull java.util.List<? super T>, T);
+    method public static int frequency(@NonNull java.util.Collection<?>, @Nullable Object);
+    method public static int indexOfSubList(@NonNull java.util.List<?>, @NonNull java.util.List<?>);
+    method public static int lastIndexOfSubList(@NonNull java.util.List<?>, @NonNull java.util.List<?>);
+    method @NonNull public static <T> java.util.ArrayList<T> list(@NonNull java.util.Enumeration<T>);
+    method @NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T max(@NonNull java.util.Collection<? extends T>);
+    method public static <T> T max(@NonNull java.util.Collection<? extends T>, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T extends java.lang.Object & java.lang.Comparable<? super T>> T min(@NonNull java.util.Collection<? extends T>);
+    method public static <T> T min(@NonNull java.util.Collection<? extends T>, @Nullable java.util.Comparator<? super T>);
+    method @NonNull public static <T> java.util.List<T> nCopies(int, T);
+    method @NonNull public static <E> java.util.Set<E> newSetFromMap(@NonNull java.util.Map<E,java.lang.Boolean>);
+    method public static <T> boolean replaceAll(@NonNull java.util.List<T>, T, T);
+    method public static void reverse(@NonNull java.util.List<?>);
+    method @NonNull public static <T> java.util.Comparator<T> reverseOrder();
+    method @NonNull public static <T> java.util.Comparator<T> reverseOrder(@Nullable java.util.Comparator<T>);
+    method public static void rotate(@NonNull java.util.List<?>, int);
+    method public static void shuffle(@NonNull java.util.List<?>);
+    method public static void shuffle(@NonNull java.util.List<?>, @NonNull java.util.Random);
+    method @NonNull public static <T> java.util.Set<T> singleton(T);
+    method @NonNull public static <T> java.util.List<T> singletonList(T);
+    method @NonNull public static <K, V> java.util.Map<K,V> singletonMap(K, V);
+    method public static <T extends java.lang.Comparable<? super T>> void sort(@NonNull java.util.List<T>);
+    method public static <T> void sort(@NonNull java.util.List<T>, @Nullable java.util.Comparator<? super T>);
+    method public static void swap(@NonNull java.util.List<?>, int, int);
+    method @NonNull public static <T> java.util.Collection<T> synchronizedCollection(@NonNull java.util.Collection<T>);
+    method @NonNull public static <T> java.util.List<T> synchronizedList(@NonNull java.util.List<T>);
+    method @NonNull public static <K, V> java.util.Map<K,V> synchronizedMap(@NonNull java.util.Map<K,V>);
+    method @NonNull public static <K, V> java.util.NavigableMap<K,V> synchronizedNavigableMap(@NonNull java.util.NavigableMap<K,V>);
+    method @NonNull public static <T> java.util.NavigableSet<T> synchronizedNavigableSet(@NonNull java.util.NavigableSet<T>);
+    method @NonNull public static <T> java.util.Set<T> synchronizedSet(@NonNull java.util.Set<T>);
+    method @NonNull public static <K, V> java.util.SortedMap<K,V> synchronizedSortedMap(@NonNull java.util.SortedMap<K,V>);
+    method @NonNull public static <T> java.util.SortedSet<T> synchronizedSortedSet(@NonNull java.util.SortedSet<T>);
+    method @NonNull public static <T> java.util.Collection<T> unmodifiableCollection(@NonNull java.util.Collection<? extends T>);
+    method @NonNull public static <T> java.util.List<T> unmodifiableList(@NonNull java.util.List<? extends T>);
+    method @NonNull public static <K, V> java.util.Map<K,V> unmodifiableMap(@NonNull java.util.Map<? extends K,? extends V>);
+    method @NonNull public static <K, V> java.util.NavigableMap<K,V> unmodifiableNavigableMap(@NonNull java.util.NavigableMap<K,? extends V>);
+    method @NonNull public static <T> java.util.NavigableSet<T> unmodifiableNavigableSet(@NonNull java.util.NavigableSet<T>);
+    method @NonNull public static <T> java.util.Set<T> unmodifiableSet(@NonNull java.util.Set<? extends T>);
+    method @NonNull public static <K, V> java.util.SortedMap<K,V> unmodifiableSortedMap(@NonNull java.util.SortedMap<K,? extends V>);
+    method @NonNull public static <T> java.util.SortedSet<T> unmodifiableSortedSet(@NonNull java.util.SortedSet<T>);
+    field @NonNull public static final java.util.List EMPTY_LIST;
+    field @NonNull public static final java.util.Map EMPTY_MAP;
+    field @NonNull public static final java.util.Set EMPTY_SET;
+  }
+
+  @java.lang.FunctionalInterface public interface Comparator<T> {
+    method public int compare(T, T);
+    method public static <T, U> java.util.Comparator<T> comparing(java.util.function.Function<? super T,? extends U>, java.util.Comparator<? super U>);
+    method public static <T, U extends java.lang.Comparable<? super U>> java.util.Comparator<T> comparing(java.util.function.Function<? super T,? extends U>);
+    method public static <T> java.util.Comparator<T> comparingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static <T> java.util.Comparator<T> comparingInt(java.util.function.ToIntFunction<? super T>);
+    method public static <T> java.util.Comparator<T> comparingLong(java.util.function.ToLongFunction<? super T>);
+    method public boolean equals(Object);
+    method public static <T extends java.lang.Comparable<? super T>> java.util.Comparator<T> naturalOrder();
+    method public static <T> java.util.Comparator<T> nullsFirst(java.util.Comparator<? super T>);
+    method public static <T> java.util.Comparator<T> nullsLast(java.util.Comparator<? super T>);
+    method public static <T extends java.lang.Comparable<? super T>> java.util.Comparator<T> reverseOrder();
+    method public default java.util.Comparator<T> reversed();
+    method public default java.util.Comparator<T> thenComparing(java.util.Comparator<? super T>);
+    method public default <U> java.util.Comparator<T> thenComparing(java.util.function.Function<? super T,? extends U>, java.util.Comparator<? super U>);
+    method public default <U extends java.lang.Comparable<? super U>> java.util.Comparator<T> thenComparing(java.util.function.Function<? super T,? extends U>);
+    method public default java.util.Comparator<T> thenComparingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public default java.util.Comparator<T> thenComparingInt(java.util.function.ToIntFunction<? super T>);
+    method public default java.util.Comparator<T> thenComparingLong(java.util.function.ToLongFunction<? super T>);
+  }
+
+  public class ConcurrentModificationException extends java.lang.RuntimeException {
+    ctor public ConcurrentModificationException();
+    ctor public ConcurrentModificationException(String);
+    ctor public ConcurrentModificationException(Throwable);
+    ctor public ConcurrentModificationException(String, Throwable);
+  }
+
+  public final class Currency implements java.io.Serializable {
+    method public static java.util.Set<java.util.Currency> getAvailableCurrencies();
+    method public String getCurrencyCode();
+    method public int getDefaultFractionDigits();
+    method public String getDisplayName();
+    method public String getDisplayName(java.util.Locale);
+    method public static java.util.Currency getInstance(String);
+    method public static java.util.Currency getInstance(java.util.Locale);
+    method public int getNumericCode();
+    method public String getSymbol();
+    method public String getSymbol(java.util.Locale);
+  }
+
+  public class Date implements java.lang.Cloneable java.lang.Comparable<java.util.Date> java.io.Serializable {
+    ctor public Date();
+    ctor public Date(long);
+    ctor @Deprecated public Date(int, int, int);
+    ctor @Deprecated public Date(int, int, int, int, int);
+    ctor @Deprecated public Date(int, int, int, int, int, int);
+    ctor @Deprecated public Date(String);
+    method @Deprecated public static long UTC(int, int, int, int, int, int);
+    method public boolean after(java.util.Date);
+    method public boolean before(java.util.Date);
+    method public Object clone();
+    method public int compareTo(java.util.Date);
+    method public static java.util.Date from(java.time.Instant);
+    method @Deprecated public int getDate();
+    method @Deprecated public int getDay();
+    method @Deprecated public int getHours();
+    method @Deprecated public int getMinutes();
+    method @Deprecated public int getMonth();
+    method @Deprecated public int getSeconds();
+    method public long getTime();
+    method @Deprecated public int getTimezoneOffset();
+    method @Deprecated public int getYear();
+    method @Deprecated public static long parse(String);
+    method @Deprecated public void setDate(int);
+    method @Deprecated public void setHours(int);
+    method @Deprecated public void setMinutes(int);
+    method @Deprecated public void setMonth(int);
+    method @Deprecated public void setSeconds(int);
+    method public void setTime(long);
+    method @Deprecated public void setYear(int);
+    method @Deprecated public String toGMTString();
+    method public java.time.Instant toInstant();
+    method @Deprecated public String toLocaleString();
+  }
+
+  public interface Deque<E> extends java.util.Queue<E> {
+    method public void addFirst(E);
+    method public void addLast(E);
+    method @NonNull public java.util.Iterator<E> descendingIterator();
+    method public E getFirst();
+    method public E getLast();
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method @Nullable public E peekFirst();
+    method @Nullable public E peekLast();
+    method @Nullable public E pollFirst();
+    method @Nullable public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(@Nullable Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(@Nullable Object);
+  }
+
+  public abstract class Dictionary<K, V> {
+    ctor public Dictionary();
+    method public abstract java.util.Enumeration<V> elements();
+    method public abstract V get(Object);
+    method public abstract boolean isEmpty();
+    method public abstract java.util.Enumeration<K> keys();
+    method public abstract V put(K, V);
+    method public abstract V remove(Object);
+    method public abstract int size();
+  }
+
+  public class DoubleSummaryStatistics implements java.util.function.DoubleConsumer {
+    ctor public DoubleSummaryStatistics();
+    method public void accept(double);
+    method public void combine(java.util.DoubleSummaryStatistics);
+    method public final double getAverage();
+    method public final long getCount();
+    method public final double getMax();
+    method public final double getMin();
+    method public final double getSum();
+  }
+
+  public class DuplicateFormatFlagsException extends java.util.IllegalFormatException {
+    ctor public DuplicateFormatFlagsException(String);
+    method public String getFlags();
+  }
+
+  public class EmptyStackException extends java.lang.RuntimeException {
+    ctor public EmptyStackException();
+  }
+
+  public class EnumMap<K extends java.lang.Enum<K>, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.io.Serializable {
+    ctor public EnumMap(Class<K>);
+    ctor public EnumMap(java.util.EnumMap<K,? extends V>);
+    ctor public EnumMap(java.util.Map<K,? extends V>);
+    method public java.util.EnumMap<K,V> clone();
+    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+  }
+
+  public abstract class EnumSet<E extends java.lang.Enum<E>> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable {
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> allOf(Class<E>);
+    method public java.util.EnumSet<E> clone();
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> complementOf(java.util.EnumSet<E>);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(java.util.EnumSet<E>);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> copyOf(java.util.Collection<E>);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> noneOf(Class<E>);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E, E);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E, E, E, E);
+    method @java.lang.SafeVarargs public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> of(E, E...);
+    method public static <E extends java.lang.Enum<E>> java.util.EnumSet<E> range(E, E);
+  }
+
+  public interface Enumeration<E> {
+    method public boolean hasMoreElements();
+    method public E nextElement();
+  }
+
+  public interface EventListener {
+  }
+
+  public abstract class EventListenerProxy<T extends java.util.EventListener> implements java.util.EventListener {
+    ctor public EventListenerProxy(T);
+    method public T getListener();
+  }
+
+  public class EventObject implements java.io.Serializable {
+    ctor public EventObject(Object);
+    method public Object getSource();
+    field protected transient Object source;
+  }
+
+  public class FormatFlagsConversionMismatchException extends java.util.IllegalFormatException {
+    ctor public FormatFlagsConversionMismatchException(String, char);
+    method public char getConversion();
+    method public String getFlags();
+  }
+
+  public interface Formattable {
+    method public void formatTo(java.util.Formatter, int, int, int);
+  }
+
+  public class FormattableFlags {
+    field public static final int ALTERNATE = 4; // 0x4
+    field public static final int LEFT_JUSTIFY = 1; // 0x1
+    field public static final int UPPERCASE = 2; // 0x2
+  }
+
+  public final class Formatter implements java.io.Closeable java.io.Flushable {
+    ctor public Formatter();
+    ctor public Formatter(Appendable);
+    ctor public Formatter(java.util.Locale);
+    ctor public Formatter(Appendable, java.util.Locale);
+    ctor public Formatter(String) throws java.io.FileNotFoundException;
+    ctor public Formatter(String, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public Formatter(String, String, java.util.Locale) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public Formatter(java.io.File) throws java.io.FileNotFoundException;
+    ctor public Formatter(java.io.File, String) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public Formatter(java.io.File, String, java.util.Locale) throws java.io.FileNotFoundException, java.io.UnsupportedEncodingException;
+    ctor public Formatter(java.io.PrintStream);
+    ctor public Formatter(java.io.OutputStream);
+    ctor public Formatter(java.io.OutputStream, String) throws java.io.UnsupportedEncodingException;
+    ctor public Formatter(java.io.OutputStream, String, java.util.Locale) throws java.io.UnsupportedEncodingException;
+    method public void close();
+    method public void flush();
+    method public java.util.Formatter format(String, java.lang.Object...);
+    method public java.util.Formatter format(java.util.Locale, String, java.lang.Object...);
+    method public java.io.IOException ioException();
+    method public java.util.Locale locale();
+    method public Appendable out();
+  }
+
+  public enum Formatter.BigDecimalLayoutForm {
+    enum_constant public static final java.util.Formatter.BigDecimalLayoutForm DECIMAL_FLOAT;
+    enum_constant public static final java.util.Formatter.BigDecimalLayoutForm SCIENTIFIC;
+  }
+
+  public class FormatterClosedException extends java.lang.IllegalStateException {
+    ctor public FormatterClosedException();
+  }
+
+  public class GregorianCalendar extends java.util.Calendar {
+    ctor public GregorianCalendar();
+    ctor public GregorianCalendar(java.util.TimeZone);
+    ctor public GregorianCalendar(java.util.Locale);
+    ctor public GregorianCalendar(java.util.TimeZone, java.util.Locale);
+    ctor public GregorianCalendar(int, int, int);
+    ctor public GregorianCalendar(int, int, int, int, int);
+    ctor public GregorianCalendar(int, int, int, int, int, int);
+    method public void add(int, int);
+    method protected void computeFields();
+    method protected void computeTime();
+    method public static java.util.GregorianCalendar from(java.time.ZonedDateTime);
+    method public int getGreatestMinimum(int);
+    method public final java.util.Date getGregorianChange();
+    method public int getLeastMaximum(int);
+    method public int getMaximum(int);
+    method public int getMinimum(int);
+    method public boolean isLeapYear(int);
+    method public final boolean isWeekDateSupported();
+    method public void roll(int, boolean);
+    method public void setGregorianChange(java.util.Date);
+    method public java.time.ZonedDateTime toZonedDateTime();
+    field public static final int AD = 1; // 0x1
+    field public static final int BC = 0; // 0x0
+  }
+
+  public class HashMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
+    ctor public HashMap(int, float);
+    ctor public HashMap(int);
+    ctor public HashMap();
+    ctor public HashMap(@NonNull java.util.Map<? extends K,? extends V>);
+    method @NonNull public Object clone();
+    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+  }
+
+  public class HashSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.io.Serializable java.util.Set<E> {
+    ctor public HashSet();
+    ctor public HashSet(@NonNull java.util.Collection<? extends E>);
+    ctor public HashSet(int, float);
+    ctor public HashSet(int);
+    method @NonNull public Object clone();
+    method @NonNull public java.util.Iterator<E> iterator();
+    method public int size();
+  }
+
+  public class Hashtable<K, V> extends java.util.Dictionary<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
+    ctor public Hashtable(int, float);
+    ctor public Hashtable(int);
+    ctor public Hashtable();
+    ctor public Hashtable(java.util.Map<? extends K,? extends V>);
+    method public void clear();
+    method public Object clone();
+    method public boolean contains(Object);
+    method public boolean containsKey(Object);
+    method public boolean containsValue(Object);
+    method public java.util.Enumeration<V> elements();
+    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+    method public V get(Object);
+    method public boolean isEmpty();
+    method public java.util.Set<K> keySet();
+    method public java.util.Enumeration<K> keys();
+    method public V put(K, V);
+    method public void putAll(java.util.Map<? extends K,? extends V>);
+    method protected void rehash();
+    method public V remove(Object);
+    method public int size();
+    method public java.util.Collection<V> values();
+  }
+
+  public class IdentityHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.Map<K,V> java.io.Serializable {
+    ctor public IdentityHashMap();
+    ctor public IdentityHashMap(int);
+    ctor public IdentityHashMap(java.util.Map<? extends K,? extends V>);
+    method public Object clone();
+    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+  }
+
+  public class IllegalFormatCodePointException extends java.util.IllegalFormatException {
+    ctor public IllegalFormatCodePointException(int);
+    method public int getCodePoint();
+  }
+
+  public class IllegalFormatConversionException extends java.util.IllegalFormatException {
+    ctor public IllegalFormatConversionException(char, Class<?>);
+    method public Class<?> getArgumentClass();
+    method public char getConversion();
+  }
+
+  public class IllegalFormatException extends java.lang.IllegalArgumentException {
+  }
+
+  public class IllegalFormatFlagsException extends java.util.IllegalFormatException {
+    ctor public IllegalFormatFlagsException(String);
+    method public String getFlags();
+  }
+
+  public class IllegalFormatPrecisionException extends java.util.IllegalFormatException {
+    ctor public IllegalFormatPrecisionException(int);
+    method public int getPrecision();
+  }
+
+  public class IllegalFormatWidthException extends java.util.IllegalFormatException {
+    ctor public IllegalFormatWidthException(int);
+    method public int getWidth();
+  }
+
+  public class IllformedLocaleException extends java.lang.RuntimeException {
+    ctor public IllformedLocaleException();
+    ctor public IllformedLocaleException(String);
+    ctor public IllformedLocaleException(String, int);
+    method public int getErrorIndex();
+  }
+
+  public class InputMismatchException extends java.util.NoSuchElementException {
+    ctor public InputMismatchException();
+    ctor public InputMismatchException(String);
+  }
+
+  public class IntSummaryStatistics implements java.util.function.IntConsumer {
+    ctor public IntSummaryStatistics();
+    method public void accept(int);
+    method public void combine(java.util.IntSummaryStatistics);
+    method public final double getAverage();
+    method public final long getCount();
+    method public final int getMax();
+    method public final int getMin();
+    method public final long getSum();
+  }
+
+  public class InvalidPropertiesFormatException extends java.io.IOException {
+    ctor public InvalidPropertiesFormatException(Throwable);
+    ctor public InvalidPropertiesFormatException(String);
+  }
+
+  public interface Iterator<E> {
+    method public default void forEachRemaining(@NonNull java.util.function.Consumer<? super E>);
+    method public boolean hasNext();
+    method public E next();
+    method public default void remove();
+  }
+
+  public class LinkedHashMap<K, V> extends java.util.HashMap<K,V> implements java.util.Map<K,V> {
+    ctor public LinkedHashMap(int, float);
+    ctor public LinkedHashMap(int);
+    ctor public LinkedHashMap();
+    ctor public LinkedHashMap(java.util.Map<? extends K,? extends V>);
+    ctor public LinkedHashMap(int, float, boolean);
+    method protected boolean removeEldestEntry(java.util.Map.Entry<K,V>);
+  }
+
+  public class LinkedHashSet<E> extends java.util.HashSet<E> implements java.lang.Cloneable java.io.Serializable java.util.Set<E> {
+    ctor public LinkedHashSet(int, float);
+    ctor public LinkedHashSet(int);
+    ctor public LinkedHashSet();
+    ctor public LinkedHashSet(java.util.Collection<? extends E>);
+  }
+
+  public class LinkedList<E> extends java.util.AbstractSequentialList<E> implements java.lang.Cloneable java.util.Deque<E> java.util.List<E> java.io.Serializable {
+    ctor public LinkedList();
+    ctor public LinkedList(@NonNull java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method @NonNull public Object clone();
+    method @NonNull public java.util.Iterator<E> descendingIterator();
+    method public E element();
+    method public E getFirst();
+    method public E getLast();
+    method public boolean offer(E);
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method @Nullable public E peek();
+    method @Nullable public E peekFirst();
+    method @Nullable public E peekLast();
+    method @Nullable public E poll();
+    method @Nullable public E pollFirst();
+    method @Nullable public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E remove();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(@Nullable Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(@Nullable Object);
+    method public int size();
+  }
+
+  public interface List<E> extends java.util.Collection<E> {
+    method public void add(int, E);
+    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
+    method @NonNull public static <E> java.util.List<E> copyOf(@NonNull java.util.Collection<? extends E>);
+    method public E get(int);
+    method public int indexOf(@Nullable Object);
+    method public int lastIndexOf(@Nullable Object);
+    method @NonNull public java.util.ListIterator<E> listIterator();
+    method @NonNull public java.util.ListIterator<E> listIterator(int);
+    method @NonNull public static <E> java.util.List<E> of();
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.List<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.List<E> of(@NonNull E...);
+    method public E remove(int);
+    method public default void replaceAll(@NonNull java.util.function.UnaryOperator<E>);
+    method public E set(int, E);
+    method public default void sort(@Nullable java.util.Comparator<? super E>);
+    method @NonNull public java.util.List<E> subList(int, int);
+  }
+
+  public interface ListIterator<E> extends java.util.Iterator<E> {
+    method public void add(E);
+    method public boolean hasPrevious();
+    method public int nextIndex();
+    method public E previous();
+    method public int previousIndex();
+    method public void remove();
+    method public void set(E);
+  }
+
+  public abstract class ListResourceBundle extends java.util.ResourceBundle {
+    ctor public ListResourceBundle();
+    method protected abstract Object[][] getContents();
+    method public java.util.Enumeration<java.lang.String> getKeys();
+    method public final Object handleGetObject(String);
+  }
+
+  public final class Locale implements java.lang.Cloneable java.io.Serializable {
+    ctor public Locale(@NonNull String, @NonNull String, @NonNull String);
+    ctor public Locale(@NonNull String, @NonNull String);
+    ctor public Locale(@NonNull String);
+    method @NonNull public Object clone();
+    method @NonNull public static java.util.List<java.util.Locale> filter(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>, @NonNull java.util.Locale.FilteringMode);
+    method @NonNull public static java.util.List<java.util.Locale> filter(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>);
+    method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>, @NonNull java.util.Locale.FilteringMode);
+    method @NonNull public static java.util.List<java.lang.String> filterTags(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>);
+    method @NonNull public static java.util.Locale forLanguageTag(@NonNull String);
+    method @NonNull public static java.util.Locale[] getAvailableLocales();
+    method @NonNull public String getCountry();
+    method @NonNull public static java.util.Locale getDefault();
+    method @NonNull public static java.util.Locale getDefault(@NonNull java.util.Locale.Category);
+    method @NonNull public String getDisplayCountry();
+    method @NonNull public String getDisplayCountry(@NonNull java.util.Locale);
+    method @NonNull public String getDisplayLanguage();
+    method @NonNull public String getDisplayLanguage(@NonNull java.util.Locale);
+    method @NonNull public String getDisplayName();
+    method @NonNull public String getDisplayName(@NonNull java.util.Locale);
+    method @NonNull public String getDisplayScript();
+    method @NonNull public String getDisplayScript(@NonNull java.util.Locale);
+    method @NonNull public String getDisplayVariant();
+    method @NonNull public String getDisplayVariant(@NonNull java.util.Locale);
+    method @Nullable public String getExtension(char);
+    method @NonNull public java.util.Set<java.lang.Character> getExtensionKeys();
+    method @NonNull public String getISO3Country() throws java.util.MissingResourceException;
+    method @NonNull public String getISO3Language() throws java.util.MissingResourceException;
+    method @NonNull public static String[] getISOCountries();
+    method @NonNull public static String[] getISOLanguages();
+    method @NonNull public String getLanguage();
+    method @NonNull public String getScript();
+    method @NonNull public java.util.Set<java.lang.String> getUnicodeLocaleAttributes();
+    method @NonNull public java.util.Set<java.lang.String> getUnicodeLocaleKeys();
+    method @Nullable public String getUnicodeLocaleType(@NonNull String);
+    method @NonNull public String getVariant();
+    method public boolean hasExtensions();
+    method @Nullable public static java.util.Locale lookup(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.util.Locale>);
+    method @Nullable public static String lookupTag(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Collection<java.lang.String>);
+    method public static void setDefault(@NonNull java.util.Locale);
+    method public static void setDefault(@NonNull java.util.Locale.Category, @NonNull java.util.Locale);
+    method @NonNull public java.util.Locale stripExtensions();
+    method @NonNull public String toLanguageTag();
+    field @NonNull public static final java.util.Locale CANADA;
+    field @NonNull public static final java.util.Locale CANADA_FRENCH;
+    field @NonNull public static final java.util.Locale CHINA;
+    field @NonNull public static final java.util.Locale CHINESE;
+    field @NonNull public static final java.util.Locale ENGLISH;
+    field @NonNull public static final java.util.Locale FRANCE;
+    field @NonNull public static final java.util.Locale FRENCH;
+    field @NonNull public static final java.util.Locale GERMAN;
+    field @NonNull public static final java.util.Locale GERMANY;
+    field @NonNull public static final java.util.Locale ITALIAN;
+    field @NonNull public static final java.util.Locale ITALY;
+    field @NonNull public static final java.util.Locale JAPAN;
+    field @NonNull public static final java.util.Locale JAPANESE;
+    field @NonNull public static final java.util.Locale KOREA;
+    field @NonNull public static final java.util.Locale KOREAN;
+    field @NonNull public static final java.util.Locale PRC;
+    field public static final char PRIVATE_USE_EXTENSION = 120; // 0x0078 'x'
+    field @NonNull public static final java.util.Locale ROOT;
+    field @NonNull public static final java.util.Locale SIMPLIFIED_CHINESE;
+    field @NonNull public static final java.util.Locale TAIWAN;
+    field @NonNull public static final java.util.Locale TRADITIONAL_CHINESE;
+    field @NonNull public static final java.util.Locale UK;
+    field public static final char UNICODE_LOCALE_EXTENSION = 117; // 0x0075 'u'
+    field @NonNull public static final java.util.Locale US;
+  }
+
+  public static final class Locale.Builder {
+    ctor public Locale.Builder();
+    method @NonNull public java.util.Locale.Builder addUnicodeLocaleAttribute(@NonNull String);
+    method @NonNull public java.util.Locale build();
+    method @NonNull public java.util.Locale.Builder clear();
+    method @NonNull public java.util.Locale.Builder clearExtensions();
+    method @NonNull public java.util.Locale.Builder removeUnicodeLocaleAttribute(@NonNull String);
+    method @NonNull public java.util.Locale.Builder setExtension(char, @Nullable String);
+    method @NonNull public java.util.Locale.Builder setLanguage(@Nullable String);
+    method @NonNull public java.util.Locale.Builder setLanguageTag(@NonNull String);
+    method @NonNull public java.util.Locale.Builder setLocale(@NonNull java.util.Locale);
+    method @NonNull public java.util.Locale.Builder setRegion(@Nullable String);
+    method @NonNull public java.util.Locale.Builder setScript(@Nullable String);
+    method @NonNull public java.util.Locale.Builder setUnicodeLocaleKeyword(@NonNull String, @Nullable String);
+    method @NonNull public java.util.Locale.Builder setVariant(@Nullable String);
+  }
+
+  public enum Locale.Category {
+    enum_constant public static final java.util.Locale.Category DISPLAY;
+    enum_constant public static final java.util.Locale.Category FORMAT;
+  }
+
+  public enum Locale.FilteringMode {
+    enum_constant public static final java.util.Locale.FilteringMode AUTOSELECT_FILTERING;
+    enum_constant public static final java.util.Locale.FilteringMode EXTENDED_FILTERING;
+    enum_constant public static final java.util.Locale.FilteringMode IGNORE_EXTENDED_RANGES;
+    enum_constant public static final java.util.Locale.FilteringMode MAP_EXTENDED_RANGES;
+    enum_constant public static final java.util.Locale.FilteringMode REJECT_EXTENDED_RANGES;
+  }
+
+  public static final class Locale.LanguageRange {
+    ctor public Locale.LanguageRange(@NonNull String);
+    ctor public Locale.LanguageRange(@NonNull String, double);
+    method @NonNull public String getRange();
+    method public double getWeight();
+    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> mapEquivalents(@NonNull java.util.List<java.util.Locale.LanguageRange>, @NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
+    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> parse(@NonNull String);
+    method @NonNull public static java.util.List<java.util.Locale.LanguageRange> parse(@NonNull String, @NonNull java.util.Map<java.lang.String,java.util.List<java.lang.String>>);
+    field public static final double MAX_WEIGHT = 1.0;
+    field public static final double MIN_WEIGHT = 0.0;
+  }
+
+  public class LongSummaryStatistics implements java.util.function.IntConsumer java.util.function.LongConsumer {
+    ctor public LongSummaryStatistics();
+    method public void accept(int);
+    method public void accept(long);
+    method public void combine(java.util.LongSummaryStatistics);
+    method public final double getAverage();
+    method public final long getCount();
+    method public final long getMax();
+    method public final long getMin();
+    method public final long getSum();
+  }
+
+  public interface Map<K, V> {
+    method public void clear();
+    method @Nullable public default V compute(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
+    method @Nullable public default V computeIfAbsent(K, @NonNull java.util.function.Function<? super K,? extends V>);
+    method @Nullable public default V computeIfPresent(K, @NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
+    method public boolean containsKey(@Nullable Object);
+    method public boolean containsValue(@Nullable Object);
+    method @NonNull public static <K, V> java.util.Map<K,V> copyOf(@NonNull java.util.Map<? extends K,? extends V>);
+    method @NonNull public static <K, V> java.util.Map.Entry<K,V> entry(@NonNull K, @NonNull V);
+    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+    method public boolean equals(@Nullable Object);
+    method public default void forEach(@NonNull java.util.function.BiConsumer<? super K,? super V>);
+    method @Nullable public V get(@Nullable Object);
+    method @Nullable public default V getOrDefault(@Nullable Object, @Nullable V);
+    method public int hashCode();
+    method public boolean isEmpty();
+    method @NonNull public java.util.Set<K> keySet();
+    method @Nullable public default V merge(K, @NonNull V, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+    method @NonNull public static <K, V> java.util.Map<K,V> of();
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull public static <K, V> java.util.Map<K,V> of(@NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V, @NonNull K, @NonNull V);
+    method @NonNull @java.lang.SafeVarargs public static <K, V> java.util.Map<K,V> ofEntries(@NonNull java.util.Map.Entry<? extends K,? extends V>...);
+    method @Nullable public V put(K, V);
+    method public void putAll(@NonNull java.util.Map<? extends K,? extends V>);
+    method @Nullable public default V putIfAbsent(K, V);
+    method @Nullable public V remove(@Nullable Object);
+    method public default boolean remove(@Nullable Object, @Nullable Object);
+    method public default boolean replace(K, @Nullable V, V);
+    method @Nullable public default V replace(K, V);
+    method public default void replaceAll(@NonNull java.util.function.BiFunction<? super K,? super V,? extends V>);
+    method public int size();
+    method @NonNull public java.util.Collection<V> values();
+  }
+
+  public static interface Map.Entry<K, V> {
+    method @NonNull public static <K extends java.lang.Comparable<? super K>, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByKey();
+    method @NonNull public static <K, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByKey(@NonNull java.util.Comparator<? super K>);
+    method @NonNull public static <K, V extends java.lang.Comparable<? super V>> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByValue();
+    method @NonNull public static <K, V> java.util.Comparator<java.util.Map.Entry<K,V>> comparingByValue(@NonNull java.util.Comparator<? super V>);
+    method public boolean equals(@Nullable Object);
+    method public K getKey();
+    method public V getValue();
+    method public int hashCode();
+    method public V setValue(V);
+  }
+
+  public class MissingFormatArgumentException extends java.util.IllegalFormatException {
+    ctor public MissingFormatArgumentException(String);
+    method public String getFormatSpecifier();
+  }
+
+  public class MissingFormatWidthException extends java.util.IllegalFormatException {
+    ctor public MissingFormatWidthException(String);
+    method public String getFormatSpecifier();
+  }
+
+  public class MissingResourceException extends java.lang.RuntimeException {
+    ctor public MissingResourceException(String, String, String);
+    method public String getClassName();
+    method public String getKey();
+  }
+
+  public interface NavigableMap<K, V> extends java.util.SortedMap<K,V> {
+    method @Nullable public java.util.Map.Entry<K,V> ceilingEntry(K);
+    method @Nullable public K ceilingKey(K);
+    method @NonNull public java.util.NavigableSet<K> descendingKeySet();
+    method @NonNull public java.util.NavigableMap<K,V> descendingMap();
+    method @Nullable public java.util.Map.Entry<K,V> firstEntry();
+    method @Nullable public java.util.Map.Entry<K,V> floorEntry(K);
+    method @Nullable public K floorKey(K);
+    method @NonNull public java.util.NavigableMap<K,V> headMap(K, boolean);
+    method @Nullable public java.util.Map.Entry<K,V> higherEntry(K);
+    method @Nullable public K higherKey(K);
+    method @Nullable public java.util.Map.Entry<K,V> lastEntry();
+    method @Nullable public java.util.Map.Entry<K,V> lowerEntry(K);
+    method @Nullable public K lowerKey(K);
+    method @NonNull public java.util.NavigableSet<K> navigableKeySet();
+    method @Nullable public java.util.Map.Entry<K,V> pollFirstEntry();
+    method @Nullable public java.util.Map.Entry<K,V> pollLastEntry();
+    method @NonNull public java.util.NavigableMap<K,V> subMap(K, boolean, K, boolean);
+    method @NonNull public java.util.NavigableMap<K,V> tailMap(K, boolean);
+  }
+
+  public interface NavigableSet<E> extends java.util.SortedSet<E> {
+    method public E ceiling(E);
+    method public java.util.Iterator<E> descendingIterator();
+    method public java.util.NavigableSet<E> descendingSet();
+    method public E floor(E);
+    method public java.util.NavigableSet<E> headSet(E, boolean);
+    method public E higher(E);
+    method public E lower(E);
+    method public E pollFirst();
+    method public E pollLast();
+    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
+    method public java.util.NavigableSet<E> tailSet(E, boolean);
+  }
+
+  public class NoSuchElementException extends java.lang.RuntimeException {
+    ctor public NoSuchElementException();
+    ctor public NoSuchElementException(String);
+  }
+
+  public final class Objects {
+    method public static int checkFromIndexSize(int, int, int);
+    method public static int checkFromToIndex(int, int, int);
+    method public static int checkIndex(int, int);
+    method public static <T> int compare(T, T, @NonNull java.util.Comparator<? super T>);
+    method public static boolean deepEquals(@Nullable Object, @Nullable Object);
+    method public static boolean equals(@Nullable Object, @Nullable Object);
+    method public static int hash(@Nullable java.lang.Object...);
+    method public static int hashCode(@Nullable Object);
+    method public static boolean isNull(@Nullable Object);
+    method public static boolean nonNull(@Nullable Object);
+    method @NonNull public static <T> T requireNonNull(@Nullable T);
+    method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull String);
+    method @NonNull public static <T> T requireNonNull(@Nullable T, @NonNull java.util.function.Supplier<java.lang.String>);
+    method @NonNull public static <T> T requireNonNullElse(@Nullable T, @NonNull T);
+    method @NonNull public static <T> T requireNonNullElseGet(@Nullable T, @NonNull java.util.function.Supplier<? extends T>);
+    method @NonNull public static String toString(@Nullable Object);
+    method @NonNull public static String toString(@Nullable Object, @NonNull String);
+  }
+
+  public class Observable {
+    ctor public Observable();
+    method public void addObserver(java.util.Observer);
+    method protected void clearChanged();
+    method public int countObservers();
+    method public void deleteObserver(java.util.Observer);
+    method public void deleteObservers();
+    method public boolean hasChanged();
+    method public void notifyObservers();
+    method public void notifyObservers(Object);
+    method protected void setChanged();
+  }
+
+  public interface Observer {
+    method public void update(java.util.Observable, Object);
+  }
+
+  public final class Optional<T> {
+    method public static <T> java.util.Optional<T> empty();
+    method public java.util.Optional<T> filter(java.util.function.Predicate<? super T>);
+    method public <U> java.util.Optional<U> flatMap(java.util.function.Function<? super T,java.util.Optional<U>>);
+    method public T get();
+    method public void ifPresent(java.util.function.Consumer<? super T>);
+    method public boolean isPresent();
+    method public <U> java.util.Optional<U> map(java.util.function.Function<? super T,? extends U>);
+    method public static <T> java.util.Optional<T> of(T);
+    method public static <T> java.util.Optional<T> ofNullable(T);
+    method public T orElse(T);
+    method public T orElseGet(java.util.function.Supplier<? extends T>);
+    method public <X extends java.lang.Throwable> T orElseThrow(java.util.function.Supplier<? extends X>) throws X;
+  }
+
+  public final class OptionalDouble {
+    method public static java.util.OptionalDouble empty();
+    method public double getAsDouble();
+    method public void ifPresent(java.util.function.DoubleConsumer);
+    method public boolean isPresent();
+    method public static java.util.OptionalDouble of(double);
+    method public double orElse(double);
+    method public double orElseGet(java.util.function.DoubleSupplier);
+    method public <X extends java.lang.Throwable> double orElseThrow(java.util.function.Supplier<X>) throws X;
+  }
+
+  public final class OptionalInt {
+    method public static java.util.OptionalInt empty();
+    method public int getAsInt();
+    method public void ifPresent(java.util.function.IntConsumer);
+    method public boolean isPresent();
+    method public static java.util.OptionalInt of(int);
+    method public int orElse(int);
+    method public int orElseGet(java.util.function.IntSupplier);
+    method public <X extends java.lang.Throwable> int orElseThrow(java.util.function.Supplier<X>) throws X;
+  }
+
+  public final class OptionalLong {
+    method public static java.util.OptionalLong empty();
+    method public long getAsLong();
+    method public void ifPresent(java.util.function.LongConsumer);
+    method public boolean isPresent();
+    method public static java.util.OptionalLong of(long);
+    method public long orElse(long);
+    method public long orElseGet(java.util.function.LongSupplier);
+    method public <X extends java.lang.Throwable> long orElseThrow(java.util.function.Supplier<X>) throws X;
+  }
+
+  public interface PrimitiveIterator<T, T_CONS> extends java.util.Iterator<T> {
+    method public void forEachRemaining(T_CONS);
+  }
+
+  public static interface PrimitiveIterator.OfDouble extends java.util.PrimitiveIterator<java.lang.Double,java.util.function.DoubleConsumer> {
+    method public default void forEachRemaining(java.util.function.DoubleConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
+    method public default Double next();
+    method public double nextDouble();
+  }
+
+  public static interface PrimitiveIterator.OfInt extends java.util.PrimitiveIterator<java.lang.Integer,java.util.function.IntConsumer> {
+    method public default void forEachRemaining(java.util.function.IntConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>);
+    method public default Integer next();
+    method public int nextInt();
+  }
+
+  public static interface PrimitiveIterator.OfLong extends java.util.PrimitiveIterator<java.lang.Long,java.util.function.LongConsumer> {
+    method public default void forEachRemaining(java.util.function.LongConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>);
+    method public default Long next();
+    method public long nextLong();
+  }
+
+  public class PriorityQueue<E> extends java.util.AbstractQueue<E> implements java.io.Serializable {
+    ctor public PriorityQueue();
+    ctor public PriorityQueue(int);
+    ctor public PriorityQueue(java.util.Comparator<? super E>);
+    ctor public PriorityQueue(int, java.util.Comparator<? super E>);
+    ctor public PriorityQueue(java.util.Collection<? extends E>);
+    ctor public PriorityQueue(java.util.PriorityQueue<? extends E>);
+    ctor public PriorityQueue(java.util.SortedSet<? extends E>);
+    method public java.util.Comparator<? super E> comparator();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll();
+    method public int size();
+    method public final java.util.Spliterator<E> spliterator();
+  }
+
+  public class Properties extends java.util.Hashtable<java.lang.Object,java.lang.Object> {
+    ctor public Properties();
+    ctor public Properties(java.util.Properties);
+    method public String getProperty(String);
+    method public String getProperty(String, String);
+    method public void list(java.io.PrintStream);
+    method public void list(java.io.PrintWriter);
+    method public void load(java.io.Reader) throws java.io.IOException;
+    method public void load(java.io.InputStream) throws java.io.IOException;
+    method public void loadFromXML(java.io.InputStream) throws java.io.IOException, java.util.InvalidPropertiesFormatException;
+    method public java.util.Enumeration<?> propertyNames();
+    method @Deprecated public void save(java.io.OutputStream, String);
+    method public Object setProperty(String, String);
+    method public void store(java.io.Writer, String) throws java.io.IOException;
+    method public void store(java.io.OutputStream, String) throws java.io.IOException;
+    method public void storeToXML(java.io.OutputStream, String) throws java.io.IOException;
+    method public void storeToXML(java.io.OutputStream, String, String) throws java.io.IOException;
+    method public java.util.Set<java.lang.String> stringPropertyNames();
+    field protected java.util.Properties defaults;
+  }
+
+  public final class PropertyPermission extends java.security.BasicPermission {
+    ctor public PropertyPermission(String, String);
+  }
+
+  public class PropertyResourceBundle extends java.util.ResourceBundle {
+    ctor public PropertyResourceBundle(java.io.InputStream) throws java.io.IOException;
+    ctor public PropertyResourceBundle(java.io.Reader) throws java.io.IOException;
+    method public java.util.Enumeration<java.lang.String> getKeys();
+    method public Object handleGetObject(String);
+  }
+
+  public interface Queue<E> extends java.util.Collection<E> {
+    method public E element();
+    method public boolean offer(E);
+    method @Nullable public E peek();
+    method @Nullable public E poll();
+    method public E remove();
+  }
+
+  public class Random implements java.io.Serializable {
+    ctor public Random();
+    ctor public Random(long);
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
+    method protected int next(int);
+    method public boolean nextBoolean();
+    method public void nextBytes(byte[]);
+    method public double nextDouble();
+    method public float nextFloat();
+    method public double nextGaussian();
+    method public int nextInt();
+    method public int nextInt(int);
+    method public long nextLong();
+    method public void setSeed(long);
+  }
+
+  public interface RandomAccess {
+  }
+
+  public abstract class ResourceBundle {
+    ctor public ResourceBundle();
+    method public static final void clearCache();
+    method public static final void clearCache(ClassLoader);
+    method public boolean containsKey(String);
+    method public String getBaseBundleName();
+    method public static final java.util.ResourceBundle getBundle(String);
+    method public static final java.util.ResourceBundle getBundle(String, java.util.ResourceBundle.Control);
+    method public static final java.util.ResourceBundle getBundle(String, java.util.Locale);
+    method public static final java.util.ResourceBundle getBundle(String, java.util.Locale, java.util.ResourceBundle.Control);
+    method public static java.util.ResourceBundle getBundle(String, java.util.Locale, ClassLoader);
+    method public static java.util.ResourceBundle getBundle(String, java.util.Locale, ClassLoader, java.util.ResourceBundle.Control);
+    method public abstract java.util.Enumeration<java.lang.String> getKeys();
+    method public java.util.Locale getLocale();
+    method public final Object getObject(String);
+    method public final String getString(String);
+    method public final String[] getStringArray(String);
+    method protected abstract Object handleGetObject(String);
+    method protected java.util.Set<java.lang.String> handleKeySet();
+    method public java.util.Set<java.lang.String> keySet();
+    method protected void setParent(java.util.ResourceBundle);
+    field protected java.util.ResourceBundle parent;
+  }
+
+  public static class ResourceBundle.Control {
+    ctor protected ResourceBundle.Control();
+    method public java.util.List<java.util.Locale> getCandidateLocales(String, java.util.Locale);
+    method public static final java.util.ResourceBundle.Control getControl(java.util.List<java.lang.String>);
+    method public java.util.Locale getFallbackLocale(String, java.util.Locale);
+    method public java.util.List<java.lang.String> getFormats(String);
+    method public static final java.util.ResourceBundle.Control getNoFallbackControl(java.util.List<java.lang.String>);
+    method public long getTimeToLive(String, java.util.Locale);
+    method public boolean needsReload(String, java.util.Locale, String, ClassLoader, java.util.ResourceBundle, long);
+    method public java.util.ResourceBundle newBundle(String, java.util.Locale, String, ClassLoader, boolean) throws java.io.IOException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+    method public String toBundleName(String, java.util.Locale);
+    method public final String toResourceName(String, String);
+    field public static final java.util.List<java.lang.String> FORMAT_CLASS;
+    field public static final java.util.List<java.lang.String> FORMAT_DEFAULT;
+    field public static final java.util.List<java.lang.String> FORMAT_PROPERTIES;
+    field public static final long TTL_DONT_CACHE = -1L; // 0xffffffffffffffffL
+    field public static final long TTL_NO_EXPIRATION_CONTROL = -2L; // 0xfffffffffffffffeL
+  }
+
+  public final class Scanner implements java.io.Closeable java.util.Iterator<java.lang.String> {
+    ctor public Scanner(Readable);
+    ctor public Scanner(java.io.InputStream);
+    ctor public Scanner(java.io.InputStream, String);
+    ctor public Scanner(java.io.File) throws java.io.FileNotFoundException;
+    ctor public Scanner(java.io.File, String) throws java.io.FileNotFoundException;
+    ctor public Scanner(java.nio.file.Path) throws java.io.IOException;
+    ctor public Scanner(java.nio.file.Path, String) throws java.io.IOException;
+    ctor public Scanner(String);
+    ctor public Scanner(java.nio.channels.ReadableByteChannel);
+    ctor public Scanner(java.nio.channels.ReadableByteChannel, String);
+    method public void close();
+    method public java.util.regex.Pattern delimiter();
+    method public String findInLine(String);
+    method public String findInLine(java.util.regex.Pattern);
+    method public String findWithinHorizon(String, int);
+    method public String findWithinHorizon(java.util.regex.Pattern, int);
+    method public boolean hasNext();
+    method public boolean hasNext(String);
+    method public boolean hasNext(java.util.regex.Pattern);
+    method public boolean hasNextBigDecimal();
+    method public boolean hasNextBigInteger();
+    method public boolean hasNextBigInteger(int);
+    method public boolean hasNextBoolean();
+    method public boolean hasNextByte();
+    method public boolean hasNextByte(int);
+    method public boolean hasNextDouble();
+    method public boolean hasNextFloat();
+    method public boolean hasNextInt();
+    method public boolean hasNextInt(int);
+    method public boolean hasNextLine();
+    method public boolean hasNextLong();
+    method public boolean hasNextLong(int);
+    method public boolean hasNextShort();
+    method public boolean hasNextShort(int);
+    method public java.io.IOException ioException();
+    method public java.util.Locale locale();
+    method public java.util.regex.MatchResult match();
+    method public String next();
+    method public String next(String);
+    method public String next(java.util.regex.Pattern);
+    method public java.math.BigDecimal nextBigDecimal();
+    method public java.math.BigInteger nextBigInteger();
+    method public java.math.BigInteger nextBigInteger(int);
+    method public boolean nextBoolean();
+    method public byte nextByte();
+    method public byte nextByte(int);
+    method public double nextDouble();
+    method public float nextFloat();
+    method public int nextInt();
+    method public int nextInt(int);
+    method public String nextLine();
+    method public long nextLong();
+    method public long nextLong(int);
+    method public short nextShort();
+    method public short nextShort(int);
+    method public int radix();
+    method public java.util.Scanner reset();
+    method public java.util.Scanner skip(java.util.regex.Pattern);
+    method public java.util.Scanner skip(String);
+    method public java.util.Scanner useDelimiter(java.util.regex.Pattern);
+    method public java.util.Scanner useDelimiter(String);
+    method public java.util.Scanner useLocale(java.util.Locale);
+    method public java.util.Scanner useRadix(int);
+  }
+
+  public class ServiceConfigurationError extends java.lang.Error {
+    ctor public ServiceConfigurationError(String);
+    ctor public ServiceConfigurationError(String, Throwable);
+  }
+
+  public final class ServiceLoader<S> implements java.lang.Iterable<S> {
+    method public java.util.Iterator<S> iterator();
+    method public static <S> java.util.ServiceLoader<S> load(Class<S>, ClassLoader);
+    method public static <S> java.util.ServiceLoader<S> load(Class<S>);
+    method public static <S> java.util.ServiceLoader<S> loadInstalled(Class<S>);
+    method public void reload();
+  }
+
+  public interface Set<E> extends java.util.Collection<E> {
+    method @NonNull public static <E> java.util.Set<E> copyOf(@NonNull java.util.Collection<? extends E>);
+    method @NonNull public static <E> java.util.Set<E> of();
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull public static <E> java.util.Set<E> of(@NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E, @NonNull E);
+    method @NonNull @java.lang.SafeVarargs public static <E> java.util.Set<E> of(@NonNull E...);
+  }
+
+  public class SimpleTimeZone extends java.util.TimeZone {
+    ctor public SimpleTimeZone(int, String);
+    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int);
+    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int, int);
+    ctor public SimpleTimeZone(int, String, int, int, int, int, int, int, int, int, int, int, int);
+    method public int getOffset(int, int, int, int, int, int);
+    method public int getRawOffset();
+    method public boolean inDaylightTime(java.util.Date);
+    method public void setDSTSavings(int);
+    method public void setEndRule(int, int, int, int);
+    method public void setEndRule(int, int, int);
+    method public void setEndRule(int, int, int, int, boolean);
+    method public void setRawOffset(int);
+    method public void setStartRule(int, int, int, int);
+    method public void setStartRule(int, int, int);
+    method public void setStartRule(int, int, int, int, boolean);
+    method public void setStartYear(int);
+    method public boolean useDaylightTime();
+    field public static final int STANDARD_TIME = 1; // 0x1
+    field public static final int UTC_TIME = 2; // 0x2
+    field public static final int WALL_TIME = 0; // 0x0
+  }
+
+  public interface SortedMap<K, V> extends java.util.Map<K,V> {
+    method @Nullable public java.util.Comparator<? super K> comparator();
+    method public K firstKey();
+    method @NonNull public java.util.SortedMap<K,V> headMap(K);
+    method public K lastKey();
+    method @NonNull public java.util.SortedMap<K,V> subMap(K, K);
+    method @NonNull public java.util.SortedMap<K,V> tailMap(K);
+  }
+
+  public interface SortedSet<E> extends java.util.Set<E> {
+    method public java.util.Comparator<? super E> comparator();
+    method public E first();
+    method public java.util.SortedSet<E> headSet(E);
+    method public E last();
+    method public java.util.SortedSet<E> subSet(E, E);
+    method public java.util.SortedSet<E> tailSet(E);
+  }
+
+  public interface Spliterator<T> {
+    method public int characteristics();
+    method public long estimateSize();
+    method public default void forEachRemaining(java.util.function.Consumer<? super T>);
+    method public default java.util.Comparator<? super T> getComparator();
+    method public default long getExactSizeIfKnown();
+    method public default boolean hasCharacteristics(int);
+    method public boolean tryAdvance(java.util.function.Consumer<? super T>);
+    method public java.util.Spliterator<T> trySplit();
+    field public static final int CONCURRENT = 4096; // 0x1000
+    field public static final int DISTINCT = 1; // 0x1
+    field public static final int IMMUTABLE = 1024; // 0x400
+    field public static final int NONNULL = 256; // 0x100
+    field public static final int ORDERED = 16; // 0x10
+    field public static final int SIZED = 64; // 0x40
+    field public static final int SORTED = 4; // 0x4
+    field public static final int SUBSIZED = 16384; // 0x4000
+  }
+
+  public static interface Spliterator.OfDouble extends java.util.Spliterator.OfPrimitive<java.lang.Double,java.util.function.DoubleConsumer,java.util.Spliterator.OfDouble> {
+    method public default void forEachRemaining(java.util.function.DoubleConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>);
+    method public boolean tryAdvance(java.util.function.DoubleConsumer);
+    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Double>);
+    method public java.util.Spliterator.OfDouble trySplit();
+  }
+
+  public static interface Spliterator.OfInt extends java.util.Spliterator.OfPrimitive<java.lang.Integer,java.util.function.IntConsumer,java.util.Spliterator.OfInt> {
+    method public default void forEachRemaining(java.util.function.IntConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>);
+    method public boolean tryAdvance(java.util.function.IntConsumer);
+    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Integer>);
+    method public java.util.Spliterator.OfInt trySplit();
+  }
+
+  public static interface Spliterator.OfLong extends java.util.Spliterator.OfPrimitive<java.lang.Long,java.util.function.LongConsumer,java.util.Spliterator.OfLong> {
+    method public default void forEachRemaining(java.util.function.LongConsumer);
+    method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>);
+    method public boolean tryAdvance(java.util.function.LongConsumer);
+    method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Long>);
+    method public java.util.Spliterator.OfLong trySplit();
+  }
+
+  public static interface Spliterator.OfPrimitive<T, T_CONS, T_SPLITR extends java.util.Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>> extends java.util.Spliterator<T> {
+    method public default void forEachRemaining(T_CONS);
+    method public boolean tryAdvance(T_CONS);
+    method public T_SPLITR trySplit();
+  }
+
+  public final class Spliterators {
+    method public static java.util.Spliterator.OfDouble emptyDoubleSpliterator();
+    method public static java.util.Spliterator.OfInt emptyIntSpliterator();
+    method public static java.util.Spliterator.OfLong emptyLongSpliterator();
+    method public static <T> java.util.Spliterator<T> emptySpliterator();
+    method public static <T> java.util.Iterator<T> iterator(java.util.Spliterator<? extends T>);
+    method public static java.util.PrimitiveIterator.OfInt iterator(java.util.Spliterator.OfInt);
+    method public static java.util.PrimitiveIterator.OfLong iterator(java.util.Spliterator.OfLong);
+    method public static java.util.PrimitiveIterator.OfDouble iterator(java.util.Spliterator.OfDouble);
+    method public static <T> java.util.Spliterator<T> spliterator(Object[], int);
+    method public static <T> java.util.Spliterator<T> spliterator(Object[], int, int, int);
+    method public static java.util.Spliterator.OfInt spliterator(int[], int);
+    method public static java.util.Spliterator.OfInt spliterator(int[], int, int, int);
+    method public static java.util.Spliterator.OfLong spliterator(long[], int);
+    method public static java.util.Spliterator.OfLong spliterator(long[], int, int, int);
+    method public static java.util.Spliterator.OfDouble spliterator(double[], int);
+    method public static java.util.Spliterator.OfDouble spliterator(double[], int, int, int);
+    method public static <T> java.util.Spliterator<T> spliterator(java.util.Collection<? extends T>, int);
+    method public static <T> java.util.Spliterator<T> spliterator(java.util.Iterator<? extends T>, long, int);
+    method public static java.util.Spliterator.OfInt spliterator(java.util.PrimitiveIterator.OfInt, long, int);
+    method public static java.util.Spliterator.OfLong spliterator(java.util.PrimitiveIterator.OfLong, long, int);
+    method public static java.util.Spliterator.OfDouble spliterator(java.util.PrimitiveIterator.OfDouble, long, int);
+    method public static <T> java.util.Spliterator<T> spliteratorUnknownSize(java.util.Iterator<? extends T>, int);
+    method public static java.util.Spliterator.OfInt spliteratorUnknownSize(java.util.PrimitiveIterator.OfInt, int);
+    method public static java.util.Spliterator.OfLong spliteratorUnknownSize(java.util.PrimitiveIterator.OfLong, int);
+    method public static java.util.Spliterator.OfDouble spliteratorUnknownSize(java.util.PrimitiveIterator.OfDouble, int);
+  }
+
+  public abstract static class Spliterators.AbstractDoubleSpliterator implements java.util.Spliterator.OfDouble {
+    ctor protected Spliterators.AbstractDoubleSpliterator(long, int);
+    method public int characteristics();
+    method public long estimateSize();
+    method public java.util.Spliterator.OfDouble trySplit();
+  }
+
+  public abstract static class Spliterators.AbstractIntSpliterator implements java.util.Spliterator.OfInt {
+    ctor protected Spliterators.AbstractIntSpliterator(long, int);
+    method public int characteristics();
+    method public long estimateSize();
+    method public java.util.Spliterator.OfInt trySplit();
+  }
+
+  public abstract static class Spliterators.AbstractLongSpliterator implements java.util.Spliterator.OfLong {
+    ctor protected Spliterators.AbstractLongSpliterator(long, int);
+    method public int characteristics();
+    method public long estimateSize();
+    method public java.util.Spliterator.OfLong trySplit();
+  }
+
+  public abstract static class Spliterators.AbstractSpliterator<T> implements java.util.Spliterator<T> {
+    ctor protected Spliterators.AbstractSpliterator(long, int);
+    method public int characteristics();
+    method public long estimateSize();
+    method public java.util.Spliterator<T> trySplit();
+  }
+
+  public final class SplittableRandom {
+    ctor public SplittableRandom(long);
+    ctor public SplittableRandom();
+    method public java.util.stream.DoubleStream doubles(long);
+    method public java.util.stream.DoubleStream doubles();
+    method public java.util.stream.DoubleStream doubles(long, double, double);
+    method public java.util.stream.DoubleStream doubles(double, double);
+    method public java.util.stream.IntStream ints(long);
+    method public java.util.stream.IntStream ints();
+    method public java.util.stream.IntStream ints(long, int, int);
+    method public java.util.stream.IntStream ints(int, int);
+    method public java.util.stream.LongStream longs(long);
+    method public java.util.stream.LongStream longs();
+    method public java.util.stream.LongStream longs(long, long, long);
+    method public java.util.stream.LongStream longs(long, long);
+    method public boolean nextBoolean();
+    method public double nextDouble();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt();
+    method public int nextInt(int);
+    method public int nextInt(int, int);
+    method public long nextLong();
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+    method public java.util.SplittableRandom split();
+  }
+
+  public class Stack<E> extends java.util.Vector<E> {
+    ctor public Stack();
+    method public boolean empty();
+    method public E peek();
+    method public E pop();
+    method public E push(E);
+    method public int search(Object);
+  }
+
+  public final class StringJoiner {
+    ctor public StringJoiner(CharSequence);
+    ctor public StringJoiner(CharSequence, CharSequence, CharSequence);
+    method public java.util.StringJoiner add(CharSequence);
+    method public int length();
+    method public java.util.StringJoiner merge(java.util.StringJoiner);
+    method public java.util.StringJoiner setEmptyValue(CharSequence);
+  }
+
+  public class StringTokenizer implements java.util.Enumeration<java.lang.Object> {
+    ctor public StringTokenizer(String, String, boolean);
+    ctor public StringTokenizer(String, String);
+    ctor public StringTokenizer(String);
+    method public int countTokens();
+    method public boolean hasMoreElements();
+    method public boolean hasMoreTokens();
+    method public Object nextElement();
+    method public String nextToken();
+    method public String nextToken(String);
+  }
+
+  public abstract class TimeZone implements java.lang.Cloneable java.io.Serializable {
+    ctor public TimeZone();
+    method public Object clone();
+    method public static String[] getAvailableIDs(int);
+    method public static String[] getAvailableIDs();
+    method public int getDSTSavings();
+    method public static java.util.TimeZone getDefault();
+    method public final String getDisplayName();
+    method public final String getDisplayName(java.util.Locale);
+    method public final String getDisplayName(boolean, int);
+    method public String getDisplayName(boolean, int, java.util.Locale);
+    method public String getID();
+    method public abstract int getOffset(int, int, int, int, int, int);
+    method public int getOffset(long);
+    method public abstract int getRawOffset();
+    method public static java.util.TimeZone getTimeZone(String);
+    method public static java.util.TimeZone getTimeZone(java.time.ZoneId);
+    method public boolean hasSameRules(java.util.TimeZone);
+    method public abstract boolean inDaylightTime(java.util.Date);
+    method public boolean observesDaylightTime();
+    method public static void setDefault(java.util.TimeZone);
+    method public void setID(String);
+    method public abstract void setRawOffset(int);
+    method public java.time.ZoneId toZoneId();
+    method public abstract boolean useDaylightTime();
+    field public static final int LONG = 1; // 0x1
+    field public static final int SHORT = 0; // 0x0
+  }
+
+  public class Timer {
+    ctor public Timer();
+    ctor public Timer(boolean);
+    ctor public Timer(String);
+    ctor public Timer(String, boolean);
+    method public void cancel();
+    method public int purge();
+    method public void schedule(java.util.TimerTask, long);
+    method public void schedule(java.util.TimerTask, java.util.Date);
+    method public void schedule(java.util.TimerTask, long, long);
+    method public void schedule(java.util.TimerTask, java.util.Date, long);
+    method public void scheduleAtFixedRate(java.util.TimerTask, long, long);
+    method public void scheduleAtFixedRate(java.util.TimerTask, java.util.Date, long);
+  }
+
+  public abstract class TimerTask implements java.lang.Runnable {
+    ctor protected TimerTask();
+    method public boolean cancel();
+    method public long scheduledExecutionTime();
+  }
+
+  public class TooManyListenersException extends java.lang.Exception {
+    ctor public TooManyListenersException();
+    ctor public TooManyListenersException(String);
+  }
+
+  public class TreeMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.NavigableMap<K,V> java.io.Serializable {
+    ctor public TreeMap();
+    ctor public TreeMap(@Nullable java.util.Comparator<? super K>);
+    ctor public TreeMap(@NonNull java.util.Map<? extends K,? extends V>);
+    ctor public TreeMap(@NonNull java.util.SortedMap<K,? extends V>);
+    method @Nullable public java.util.Map.Entry<K,V> ceilingEntry(K);
+    method @Nullable public K ceilingKey(K);
+    method @NonNull public Object clone();
+    method @Nullable public java.util.Comparator<? super K> comparator();
+    method @NonNull public java.util.NavigableSet<K> descendingKeySet();
+    method @NonNull public java.util.NavigableMap<K,V> descendingMap();
+    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+    method @Nullable public java.util.Map.Entry<K,V> firstEntry();
+    method public K firstKey();
+    method @Nullable public java.util.Map.Entry<K,V> floorEntry(K);
+    method @Nullable public K floorKey(K);
+    method @NonNull public java.util.NavigableMap<K,V> headMap(K, boolean);
+    method @NonNull public java.util.SortedMap<K,V> headMap(K);
+    method @Nullable public java.util.Map.Entry<K,V> higherEntry(K);
+    method @Nullable public K higherKey(K);
+    method @Nullable public java.util.Map.Entry<K,V> lastEntry();
+    method public K lastKey();
+    method @Nullable public java.util.Map.Entry<K,V> lowerEntry(K);
+    method @Nullable public K lowerKey(K);
+    method @NonNull public java.util.NavigableSet<K> navigableKeySet();
+    method @Nullable public java.util.Map.Entry<K,V> pollFirstEntry();
+    method @Nullable public java.util.Map.Entry<K,V> pollLastEntry();
+    method @NonNull public java.util.NavigableMap<K,V> subMap(K, boolean, K, boolean);
+    method @NonNull public java.util.SortedMap<K,V> subMap(K, K);
+    method @NonNull public java.util.NavigableMap<K,V> tailMap(K, boolean);
+    method @NonNull public java.util.SortedMap<K,V> tailMap(K);
+  }
+
+  public class TreeSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.util.NavigableSet<E> java.io.Serializable {
+    ctor public TreeSet();
+    ctor public TreeSet(java.util.Comparator<? super E>);
+    ctor public TreeSet(java.util.Collection<? extends E>);
+    ctor public TreeSet(java.util.SortedSet<E>);
+    method public E ceiling(E);
+    method public Object clone();
+    method public java.util.Comparator<? super E> comparator();
+    method public java.util.Iterator<E> descendingIterator();
+    method public java.util.NavigableSet<E> descendingSet();
+    method public E first();
+    method public E floor(E);
+    method public java.util.NavigableSet<E> headSet(E, boolean);
+    method public java.util.SortedSet<E> headSet(E);
+    method public E higher(E);
+    method public java.util.Iterator<E> iterator();
+    method public E last();
+    method public E lower(E);
+    method public E pollFirst();
+    method public E pollLast();
+    method public int size();
+    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
+    method public java.util.SortedSet<E> subSet(E, E);
+    method public java.util.NavigableSet<E> tailSet(E, boolean);
+    method public java.util.SortedSet<E> tailSet(E);
+  }
+
+  public final class UUID implements java.lang.Comparable<java.util.UUID> java.io.Serializable {
+    ctor public UUID(long, long);
+    method public int clockSequence();
+    method public int compareTo(java.util.UUID);
+    method public static java.util.UUID fromString(String);
+    method public long getLeastSignificantBits();
+    method public long getMostSignificantBits();
+    method public static java.util.UUID nameUUIDFromBytes(byte[]);
+    method public long node();
+    method public static java.util.UUID randomUUID();
+    method public long timestamp();
+    method public int variant();
+    method public int version();
+  }
+
+  public class UnknownFormatConversionException extends java.util.IllegalFormatException {
+    ctor public UnknownFormatConversionException(String);
+    method public String getConversion();
+  }
+
+  public class UnknownFormatFlagsException extends java.util.IllegalFormatException {
+    ctor public UnknownFormatFlagsException(String);
+    method public String getFlags();
+  }
+
+  public class Vector<E> extends java.util.AbstractList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
+    ctor public Vector(int, int);
+    ctor public Vector(int);
+    ctor public Vector();
+    ctor public Vector(@NonNull java.util.Collection<? extends E>);
+    method public void addElement(E);
+    method public int capacity();
+    method @NonNull public Object clone();
+    method public void copyInto(@NonNull Object[]);
+    method public E elementAt(int);
+    method @NonNull public java.util.Enumeration<E> elements();
+    method public void ensureCapacity(int);
+    method public E firstElement();
+    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
+    method public E get(int);
+    method public int indexOf(@Nullable Object, int);
+    method public void insertElementAt(E, int);
+    method public E lastElement();
+    method public int lastIndexOf(@Nullable Object, int);
+    method public void removeAllElements();
+    method public boolean removeElement(@Nullable Object);
+    method public void removeElementAt(int);
+    method public void setElementAt(E, int);
+    method public void setSize(int);
+    method public int size();
+    method public void trimToSize();
+    field protected int capacityIncrement;
+    field protected int elementCount;
+    field @NonNull protected Object[] elementData;
+  }
+
+  public class WeakHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.Map<K,V> {
+    ctor public WeakHashMap(int, float);
+    ctor public WeakHashMap(int);
+    ctor public WeakHashMap();
+    ctor public WeakHashMap(@NonNull java.util.Map<? extends K,? extends V>);
+    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+  }
+
+}
+
+package java.util.concurrent {
+
+  public abstract class AbstractExecutorService implements java.util.concurrent.ExecutorService {
+    ctor public AbstractExecutorService();
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.lang.InterruptedException;
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method protected <T> java.util.concurrent.RunnableFuture<T> newTaskFor(Runnable, T);
+    method protected <T> java.util.concurrent.RunnableFuture<T> newTaskFor(java.util.concurrent.Callable<T>);
+    method public java.util.concurrent.Future<?> submit(Runnable);
+    method public <T> java.util.concurrent.Future<T> submit(Runnable, T);
+    method public <T> java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T>);
+  }
+
+  public class ArrayBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
+    ctor public ArrayBlockingQueue(int);
+    ctor public ArrayBlockingQueue(int, boolean);
+    ctor public ArrayBlockingQueue(int, boolean, java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E peek();
+    method public E poll();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void put(E) throws java.lang.InterruptedException;
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public interface BlockingDeque<E> extends java.util.concurrent.BlockingQueue<E> java.util.Deque<E> {
+    method public boolean offerFirst(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean offerLast(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E pollFirst(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E pollLast(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void putFirst(E) throws java.lang.InterruptedException;
+    method public void putLast(E) throws java.lang.InterruptedException;
+    method public E takeFirst() throws java.lang.InterruptedException;
+    method public E takeLast() throws java.lang.InterruptedException;
+  }
+
+  public interface BlockingQueue<E> extends java.util.Queue<E> {
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void put(E) throws java.lang.InterruptedException;
+    method public int remainingCapacity();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public class BrokenBarrierException extends java.lang.Exception {
+    ctor public BrokenBarrierException();
+    ctor public BrokenBarrierException(String);
+  }
+
+  @java.lang.FunctionalInterface public interface Callable<V> {
+    method public V call() throws java.lang.Exception;
+  }
+
+  public class CancellationException extends java.lang.IllegalStateException {
+    ctor public CancellationException();
+    ctor public CancellationException(String);
+  }
+
+  public class CompletableFuture<T> implements java.util.concurrent.CompletionStage<T> java.util.concurrent.Future<T> {
+    ctor public CompletableFuture();
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> allOf(java.util.concurrent.CompletableFuture<?>...);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Object> anyOf(java.util.concurrent.CompletableFuture<?>...);
+    method public <U> java.util.concurrent.CompletableFuture<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>, java.util.concurrent.Executor);
+    method public boolean cancel(boolean);
+    method public boolean complete(T);
+    method public java.util.concurrent.CompletableFuture<T> completeAsync(java.util.function.Supplier<? extends T>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> completeAsync(java.util.function.Supplier<? extends T>);
+    method public boolean completeExceptionally(Throwable);
+    method public java.util.concurrent.CompletableFuture<T> completeOnTimeout(T, long, java.util.concurrent.TimeUnit);
+    method public static <U> java.util.concurrent.CompletableFuture<U> completedFuture(U);
+    method public static <U> java.util.concurrent.CompletionStage<U> completedStage(U);
+    method public java.util.concurrent.CompletableFuture<T> copy();
+    method public java.util.concurrent.Executor defaultExecutor();
+    method public static java.util.concurrent.Executor delayedExecutor(long, java.util.concurrent.TimeUnit, java.util.concurrent.Executor);
+    method public static java.util.concurrent.Executor delayedExecutor(long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.CompletableFuture<T> exceptionally(java.util.function.Function<java.lang.Throwable,? extends T>);
+    method public static <U> java.util.concurrent.CompletableFuture<U> failedFuture(Throwable);
+    method public static <U> java.util.concurrent.CompletionStage<U> failedStage(Throwable);
+    method public T get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public T get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public T getNow(T);
+    method public int getNumberOfDependents();
+    method public <U> java.util.concurrent.CompletableFuture<U> handle(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>, java.util.concurrent.Executor);
+    method public boolean isCancelled();
+    method public boolean isCompletedExceptionally();
+    method public boolean isDone();
+    method public T join();
+    method public java.util.concurrent.CompletionStage<T> minimalCompletionStage();
+    method public <U> java.util.concurrent.CompletableFuture<U> newIncompleteFuture();
+    method public void obtrudeException(Throwable);
+    method public void obtrudeValue(T);
+    method public java.util.concurrent.CompletableFuture<T> orTimeout(long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(Runnable);
+    method public static java.util.concurrent.CompletableFuture<java.lang.Void> runAsync(Runnable, java.util.concurrent.Executor);
+    method public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>);
+    method public static <U> java.util.concurrent.CompletableFuture<U> supplyAsync(java.util.function.Supplier<U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
+    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
+    method public <U> java.util.concurrent.CompletableFuture<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenApply(java.util.function.Function<? super T,? extends U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>, java.util.concurrent.Executor);
+    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
+    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
+    method public <U, V> java.util.concurrent.CompletableFuture<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenCompose(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
+    method public <U> java.util.concurrent.CompletableFuture<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRun(Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(Runnable);
+    method public java.util.concurrent.CompletableFuture<java.lang.Void> thenRunAsync(Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public java.util.concurrent.CompletableFuture<T> whenComplete(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletableFuture<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
+  public static interface CompletableFuture.AsynchronousCompletionTask {
+  }
+
+  public class CompletionException extends java.lang.RuntimeException {
+    ctor protected CompletionException();
+    ctor protected CompletionException(String);
+    ctor public CompletionException(String, Throwable);
+    ctor public CompletionException(Throwable);
+  }
+
+  public interface CompletionService<V> {
+    method public java.util.concurrent.Future<V> poll();
+    method public java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public java.util.concurrent.Future<V> submit(java.util.concurrent.Callable<V>);
+    method public java.util.concurrent.Future<V> submit(Runnable, V);
+    method public java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
+  }
+
+  public interface CompletionStage<T> {
+    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> acceptEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletionStage<U> applyToEither(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
+    method public <U> java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>);
+    method public <U> java.util.concurrent.CompletionStage<U> applyToEitherAsync(java.util.concurrent.CompletionStage<? extends T>, java.util.function.Function<? super T,U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletionStage<T> exceptionally(java.util.function.Function<java.lang.Throwable,? extends T>);
+    method public <U> java.util.concurrent.CompletionStage<U> handle(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
+    method public <U> java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>);
+    method public <U> java.util.concurrent.CompletionStage<U> handleAsync(java.util.function.BiFunction<? super T,java.lang.Throwable,? extends U>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBoth(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterBothAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEither(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> runAfterEitherAsync(java.util.concurrent.CompletionStage<?>, Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAccept(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptAsync(java.util.function.Consumer<? super T>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBoth(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
+    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>);
+    method public <U> java.util.concurrent.CompletionStage<java.lang.Void> thenAcceptBothAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiConsumer<? super T,? super U>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletionStage<U> thenApply(java.util.function.Function<? super T,? extends U>);
+    method public <U> java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>);
+    method public <U> java.util.concurrent.CompletionStage<U> thenApplyAsync(java.util.function.Function<? super T,? extends U>, java.util.concurrent.Executor);
+    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombine(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
+    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>);
+    method public <U, V> java.util.concurrent.CompletionStage<V> thenCombineAsync(java.util.concurrent.CompletionStage<? extends U>, java.util.function.BiFunction<? super T,? super U,? extends V>, java.util.concurrent.Executor);
+    method public <U> java.util.concurrent.CompletionStage<U> thenCompose(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
+    method public <U> java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>);
+    method public <U> java.util.concurrent.CompletionStage<U> thenComposeAsync(java.util.function.Function<? super T,? extends java.util.concurrent.CompletionStage<U>>, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRun(Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(Runnable);
+    method public java.util.concurrent.CompletionStage<java.lang.Void> thenRunAsync(Runnable, java.util.concurrent.Executor);
+    method public java.util.concurrent.CompletableFuture<T> toCompletableFuture();
+    method public java.util.concurrent.CompletionStage<T> whenComplete(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>);
+    method public java.util.concurrent.CompletionStage<T> whenCompleteAsync(java.util.function.BiConsumer<? super T,? super java.lang.Throwable>, java.util.concurrent.Executor);
+  }
+
+  public class ConcurrentHashMap<K, V> extends java.util.AbstractMap<K,V> implements java.util.concurrent.ConcurrentMap<K,V> java.io.Serializable {
+    ctor public ConcurrentHashMap();
+    ctor public ConcurrentHashMap(int);
+    ctor public ConcurrentHashMap(@NonNull java.util.Map<? extends K,? extends V>);
+    ctor public ConcurrentHashMap(int, float);
+    ctor public ConcurrentHashMap(int, float, int);
+    method public boolean contains(@NonNull Object);
+    method @NonNull public java.util.Enumeration<V> elements();
+    method @NonNull public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+    method public void forEach(long, @NonNull java.util.function.BiConsumer<? super K,? super V>);
+    method public <U> void forEach(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
+    method public void forEachEntry(long, @NonNull java.util.function.Consumer<? super java.util.Map.Entry<K,V>>);
+    method public <U> void forEachEntry(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>, @NonNull java.util.function.Consumer<? super U>);
+    method public void forEachKey(long, @NonNull java.util.function.Consumer<? super K>);
+    method public <U> void forEachKey(long, @NonNull java.util.function.Function<? super K,? extends U>, @NonNull java.util.function.Consumer<? super U>);
+    method public void forEachValue(long, @NonNull java.util.function.Consumer<? super V>);
+    method public <U> void forEachValue(long, @NonNull java.util.function.Function<? super V,? extends U>, @NonNull java.util.function.Consumer<? super U>);
+    method @NonNull public java.util.concurrent.ConcurrentHashMap.KeySetView<K,V> keySet(@NonNull V);
+    method @NonNull public java.util.Enumeration<K> keys();
+    method public long mappingCount();
+    method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet();
+    method @NonNull public static <K> java.util.concurrent.ConcurrentHashMap.KeySetView<K,java.lang.Boolean> newKeySet(int);
+    method @Nullable public <U> U reduce(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
+    method @Nullable public java.util.Map.Entry<K,V> reduceEntries(long, @NonNull java.util.function.BiFunction<java.util.Map.Entry<K,V>,java.util.Map.Entry<K,V>,? extends java.util.Map.Entry<K,V>>);
+    method @Nullable public <U> U reduceEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
+    method public double reduceEntriesToDouble(long, @NonNull java.util.function.ToDoubleFunction<java.util.Map.Entry<K,V>>, double, @NonNull java.util.function.DoubleBinaryOperator);
+    method public int reduceEntriesToInt(long, @NonNull java.util.function.ToIntFunction<java.util.Map.Entry<K,V>>, int, @NonNull java.util.function.IntBinaryOperator);
+    method public long reduceEntriesToLong(long, @NonNull java.util.function.ToLongFunction<java.util.Map.Entry<K,V>>, long, @NonNull java.util.function.LongBinaryOperator);
+    method @Nullable public K reduceKeys(long, @NonNull java.util.function.BiFunction<? super K,? super K,? extends K>);
+    method @Nullable public <U> U reduceKeys(long, @NonNull java.util.function.Function<? super K,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
+    method public double reduceKeysToDouble(long, @NonNull java.util.function.ToDoubleFunction<? super K>, double, @NonNull java.util.function.DoubleBinaryOperator);
+    method public int reduceKeysToInt(long, @NonNull java.util.function.ToIntFunction<? super K>, int, @NonNull java.util.function.IntBinaryOperator);
+    method public long reduceKeysToLong(long, @NonNull java.util.function.ToLongFunction<? super K>, long, @NonNull java.util.function.LongBinaryOperator);
+    method public double reduceToDouble(long, @NonNull java.util.function.ToDoubleBiFunction<? super K,? super V>, double, @NonNull java.util.function.DoubleBinaryOperator);
+    method public int reduceToInt(long, @NonNull java.util.function.ToIntBiFunction<? super K,? super V>, int, @NonNull java.util.function.IntBinaryOperator);
+    method public long reduceToLong(long, @NonNull java.util.function.ToLongBiFunction<? super K,? super V>, long, @NonNull java.util.function.LongBinaryOperator);
+    method @Nullable public V reduceValues(long, @NonNull java.util.function.BiFunction<? super V,? super V,? extends V>);
+    method @Nullable public <U> U reduceValues(long, @NonNull java.util.function.Function<? super V,? extends U>, @NonNull java.util.function.BiFunction<? super U,? super U,? extends U>);
+    method public double reduceValuesToDouble(long, @NonNull java.util.function.ToDoubleFunction<? super V>, double, @NonNull java.util.function.DoubleBinaryOperator);
+    method public int reduceValuesToInt(long, @NonNull java.util.function.ToIntFunction<? super V>, int, @NonNull java.util.function.IntBinaryOperator);
+    method public long reduceValuesToLong(long, @NonNull java.util.function.ToLongFunction<? super V>, long, @NonNull java.util.function.LongBinaryOperator);
+    method @Nullable public <U> U search(long, @NonNull java.util.function.BiFunction<? super K,? super V,? extends U>);
+    method @Nullable public <U> U searchEntries(long, @NonNull java.util.function.Function<java.util.Map.Entry<K,V>,? extends U>);
+    method @Nullable public <U> U searchKeys(long, @NonNull java.util.function.Function<? super K,? extends U>);
+    method @Nullable public <U> U searchValues(long, @NonNull java.util.function.Function<? super V,? extends U>);
+  }
+
+  public static class ConcurrentHashMap.KeySetView<K, V> implements java.util.Collection<K> java.io.Serializable java.util.Set<K> {
+    method public boolean add(@NonNull K);
+    method public boolean addAll(@NonNull java.util.Collection<? extends K>);
+    method public final void clear();
+    method public boolean contains(@NonNull Object);
+    method public final boolean containsAll(@NonNull java.util.Collection<?>);
+    method public void forEach(@NonNull java.util.function.Consumer<? super K>);
+    method @NonNull public java.util.concurrent.ConcurrentHashMap<K,V> getMap();
+    method @Nullable public V getMappedValue();
+    method public final boolean isEmpty();
+    method @NonNull public java.util.Iterator<K> iterator();
+    method public boolean remove(@NonNull Object);
+    method public final boolean removeAll(@NonNull java.util.Collection<?>);
+    method public final boolean retainAll(@NonNull java.util.Collection<?>);
+    method public final int size();
+    method @NonNull public java.util.Spliterator<K> spliterator();
+    method @NonNull public final Object[] toArray();
+    method @NonNull public final <T> T[] toArray(@NonNull T[]);
+    method @NonNull public final String toString();
+  }
+
+  public class ConcurrentLinkedDeque<E> extends java.util.AbstractCollection<E> implements java.util.Deque<E> java.io.Serializable {
+    ctor public ConcurrentLinkedDeque();
+    ctor public ConcurrentLinkedDeque(java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method public java.util.Iterator<E> descendingIterator();
+    method public E element();
+    method public E getFirst();
+    method public E getLast();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offerFirst(E);
+    method public boolean offerLast(E);
+    method public E peek();
+    method public E peekFirst();
+    method public E peekLast();
+    method public E poll();
+    method public E pollFirst();
+    method public E pollLast();
+    method public E pop();
+    method public void push(E);
+    method public E remove();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(Object);
+    method public int size();
+  }
+
+  public class ConcurrentLinkedQueue<E> extends java.util.AbstractQueue<E> implements java.util.Queue<E> java.io.Serializable {
+    ctor public ConcurrentLinkedQueue();
+    ctor public ConcurrentLinkedQueue(java.util.Collection<? extends E>);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll();
+    method public int size();
+  }
+
+  public interface ConcurrentMap<K, V> extends java.util.Map<K,V> {
+    method public V putIfAbsent(K, V);
+    method public boolean remove(Object, Object);
+    method public boolean replace(K, V, V);
+    method public V replace(K, V);
+  }
+
+  public interface ConcurrentNavigableMap<K, V> extends java.util.concurrent.ConcurrentMap<K,V> java.util.NavigableMap<K,V> {
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap();
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K);
+    method public java.util.NavigableSet<K> keySet();
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, boolean, K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, K);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K);
+  }
+
+  public class ConcurrentSkipListMap<K, V> extends java.util.AbstractMap<K,V> implements java.lang.Cloneable java.util.concurrent.ConcurrentNavigableMap<K,V> java.io.Serializable {
+    ctor public ConcurrentSkipListMap();
+    ctor public ConcurrentSkipListMap(java.util.Comparator<? super K>);
+    ctor public ConcurrentSkipListMap(java.util.Map<? extends K,? extends V>);
+    ctor public ConcurrentSkipListMap(java.util.SortedMap<K,? extends V>);
+    method public java.util.Map.Entry<K,V> ceilingEntry(K);
+    method public K ceilingKey(K);
+    method public java.util.concurrent.ConcurrentSkipListMap<K,V> clone();
+    method public java.util.Comparator<? super K> comparator();
+    method public java.util.NavigableSet<K> descendingKeySet();
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> descendingMap();
+    method public java.util.Set<java.util.Map.Entry<K,V>> entrySet();
+    method public java.util.Map.Entry<K,V> firstEntry();
+    method public K firstKey();
+    method public java.util.Map.Entry<K,V> floorEntry(K);
+    method public K floorKey(K);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> headMap(K);
+    method public java.util.Map.Entry<K,V> higherEntry(K);
+    method public K higherKey(K);
+    method public java.util.NavigableSet<K> keySet();
+    method public java.util.Map.Entry<K,V> lastEntry();
+    method public K lastKey();
+    method public java.util.Map.Entry<K,V> lowerEntry(K);
+    method public K lowerKey(K);
+    method public java.util.NavigableSet<K> navigableKeySet();
+    method public java.util.Map.Entry<K,V> pollFirstEntry();
+    method public java.util.Map.Entry<K,V> pollLastEntry();
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, boolean, K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> subMap(K, K);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K, boolean);
+    method public java.util.concurrent.ConcurrentNavigableMap<K,V> tailMap(K);
+  }
+
+  public class ConcurrentSkipListSet<E> extends java.util.AbstractSet<E> implements java.lang.Cloneable java.util.NavigableSet<E> java.io.Serializable {
+    ctor public ConcurrentSkipListSet();
+    ctor public ConcurrentSkipListSet(java.util.Comparator<? super E>);
+    ctor public ConcurrentSkipListSet(java.util.Collection<? extends E>);
+    ctor public ConcurrentSkipListSet(java.util.SortedSet<E>);
+    method public E ceiling(E);
+    method public java.util.concurrent.ConcurrentSkipListSet<E> clone();
+    method public java.util.Comparator<? super E> comparator();
+    method public java.util.Iterator<E> descendingIterator();
+    method public java.util.NavigableSet<E> descendingSet();
+    method public E first();
+    method public E floor(E);
+    method public java.util.NavigableSet<E> headSet(E, boolean);
+    method public java.util.NavigableSet<E> headSet(E);
+    method public E higher(E);
+    method public java.util.Iterator<E> iterator();
+    method public E last();
+    method public E lower(E);
+    method public E pollFirst();
+    method public E pollLast();
+    method public int size();
+    method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean);
+    method public java.util.NavigableSet<E> subSet(E, E);
+    method public java.util.NavigableSet<E> tailSet(E, boolean);
+    method public java.util.NavigableSet<E> tailSet(E);
+  }
+
+  public class CopyOnWriteArrayList<E> implements java.lang.Cloneable java.util.List<E> java.util.RandomAccess java.io.Serializable {
+    ctor public CopyOnWriteArrayList();
+    ctor public CopyOnWriteArrayList(@NonNull java.util.Collection<? extends E>);
+    ctor public CopyOnWriteArrayList(@NonNull E[]);
+    method public boolean add(E);
+    method public void add(int, E);
+    method public boolean addAll(@NonNull java.util.Collection<? extends E>);
+    method public boolean addAll(int, @NonNull java.util.Collection<? extends E>);
+    method public int addAllAbsent(@NonNull java.util.Collection<? extends E>);
+    method public boolean addIfAbsent(E);
+    method public void clear();
+    method @NonNull public Object clone();
+    method public boolean contains(@Nullable Object);
+    method public boolean containsAll(@NonNull java.util.Collection<?>);
+    method public void forEach(@NonNull java.util.function.Consumer<? super E>);
+    method public E get(int);
+    method public int indexOf(@Nullable Object);
+    method public int indexOf(@Nullable E, int);
+    method public boolean isEmpty();
+    method @NonNull public java.util.Iterator<E> iterator();
+    method public int lastIndexOf(@Nullable Object);
+    method public int lastIndexOf(@Nullable E, int);
+    method @NonNull public java.util.ListIterator<E> listIterator();
+    method @NonNull public java.util.ListIterator<E> listIterator(int);
+    method public E remove(int);
+    method public boolean remove(@Nullable Object);
+    method public boolean removeAll(@NonNull java.util.Collection<?>);
+    method public boolean retainAll(@NonNull java.util.Collection<?>);
+    method public E set(int, E);
+    method public int size();
+    method @NonNull public java.util.List<E> subList(int, int);
+    method @NonNull public Object[] toArray();
+    method @NonNull public <T> T[] toArray(@NonNull T[]);
+  }
+
+  public class CopyOnWriteArraySet<E> extends java.util.AbstractSet<E> implements java.io.Serializable {
+    ctor public CopyOnWriteArraySet();
+    ctor public CopyOnWriteArraySet(java.util.Collection<? extends E>);
+    method public void forEach(java.util.function.Consumer<? super E>);
+    method public java.util.Iterator<E> iterator();
+    method public int size();
+  }
+
+  public class CountDownLatch {
+    ctor public CountDownLatch(int);
+    method public void await() throws java.lang.InterruptedException;
+    method public boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void countDown();
+    method public long getCount();
+  }
+
+  public abstract class CountedCompleter<T> extends java.util.concurrent.ForkJoinTask<T> {
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>, int);
+    ctor protected CountedCompleter(java.util.concurrent.CountedCompleter<?>);
+    ctor protected CountedCompleter();
+    method public final void addToPendingCount(int);
+    method public final boolean compareAndSetPendingCount(int, int);
+    method public void complete(T);
+    method public abstract void compute();
+    method public final int decrementPendingCountUnlessZero();
+    method protected final boolean exec();
+    method public final java.util.concurrent.CountedCompleter<?> firstComplete();
+    method public final java.util.concurrent.CountedCompleter<?> getCompleter();
+    method public final int getPendingCount();
+    method public T getRawResult();
+    method public final java.util.concurrent.CountedCompleter<?> getRoot();
+    method public final void helpComplete(int);
+    method public final java.util.concurrent.CountedCompleter<?> nextComplete();
+    method public void onCompletion(java.util.concurrent.CountedCompleter<?>);
+    method public boolean onExceptionalCompletion(Throwable, java.util.concurrent.CountedCompleter<?>);
+    method public final void propagateCompletion();
+    method public final void quietlyCompleteRoot();
+    method public final void setPendingCount(int);
+    method protected void setRawResult(T);
+    method public final void tryComplete();
+  }
+
+  public class CyclicBarrier {
+    ctor public CyclicBarrier(int, Runnable);
+    ctor public CyclicBarrier(int);
+    method public int await() throws java.util.concurrent.BrokenBarrierException, java.lang.InterruptedException;
+    method public int await(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.BrokenBarrierException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public int getNumberWaiting();
+    method public int getParties();
+    method public boolean isBroken();
+    method public void reset();
+  }
+
+  public class DelayQueue<E extends java.util.concurrent.Delayed> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> {
+    ctor public DelayQueue();
+    ctor public DelayQueue(java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
+    method public E peek();
+    method public E poll();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void put(E);
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public interface Delayed extends java.lang.Comparable<java.util.concurrent.Delayed> {
+    method public long getDelay(java.util.concurrent.TimeUnit);
+  }
+
+  public class Exchanger<V> {
+    ctor public Exchanger();
+    method public V exchange(V) throws java.lang.InterruptedException;
+    method public V exchange(V, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+  }
+
+  public class ExecutionException extends java.lang.Exception {
+    ctor protected ExecutionException();
+    ctor protected ExecutionException(String);
+    ctor public ExecutionException(String, Throwable);
+    ctor public ExecutionException(Throwable);
+  }
+
+  public interface Executor {
+    method public void execute(Runnable);
+  }
+
+  public class ExecutorCompletionService<V> implements java.util.concurrent.CompletionService<V> {
+    ctor public ExecutorCompletionService(java.util.concurrent.Executor);
+    ctor public ExecutorCompletionService(java.util.concurrent.Executor, java.util.concurrent.BlockingQueue<java.util.concurrent.Future<V>>);
+    method public java.util.concurrent.Future<V> poll();
+    method public java.util.concurrent.Future<V> poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public java.util.concurrent.Future<V> submit(java.util.concurrent.Callable<V>);
+    method public java.util.concurrent.Future<V> submit(Runnable, V);
+    method public java.util.concurrent.Future<V> take() throws java.lang.InterruptedException;
+  }
+
+  public interface ExecutorService extends java.util.concurrent.Executor {
+    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.lang.InterruptedException;
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public <T> T invokeAny(java.util.Collection<? extends java.util.concurrent.Callable<T>>, long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public boolean isShutdown();
+    method public boolean isTerminated();
+    method public void shutdown();
+    method public java.util.List<java.lang.Runnable> shutdownNow();
+    method public <T> java.util.concurrent.Future<T> submit(java.util.concurrent.Callable<T>);
+    method public <T> java.util.concurrent.Future<T> submit(Runnable, T);
+    method public java.util.concurrent.Future<?> submit(Runnable);
+  }
+
+  public class Executors {
+    method public static <T> java.util.concurrent.Callable<T> callable(Runnable, T);
+    method public static java.util.concurrent.Callable<java.lang.Object> callable(Runnable);
+    method public static java.util.concurrent.Callable<java.lang.Object> callable(java.security.PrivilegedAction<?>);
+    method public static java.util.concurrent.Callable<java.lang.Object> callable(java.security.PrivilegedExceptionAction<?>);
+    method public static java.util.concurrent.ThreadFactory defaultThreadFactory();
+    method public static java.util.concurrent.ExecutorService newCachedThreadPool();
+    method public static java.util.concurrent.ExecutorService newCachedThreadPool(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newFixedThreadPool(int);
+    method public static java.util.concurrent.ExecutorService newFixedThreadPool(int, java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(int);
+    method public static java.util.concurrent.ScheduledExecutorService newScheduledThreadPool(int, java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newSingleThreadExecutor();
+    method public static java.util.concurrent.ExecutorService newSingleThreadExecutor(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor();
+    method public static java.util.concurrent.ScheduledExecutorService newSingleThreadScheduledExecutor(java.util.concurrent.ThreadFactory);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool(int);
+    method public static java.util.concurrent.ExecutorService newWorkStealingPool();
+    method public static <T> java.util.concurrent.Callable<T> privilegedCallable(java.util.concurrent.Callable<T>);
+    method public static <T> java.util.concurrent.Callable<T> privilegedCallableUsingCurrentClassLoader(java.util.concurrent.Callable<T>);
+    method public static java.util.concurrent.ThreadFactory privilegedThreadFactory();
+    method public static java.util.concurrent.ExecutorService unconfigurableExecutorService(java.util.concurrent.ExecutorService);
+    method public static java.util.concurrent.ScheduledExecutorService unconfigurableScheduledExecutorService(java.util.concurrent.ScheduledExecutorService);
+  }
+
+  public final class Flow {
+    method public static int defaultBufferSize();
+  }
+
+  public static interface Flow.Processor<T, R> extends java.util.concurrent.Flow.Subscriber<T> java.util.concurrent.Flow.Publisher<R> {
+  }
+
+  @java.lang.FunctionalInterface public static interface Flow.Publisher<T> {
+    method public void subscribe(java.util.concurrent.Flow.Subscriber<? super T>);
+  }
+
+  public static interface Flow.Subscriber<T> {
+    method public void onComplete();
+    method public void onError(Throwable);
+    method public void onNext(T);
+    method public void onSubscribe(java.util.concurrent.Flow.Subscription);
+  }
+
+  public static interface Flow.Subscription {
+    method public void cancel();
+    method public void request(long);
+  }
+
+  public class ForkJoinPool extends java.util.concurrent.AbstractExecutorService {
+    ctor public ForkJoinPool();
+    ctor public ForkJoinPool(int);
+    ctor public ForkJoinPool(int, java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory, java.lang.Thread.UncaughtExceptionHandler, boolean);
+    method public boolean awaitQuiescence(long, java.util.concurrent.TimeUnit);
+    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public static java.util.concurrent.ForkJoinPool commonPool();
+    method protected int drainTasksTo(java.util.Collection<? super java.util.concurrent.ForkJoinTask<?>>);
+    method public void execute(java.util.concurrent.ForkJoinTask<?>);
+    method public void execute(Runnable);
+    method public int getActiveThreadCount();
+    method public boolean getAsyncMode();
+    method public static int getCommonPoolParallelism();
+    method public java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory getFactory();
+    method public int getParallelism();
+    method public int getPoolSize();
+    method public int getQueuedSubmissionCount();
+    method public long getQueuedTaskCount();
+    method public int getRunningThreadCount();
+    method public long getStealCount();
+    method public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler();
+    method public boolean hasQueuedSubmissions();
+    method public <T> T invoke(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.List<java.util.concurrent.Future<T>> invokeAll(java.util.Collection<? extends java.util.concurrent.Callable<T>>);
+    method public boolean isQuiescent();
+    method public boolean isShutdown();
+    method public boolean isTerminated();
+    method public boolean isTerminating();
+    method public static void managedBlock(java.util.concurrent.ForkJoinPool.ManagedBlocker) throws java.lang.InterruptedException;
+    method protected java.util.concurrent.ForkJoinTask<?> pollSubmission();
+    method public void shutdown();
+    method public java.util.List<java.lang.Runnable> shutdownNow();
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.ForkJoinTask<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(java.util.concurrent.Callable<T>);
+    method public <T> java.util.concurrent.ForkJoinTask<T> submit(Runnable, T);
+    method public java.util.concurrent.ForkJoinTask<?> submit(Runnable);
+    field public static final java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory defaultForkJoinWorkerThreadFactory;
+  }
+
+  public static interface ForkJoinPool.ForkJoinWorkerThreadFactory {
+    method public java.util.concurrent.ForkJoinWorkerThread newThread(java.util.concurrent.ForkJoinPool);
+  }
+
+  public static interface ForkJoinPool.ManagedBlocker {
+    method public boolean block() throws java.lang.InterruptedException;
+    method public boolean isReleasable();
+  }
+
+  public abstract class ForkJoinTask<V> implements java.util.concurrent.Future<V> java.io.Serializable {
+    ctor public ForkJoinTask();
+    method public static java.util.concurrent.ForkJoinTask<?> adapt(Runnable);
+    method public static <T> java.util.concurrent.ForkJoinTask<T> adapt(Runnable, T);
+    method public static <T> java.util.concurrent.ForkJoinTask<T> adapt(java.util.concurrent.Callable<? extends T>);
+    method public boolean cancel(boolean);
+    method public final boolean compareAndSetForkJoinTaskTag(short, short);
+    method public void complete(V);
+    method public void completeExceptionally(Throwable);
+    method protected abstract boolean exec();
+    method public final java.util.concurrent.ForkJoinTask<V> fork();
+    method public final V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public final V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public final Throwable getException();
+    method public final short getForkJoinTaskTag();
+    method public static java.util.concurrent.ForkJoinPool getPool();
+    method public static int getQueuedTaskCount();
+    method public abstract V getRawResult();
+    method public static int getSurplusQueuedTaskCount();
+    method public static void helpQuiesce();
+    method public static boolean inForkJoinPool();
+    method public final V invoke();
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>, java.util.concurrent.ForkJoinTask<?>);
+    method public static void invokeAll(java.util.concurrent.ForkJoinTask<?>...);
+    method public static <T extends java.util.concurrent.ForkJoinTask<?>> java.util.Collection<T> invokeAll(java.util.Collection<T>);
+    method public final boolean isCancelled();
+    method public final boolean isCompletedAbnormally();
+    method public final boolean isCompletedNormally();
+    method public final boolean isDone();
+    method public final V join();
+    method protected static java.util.concurrent.ForkJoinTask<?> peekNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollNextLocalTask();
+    method protected static java.util.concurrent.ForkJoinTask<?> pollTask();
+    method public final void quietlyComplete();
+    method public final void quietlyInvoke();
+    method public final void quietlyJoin();
+    method public void reinitialize();
+    method public final short setForkJoinTaskTag(short);
+    method protected abstract void setRawResult(V);
+    method public boolean tryUnfork();
+  }
+
+  public class ForkJoinWorkerThread extends java.lang.Thread {
+    ctor protected ForkJoinWorkerThread(java.util.concurrent.ForkJoinPool);
+    method public java.util.concurrent.ForkJoinPool getPool();
+    method public int getPoolIndex();
+    method protected void onStart();
+    method protected void onTermination(Throwable);
+  }
+
+  public interface Future<V> {
+    method public boolean cancel(boolean);
+    method public V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public boolean isCancelled();
+    method public boolean isDone();
+  }
+
+  public class FutureTask<V> implements java.util.concurrent.RunnableFuture<V> {
+    ctor public FutureTask(java.util.concurrent.Callable<V>);
+    ctor public FutureTask(Runnable, V);
+    method public boolean cancel(boolean);
+    method protected void done();
+    method public V get() throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
+    method public V get(long, java.util.concurrent.TimeUnit) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public boolean isCancelled();
+    method public boolean isDone();
+    method public void run();
+    method protected boolean runAndReset();
+    method protected void set(V);
+    method protected void setException(Throwable);
+  }
+
+  public class LinkedBlockingDeque<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingDeque<E> java.io.Serializable {
+    ctor public LinkedBlockingDeque();
+    ctor public LinkedBlockingDeque(int);
+    ctor public LinkedBlockingDeque(java.util.Collection<? extends E>);
+    method public void addFirst(E);
+    method public void addLast(E);
+    method public java.util.Iterator<E> descendingIterator();
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public E getFirst();
+    method public E getLast();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean offerFirst(E);
+    method public boolean offerFirst(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean offerLast(E);
+    method public boolean offerLast(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E peek();
+    method public E peekFirst();
+    method public E peekLast();
+    method public E poll();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E pollFirst();
+    method public E pollFirst(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E pollLast();
+    method public E pollLast(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E pop();
+    method public void push(E);
+    method public void put(E) throws java.lang.InterruptedException;
+    method public void putFirst(E) throws java.lang.InterruptedException;
+    method public void putLast(E) throws java.lang.InterruptedException;
+    method public int remainingCapacity();
+    method public E removeFirst();
+    method public boolean removeFirstOccurrence(Object);
+    method public E removeLast();
+    method public boolean removeLastOccurrence(Object);
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+    method public E takeFirst() throws java.lang.InterruptedException;
+    method public E takeLast() throws java.lang.InterruptedException;
+  }
+
+  public class LinkedBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
+    ctor public LinkedBlockingQueue();
+    ctor public LinkedBlockingQueue(int);
+    ctor public LinkedBlockingQueue(java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll();
+    method public void put(E) throws java.lang.InterruptedException;
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public class LinkedTransferQueue<E> extends java.util.AbstractQueue<E> implements java.io.Serializable java.util.concurrent.TransferQueue<E> {
+    ctor public LinkedTransferQueue();
+    ctor public LinkedTransferQueue(java.util.Collection<? extends E>);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public int getWaitingConsumerCount();
+    method public boolean hasWaitingConsumer();
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll();
+    method public void put(E);
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+    method public void transfer(E) throws java.lang.InterruptedException;
+    method public boolean tryTransfer(E);
+    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+  public class Phaser {
+    ctor public Phaser();
+    ctor public Phaser(int);
+    ctor public Phaser(java.util.concurrent.Phaser);
+    ctor public Phaser(java.util.concurrent.Phaser, int);
+    method public int arrive();
+    method public int arriveAndAwaitAdvance();
+    method public int arriveAndDeregister();
+    method public int awaitAdvance(int);
+    method public int awaitAdvanceInterruptibly(int) throws java.lang.InterruptedException;
+    method public int awaitAdvanceInterruptibly(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException, java.util.concurrent.TimeoutException;
+    method public int bulkRegister(int);
+    method public void forceTermination();
+    method public int getArrivedParties();
+    method public java.util.concurrent.Phaser getParent();
+    method public final int getPhase();
+    method public int getRegisteredParties();
+    method public java.util.concurrent.Phaser getRoot();
+    method public int getUnarrivedParties();
+    method public boolean isTerminated();
+    method protected boolean onAdvance(int, int);
+    method public int register();
+  }
+
+  public class PriorityBlockingQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
+    ctor public PriorityBlockingQueue();
+    ctor public PriorityBlockingQueue(int);
+    ctor public PriorityBlockingQueue(int, java.util.Comparator<? super E>);
+    ctor public PriorityBlockingQueue(java.util.Collection<? extends E>);
+    method public java.util.Comparator<? super E> comparator();
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E);
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit);
+    method public E peek();
+    method public E poll();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void put(E);
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public abstract class RecursiveAction extends java.util.concurrent.ForkJoinTask<java.lang.Void> {
+    ctor public RecursiveAction();
+    method protected abstract void compute();
+    method protected final boolean exec();
+    method public final Void getRawResult();
+    method protected final void setRawResult(Void);
+  }
+
+  public abstract class RecursiveTask<V> extends java.util.concurrent.ForkJoinTask<V> {
+    ctor public RecursiveTask();
+    method protected abstract V compute();
+    method protected final boolean exec();
+    method public final V getRawResult();
+    method protected final void setRawResult(V);
+  }
+
+  public class RejectedExecutionException extends java.lang.RuntimeException {
+    ctor public RejectedExecutionException();
+    ctor public RejectedExecutionException(String);
+    ctor public RejectedExecutionException(String, Throwable);
+    ctor public RejectedExecutionException(Throwable);
+  }
+
+  public interface RejectedExecutionHandler {
+    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
+  }
+
+  public interface RunnableFuture<V> extends java.lang.Runnable java.util.concurrent.Future<V> {
+  }
+
+  public interface RunnableScheduledFuture<V> extends java.util.concurrent.RunnableFuture<V> java.util.concurrent.ScheduledFuture<V> {
+    method public boolean isPeriodic();
+  }
+
+  public interface ScheduledExecutorService extends java.util.concurrent.ExecutorService {
+    method public java.util.concurrent.ScheduledFuture<?> schedule(Runnable, long, java.util.concurrent.TimeUnit);
+    method public <V> java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(Runnable, long, long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(Runnable, long, long, java.util.concurrent.TimeUnit);
+  }
+
+  public interface ScheduledFuture<V> extends java.util.concurrent.Delayed java.util.concurrent.Future<V> {
+  }
+
+  public class ScheduledThreadPoolExecutor extends java.util.concurrent.ThreadPoolExecutor implements java.util.concurrent.ScheduledExecutorService {
+    ctor public ScheduledThreadPoolExecutor(int);
+    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.ThreadFactory);
+    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.RejectedExecutionHandler);
+    ctor public ScheduledThreadPoolExecutor(int, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler);
+    method protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(Runnable, java.util.concurrent.RunnableScheduledFuture<V>);
+    method protected <V> java.util.concurrent.RunnableScheduledFuture<V> decorateTask(java.util.concurrent.Callable<V>, java.util.concurrent.RunnableScheduledFuture<V>);
+    method public boolean getContinueExistingPeriodicTasksAfterShutdownPolicy();
+    method public boolean getExecuteExistingDelayedTasksAfterShutdownPolicy();
+    method public boolean getRemoveOnCancelPolicy();
+    method public java.util.concurrent.ScheduledFuture<?> schedule(Runnable, long, java.util.concurrent.TimeUnit);
+    method public <V> java.util.concurrent.ScheduledFuture<V> schedule(java.util.concurrent.Callable<V>, long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.ScheduledFuture<?> scheduleAtFixedRate(Runnable, long, long, java.util.concurrent.TimeUnit);
+    method public java.util.concurrent.ScheduledFuture<?> scheduleWithFixedDelay(Runnable, long, long, java.util.concurrent.TimeUnit);
+    method public void setContinueExistingPeriodicTasksAfterShutdownPolicy(boolean);
+    method public void setExecuteExistingDelayedTasksAfterShutdownPolicy(boolean);
+    method public void setRemoveOnCancelPolicy(boolean);
+  }
+
+  public class Semaphore implements java.io.Serializable {
+    ctor public Semaphore(int);
+    ctor public Semaphore(int, boolean);
+    method public void acquire() throws java.lang.InterruptedException;
+    method public void acquire(int) throws java.lang.InterruptedException;
+    method public void acquireUninterruptibly();
+    method public void acquireUninterruptibly(int);
+    method public int availablePermits();
+    method public int drainPermits();
+    method public final int getQueueLength();
+    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
+    method public final boolean hasQueuedThreads();
+    method public boolean isFair();
+    method protected void reducePermits(int);
+    method public void release();
+    method public void release(int);
+    method public boolean tryAcquire();
+    method public boolean tryAcquire(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean tryAcquire(int);
+    method public boolean tryAcquire(int, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+  public class SynchronousQueue<E> extends java.util.AbstractQueue<E> implements java.util.concurrent.BlockingQueue<E> java.io.Serializable {
+    ctor public SynchronousQueue();
+    ctor public SynchronousQueue(boolean);
+    method public int drainTo(java.util.Collection<? super E>);
+    method public int drainTo(java.util.Collection<? super E>, int);
+    method public java.util.Iterator<E> iterator();
+    method public boolean offer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean offer(E);
+    method public E peek();
+    method public E poll(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public E poll();
+    method public void put(E) throws java.lang.InterruptedException;
+    method public int remainingCapacity();
+    method public int size();
+    method public E take() throws java.lang.InterruptedException;
+  }
+
+  public interface ThreadFactory {
+    method public Thread newThread(Runnable);
+  }
+
+  public class ThreadLocalRandom extends java.util.Random {
+    method public static java.util.concurrent.ThreadLocalRandom current();
+    method public double nextDouble(double);
+    method public double nextDouble(double, double);
+    method public int nextInt(int, int);
+    method public long nextLong(long);
+    method public long nextLong(long, long);
+  }
+
+  public class ThreadPoolExecutor extends java.util.concurrent.AbstractExecutorService {
+    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>);
+    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory);
+    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.RejectedExecutionHandler);
+    ctor public ThreadPoolExecutor(int, int, long, java.util.concurrent.TimeUnit, java.util.concurrent.BlockingQueue<java.lang.Runnable>, java.util.concurrent.ThreadFactory, java.util.concurrent.RejectedExecutionHandler);
+    method protected void afterExecute(Runnable, Throwable);
+    method public void allowCoreThreadTimeOut(boolean);
+    method public boolean allowsCoreThreadTimeOut();
+    method public boolean awaitTermination(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method protected void beforeExecute(Thread, Runnable);
+    method public void execute(Runnable);
+    method protected void finalize();
+    method public int getActiveCount();
+    method public long getCompletedTaskCount();
+    method public int getCorePoolSize();
+    method public long getKeepAliveTime(java.util.concurrent.TimeUnit);
+    method public int getLargestPoolSize();
+    method public int getMaximumPoolSize();
+    method public int getPoolSize();
+    method public java.util.concurrent.BlockingQueue<java.lang.Runnable> getQueue();
+    method public java.util.concurrent.RejectedExecutionHandler getRejectedExecutionHandler();
+    method public long getTaskCount();
+    method public java.util.concurrent.ThreadFactory getThreadFactory();
+    method public boolean isShutdown();
+    method public boolean isTerminated();
+    method public boolean isTerminating();
+    method public int prestartAllCoreThreads();
+    method public boolean prestartCoreThread();
+    method public void purge();
+    method public boolean remove(Runnable);
+    method public void setCorePoolSize(int);
+    method public void setKeepAliveTime(long, java.util.concurrent.TimeUnit);
+    method public void setMaximumPoolSize(int);
+    method public void setRejectedExecutionHandler(java.util.concurrent.RejectedExecutionHandler);
+    method public void setThreadFactory(java.util.concurrent.ThreadFactory);
+    method public void shutdown();
+    method public java.util.List<java.lang.Runnable> shutdownNow();
+    method protected void terminated();
+  }
+
+  public static class ThreadPoolExecutor.AbortPolicy implements java.util.concurrent.RejectedExecutionHandler {
+    ctor public ThreadPoolExecutor.AbortPolicy();
+    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
+  }
+
+  public static class ThreadPoolExecutor.CallerRunsPolicy implements java.util.concurrent.RejectedExecutionHandler {
+    ctor public ThreadPoolExecutor.CallerRunsPolicy();
+    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
+  }
+
+  public static class ThreadPoolExecutor.DiscardOldestPolicy implements java.util.concurrent.RejectedExecutionHandler {
+    ctor public ThreadPoolExecutor.DiscardOldestPolicy();
+    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
+  }
+
+  public static class ThreadPoolExecutor.DiscardPolicy implements java.util.concurrent.RejectedExecutionHandler {
+    ctor public ThreadPoolExecutor.DiscardPolicy();
+    method public void rejectedExecution(Runnable, java.util.concurrent.ThreadPoolExecutor);
+  }
+
+  public enum TimeUnit {
+    method public long convert(long, java.util.concurrent.TimeUnit);
+    method public void sleep(long) throws java.lang.InterruptedException;
+    method public void timedJoin(Thread, long) throws java.lang.InterruptedException;
+    method public void timedWait(Object, long) throws java.lang.InterruptedException;
+    method public long toDays(long);
+    method public long toHours(long);
+    method public long toMicros(long);
+    method public long toMillis(long);
+    method public long toMinutes(long);
+    method public long toNanos(long);
+    method public long toSeconds(long);
+    enum_constant public static final java.util.concurrent.TimeUnit DAYS;
+    enum_constant public static final java.util.concurrent.TimeUnit HOURS;
+    enum_constant public static final java.util.concurrent.TimeUnit MICROSECONDS;
+    enum_constant public static final java.util.concurrent.TimeUnit MILLISECONDS;
+    enum_constant public static final java.util.concurrent.TimeUnit MINUTES;
+    enum_constant public static final java.util.concurrent.TimeUnit NANOSECONDS;
+    enum_constant public static final java.util.concurrent.TimeUnit SECONDS;
+  }
+
+  public class TimeoutException extends java.lang.Exception {
+    ctor public TimeoutException();
+    ctor public TimeoutException(String);
+  }
+
+  public interface TransferQueue<E> extends java.util.concurrent.BlockingQueue<E> {
+    method public int getWaitingConsumerCount();
+    method public boolean hasWaitingConsumer();
+    method public void transfer(E) throws java.lang.InterruptedException;
+    method public boolean tryTransfer(E);
+    method public boolean tryTransfer(E, long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+  }
+
+}
+
+package java.util.concurrent.atomic {
+
+  public class AtomicBoolean implements java.io.Serializable {
+    ctor public AtomicBoolean(boolean);
+    ctor public AtomicBoolean();
+    method public final boolean compareAndSet(boolean, boolean);
+    method public final boolean get();
+    method public final boolean getAndSet(boolean);
+    method public final void lazySet(boolean);
+    method public final void set(boolean);
+    method public boolean weakCompareAndSet(boolean, boolean);
+  }
+
+  public class AtomicInteger extends java.lang.Number implements java.io.Serializable {
+    ctor public AtomicInteger(int);
+    ctor public AtomicInteger();
+    method public final int accumulateAndGet(int, java.util.function.IntBinaryOperator);
+    method public final int addAndGet(int);
+    method public final boolean compareAndSet(int, int);
+    method public final int decrementAndGet();
+    method public double doubleValue();
+    method public float floatValue();
+    method public final int get();
+    method public final int getAndAccumulate(int, java.util.function.IntBinaryOperator);
+    method public final int getAndAdd(int);
+    method public final int getAndDecrement();
+    method public final int getAndIncrement();
+    method public final int getAndSet(int);
+    method public final int getAndUpdate(java.util.function.IntUnaryOperator);
+    method public final int incrementAndGet();
+    method public int intValue();
+    method public final void lazySet(int);
+    method public long longValue();
+    method public final void set(int);
+    method public final int updateAndGet(java.util.function.IntUnaryOperator);
+    method public final boolean weakCompareAndSet(int, int);
+  }
+
+  public class AtomicIntegerArray implements java.io.Serializable {
+    ctor public AtomicIntegerArray(int);
+    ctor public AtomicIntegerArray(int[]);
+    method public final int accumulateAndGet(int, int, java.util.function.IntBinaryOperator);
+    method public final int addAndGet(int, int);
+    method public final boolean compareAndSet(int, int, int);
+    method public final int decrementAndGet(int);
+    method public final int get(int);
+    method public final int getAndAccumulate(int, int, java.util.function.IntBinaryOperator);
+    method public final int getAndAdd(int, int);
+    method public final int getAndDecrement(int);
+    method public final int getAndIncrement(int);
+    method public final int getAndSet(int, int);
+    method public final int getAndUpdate(int, java.util.function.IntUnaryOperator);
+    method public final int incrementAndGet(int);
+    method public final void lazySet(int, int);
+    method public final int length();
+    method public final void set(int, int);
+    method public final int updateAndGet(int, java.util.function.IntUnaryOperator);
+    method public final boolean weakCompareAndSet(int, int, int);
+  }
+
+  public abstract class AtomicIntegerFieldUpdater<T> {
+    ctor protected AtomicIntegerFieldUpdater();
+    method public final int accumulateAndGet(T, int, java.util.function.IntBinaryOperator);
+    method public int addAndGet(T, int);
+    method public abstract boolean compareAndSet(T, int, int);
+    method public int decrementAndGet(T);
+    method public abstract int get(T);
+    method public final int getAndAccumulate(T, int, java.util.function.IntBinaryOperator);
+    method public int getAndAdd(T, int);
+    method public int getAndDecrement(T);
+    method public int getAndIncrement(T);
+    method public int getAndSet(T, int);
+    method public final int getAndUpdate(T, java.util.function.IntUnaryOperator);
+    method public int incrementAndGet(T);
+    method public abstract void lazySet(T, int);
+    method public static <U> java.util.concurrent.atomic.AtomicIntegerFieldUpdater<U> newUpdater(Class<U>, String);
+    method public abstract void set(T, int);
+    method public final int updateAndGet(T, java.util.function.IntUnaryOperator);
+    method public abstract boolean weakCompareAndSet(T, int, int);
+  }
+
+  public class AtomicLong extends java.lang.Number implements java.io.Serializable {
+    ctor public AtomicLong(long);
+    ctor public AtomicLong();
+    method public final long accumulateAndGet(long, java.util.function.LongBinaryOperator);
+    method public final long addAndGet(long);
+    method public final boolean compareAndSet(long, long);
+    method public final long decrementAndGet();
+    method public double doubleValue();
+    method public float floatValue();
+    method public final long get();
+    method public final long getAndAccumulate(long, java.util.function.LongBinaryOperator);
+    method public final long getAndAdd(long);
+    method public final long getAndDecrement();
+    method public final long getAndIncrement();
+    method public final long getAndSet(long);
+    method public final long getAndUpdate(java.util.function.LongUnaryOperator);
+    method public final long incrementAndGet();
+    method public int intValue();
+    method public final void lazySet(long);
+    method public long longValue();
+    method public final void set(long);
+    method public final long updateAndGet(java.util.function.LongUnaryOperator);
+    method public final boolean weakCompareAndSet(long, long);
+  }
+
+  public class AtomicLongArray implements java.io.Serializable {
+    ctor public AtomicLongArray(int);
+    ctor public AtomicLongArray(long[]);
+    method public final long accumulateAndGet(int, long, java.util.function.LongBinaryOperator);
+    method public long addAndGet(int, long);
+    method public final boolean compareAndSet(int, long, long);
+    method public final long decrementAndGet(int);
+    method public final long get(int);
+    method public final long getAndAccumulate(int, long, java.util.function.LongBinaryOperator);
+    method public final long getAndAdd(int, long);
+    method public final long getAndDecrement(int);
+    method public final long getAndIncrement(int);
+    method public final long getAndSet(int, long);
+    method public final long getAndUpdate(int, java.util.function.LongUnaryOperator);
+    method public final long incrementAndGet(int);
+    method public final void lazySet(int, long);
+    method public final int length();
+    method public final void set(int, long);
+    method public final long updateAndGet(int, java.util.function.LongUnaryOperator);
+    method public final boolean weakCompareAndSet(int, long, long);
+  }
+
+  public abstract class AtomicLongFieldUpdater<T> {
+    ctor protected AtomicLongFieldUpdater();
+    method public final long accumulateAndGet(T, long, java.util.function.LongBinaryOperator);
+    method public long addAndGet(T, long);
+    method public abstract boolean compareAndSet(T, long, long);
+    method public long decrementAndGet(T);
+    method public abstract long get(T);
+    method public final long getAndAccumulate(T, long, java.util.function.LongBinaryOperator);
+    method public long getAndAdd(T, long);
+    method public long getAndDecrement(T);
+    method public long getAndIncrement(T);
+    method public long getAndSet(T, long);
+    method public final long getAndUpdate(T, java.util.function.LongUnaryOperator);
+    method public long incrementAndGet(T);
+    method public abstract void lazySet(T, long);
+    method public static <U> java.util.concurrent.atomic.AtomicLongFieldUpdater<U> newUpdater(Class<U>, String);
+    method public abstract void set(T, long);
+    method public final long updateAndGet(T, java.util.function.LongUnaryOperator);
+    method public abstract boolean weakCompareAndSet(T, long, long);
+  }
+
+  public class AtomicMarkableReference<V> {
+    ctor public AtomicMarkableReference(V, boolean);
+    method public boolean attemptMark(V, boolean);
+    method public boolean compareAndSet(V, V, boolean, boolean);
+    method public V get(boolean[]);
+    method public V getReference();
+    method public boolean isMarked();
+    method public void set(V, boolean);
+    method public boolean weakCompareAndSet(V, V, boolean, boolean);
+  }
+
+  public class AtomicReference<V> implements java.io.Serializable {
+    ctor public AtomicReference(V);
+    ctor public AtomicReference();
+    method public final V accumulateAndGet(V, java.util.function.BinaryOperator<V>);
+    method public final boolean compareAndSet(V, V);
+    method public final V get();
+    method public final V getAndAccumulate(V, java.util.function.BinaryOperator<V>);
+    method public final V getAndSet(V);
+    method public final V getAndUpdate(java.util.function.UnaryOperator<V>);
+    method public final void lazySet(V);
+    method public final void set(V);
+    method public final V updateAndGet(java.util.function.UnaryOperator<V>);
+    method public final boolean weakCompareAndSet(V, V);
+  }
+
+  public class AtomicReferenceArray<E> implements java.io.Serializable {
+    ctor public AtomicReferenceArray(int);
+    ctor public AtomicReferenceArray(E[]);
+    method public final E accumulateAndGet(int, E, java.util.function.BinaryOperator<E>);
+    method public final boolean compareAndSet(int, E, E);
+    method public final E get(int);
+    method public final E getAndAccumulate(int, E, java.util.function.BinaryOperator<E>);
+    method public final E getAndSet(int, E);
+    method public final E getAndUpdate(int, java.util.function.UnaryOperator<E>);
+    method public final void lazySet(int, E);
+    method public final int length();
+    method public final void set(int, E);
+    method public final E updateAndGet(int, java.util.function.UnaryOperator<E>);
+    method public final boolean weakCompareAndSet(int, E, E);
+  }
+
+  public abstract class AtomicReferenceFieldUpdater<T, V> {
+    ctor protected AtomicReferenceFieldUpdater();
+    method public final V accumulateAndGet(T, V, java.util.function.BinaryOperator<V>);
+    method public abstract boolean compareAndSet(T, V, V);
+    method public abstract V get(T);
+    method public final V getAndAccumulate(T, V, java.util.function.BinaryOperator<V>);
+    method public V getAndSet(T, V);
+    method public final V getAndUpdate(T, java.util.function.UnaryOperator<V>);
+    method public abstract void lazySet(T, V);
+    method public static <U, W> java.util.concurrent.atomic.AtomicReferenceFieldUpdater<U,W> newUpdater(Class<U>, Class<W>, String);
+    method public abstract void set(T, V);
+    method public final V updateAndGet(T, java.util.function.UnaryOperator<V>);
+    method public abstract boolean weakCompareAndSet(T, V, V);
+  }
+
+  public class AtomicStampedReference<V> {
+    ctor public AtomicStampedReference(V, int);
+    method public boolean attemptStamp(V, int);
+    method public boolean compareAndSet(V, V, int, int);
+    method public V get(int[]);
+    method public V getReference();
+    method public int getStamp();
+    method public void set(V, int);
+    method public boolean weakCompareAndSet(V, V, int, int);
+  }
+
+  public class DoubleAccumulator extends java.lang.Number implements java.io.Serializable {
+    ctor public DoubleAccumulator(java.util.function.DoubleBinaryOperator, double);
+    method public void accumulate(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public double get();
+    method public double getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class DoubleAdder extends java.lang.Number implements java.io.Serializable {
+    ctor public DoubleAdder();
+    method public void add(double);
+    method public double doubleValue();
+    method public float floatValue();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public double sum();
+    method public double sumThenReset();
+  }
+
+  public class LongAccumulator extends java.lang.Number implements java.io.Serializable {
+    ctor public LongAccumulator(java.util.function.LongBinaryOperator, long);
+    method public void accumulate(long);
+    method public double doubleValue();
+    method public float floatValue();
+    method public long get();
+    method public long getThenReset();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+  }
+
+  public class LongAdder extends java.lang.Number implements java.io.Serializable {
+    ctor public LongAdder();
+    method public void add(long);
+    method public void decrement();
+    method public double doubleValue();
+    method public float floatValue();
+    method public void increment();
+    method public int intValue();
+    method public long longValue();
+    method public void reset();
+    method public long sum();
+    method public long sumThenReset();
+  }
+
+}
+
+package java.util.concurrent.locks {
+
+  public abstract class AbstractOwnableSynchronizer implements java.io.Serializable {
+    ctor protected AbstractOwnableSynchronizer();
+    method protected final Thread getExclusiveOwnerThread();
+    method protected final void setExclusiveOwnerThread(Thread);
+  }
+
+  public abstract class AbstractQueuedLongSynchronizer extends java.util.concurrent.locks.AbstractOwnableSynchronizer implements java.io.Serializable {
+    ctor protected AbstractQueuedLongSynchronizer();
+    method public final void acquire(long);
+    method public final void acquireInterruptibly(long) throws java.lang.InterruptedException;
+    method public final void acquireShared(long);
+    method public final void acquireSharedInterruptibly(long) throws java.lang.InterruptedException;
+    method protected final boolean compareAndSetState(long, long);
+    method public final java.util.Collection<java.lang.Thread> getExclusiveQueuedThreads();
+    method public final Thread getFirstQueuedThread();
+    method public final int getQueueLength();
+    method public final java.util.Collection<java.lang.Thread> getQueuedThreads();
+    method public final java.util.Collection<java.lang.Thread> getSharedQueuedThreads();
+    method protected final long getState();
+    method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
+    method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
+    method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
+    method public final boolean hasQueuedThreads();
+    method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
+    method protected boolean isHeldExclusively();
+    method public final boolean isQueued(Thread);
+    method public final boolean owns(java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject);
+    method public final boolean release(long);
+    method public final boolean releaseShared(long);
+    method protected final void setState(long);
+    method protected boolean tryAcquire(long);
+    method public final boolean tryAcquireNanos(long, long) throws java.lang.InterruptedException;
+    method protected long tryAcquireShared(long);
+    method public final boolean tryAcquireSharedNanos(long, long) throws java.lang.InterruptedException;
+    method protected boolean tryRelease(long);
+    method protected boolean tryReleaseShared(long);
+  }
+
+  public class AbstractQueuedLongSynchronizer.ConditionObject implements java.util.concurrent.locks.Condition java.io.Serializable {
+    ctor public AbstractQueuedLongSynchronizer.ConditionObject();
+    method public final void await() throws java.lang.InterruptedException;
+    method public final boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public final long awaitNanos(long) throws java.lang.InterruptedException;
+    method public final void awaitUninterruptibly();
+    method public final boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
+    method protected final int getWaitQueueLength();
+    method protected final java.util.Collection<java.lang.Thread> getWaitingThreads();
+    method protected final boolean hasWaiters();
+    method public final void signal();
+    method public final void signalAll();
+  }
+
+  public abstract class AbstractQueuedSynchronizer extends java.util.concurrent.locks.AbstractOwnableSynchronizer implements java.io.Serializable {
+    ctor protected AbstractQueuedSynchronizer();
+    method public final void acquire(int);
+    method public final void acquireInterruptibly(int) throws java.lang.InterruptedException;
+    method public final void acquireShared(int);
+    method public final void acquireSharedInterruptibly(int) throws java.lang.InterruptedException;
+    method protected final boolean compareAndSetState(int, int);
+    method public final java.util.Collection<java.lang.Thread> getExclusiveQueuedThreads();
+    method public final Thread getFirstQueuedThread();
+    method public final int getQueueLength();
+    method public final java.util.Collection<java.lang.Thread> getQueuedThreads();
+    method public final java.util.Collection<java.lang.Thread> getSharedQueuedThreads();
+    method protected final int getState();
+    method public final int getWaitQueueLength(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
+    method public final java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
+    method public final boolean hasContended();
+    method public final boolean hasQueuedPredecessors();
+    method public final boolean hasQueuedThreads();
+    method public final boolean hasWaiters(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
+    method protected boolean isHeldExclusively();
+    method public final boolean isQueued(Thread);
+    method public final boolean owns(java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject);
+    method public final boolean release(int);
+    method public final boolean releaseShared(int);
+    method protected final void setState(int);
+    method protected boolean tryAcquire(int);
+    method public final boolean tryAcquireNanos(int, long) throws java.lang.InterruptedException;
+    method protected int tryAcquireShared(int);
+    method public final boolean tryAcquireSharedNanos(int, long) throws java.lang.InterruptedException;
+    method protected boolean tryRelease(int);
+    method protected boolean tryReleaseShared(int);
+  }
+
+  public class AbstractQueuedSynchronizer.ConditionObject implements java.util.concurrent.locks.Condition java.io.Serializable {
+    ctor public AbstractQueuedSynchronizer.ConditionObject();
+    method public final void await() throws java.lang.InterruptedException;
+    method public final boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public final long awaitNanos(long) throws java.lang.InterruptedException;
+    method public final void awaitUninterruptibly();
+    method public final boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
+    method protected final int getWaitQueueLength();
+    method protected final java.util.Collection<java.lang.Thread> getWaitingThreads();
+    method protected final boolean hasWaiters();
+    method public final void signal();
+    method public final void signalAll();
+  }
+
+  public interface Condition {
+    method public void await() throws java.lang.InterruptedException;
+    method public boolean await(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public long awaitNanos(long) throws java.lang.InterruptedException;
+    method public void awaitUninterruptibly();
+    method public boolean awaitUntil(java.util.Date) throws java.lang.InterruptedException;
+    method public void signal();
+    method public void signalAll();
+  }
+
+  public interface Lock {
+    method public void lock();
+    method public void lockInterruptibly() throws java.lang.InterruptedException;
+    method public java.util.concurrent.locks.Condition newCondition();
+    method public boolean tryLock();
+    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock();
+  }
+
+  public class LockSupport {
+    method public static Object getBlocker(Thread);
+    method public static void park(Object);
+    method public static void park();
+    method public static void parkNanos(Object, long);
+    method public static void parkNanos(long);
+    method public static void parkUntil(Object, long);
+    method public static void parkUntil(long);
+    method public static void unpark(Thread);
+  }
+
+  public interface ReadWriteLock {
+    method public java.util.concurrent.locks.Lock readLock();
+    method public java.util.concurrent.locks.Lock writeLock();
+  }
+
+  public class ReentrantLock implements java.util.concurrent.locks.Lock java.io.Serializable {
+    ctor public ReentrantLock();
+    ctor public ReentrantLock(boolean);
+    method public int getHoldCount();
+    method protected Thread getOwner();
+    method public final int getQueueLength();
+    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
+    method public int getWaitQueueLength(java.util.concurrent.locks.Condition);
+    method protected java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.Condition);
+    method public final boolean hasQueuedThread(Thread);
+    method public final boolean hasQueuedThreads();
+    method public boolean hasWaiters(java.util.concurrent.locks.Condition);
+    method public final boolean isFair();
+    method public boolean isHeldByCurrentThread();
+    method public boolean isLocked();
+    method public void lock();
+    method public void lockInterruptibly() throws java.lang.InterruptedException;
+    method public java.util.concurrent.locks.Condition newCondition();
+    method public boolean tryLock();
+    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock();
+  }
+
+  public class ReentrantReadWriteLock implements java.util.concurrent.locks.ReadWriteLock java.io.Serializable {
+    ctor public ReentrantReadWriteLock();
+    ctor public ReentrantReadWriteLock(boolean);
+    method protected Thread getOwner();
+    method public final int getQueueLength();
+    method protected java.util.Collection<java.lang.Thread> getQueuedReaderThreads();
+    method protected java.util.Collection<java.lang.Thread> getQueuedThreads();
+    method protected java.util.Collection<java.lang.Thread> getQueuedWriterThreads();
+    method public int getReadHoldCount();
+    method public int getReadLockCount();
+    method public int getWaitQueueLength(java.util.concurrent.locks.Condition);
+    method protected java.util.Collection<java.lang.Thread> getWaitingThreads(java.util.concurrent.locks.Condition);
+    method public int getWriteHoldCount();
+    method public final boolean hasQueuedThread(Thread);
+    method public final boolean hasQueuedThreads();
+    method public boolean hasWaiters(java.util.concurrent.locks.Condition);
+    method public final boolean isFair();
+    method public boolean isWriteLocked();
+    method public boolean isWriteLockedByCurrentThread();
+    method public java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock readLock();
+    method public java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock writeLock();
+  }
+
+  public static class ReentrantReadWriteLock.ReadLock implements java.util.concurrent.locks.Lock java.io.Serializable {
+    ctor protected ReentrantReadWriteLock.ReadLock(java.util.concurrent.locks.ReentrantReadWriteLock);
+    method public void lock();
+    method public void lockInterruptibly() throws java.lang.InterruptedException;
+    method public java.util.concurrent.locks.Condition newCondition();
+    method public boolean tryLock();
+    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock();
+  }
+
+  public static class ReentrantReadWriteLock.WriteLock implements java.util.concurrent.locks.Lock java.io.Serializable {
+    ctor protected ReentrantReadWriteLock.WriteLock(java.util.concurrent.locks.ReentrantReadWriteLock);
+    method public int getHoldCount();
+    method public boolean isHeldByCurrentThread();
+    method public void lock();
+    method public void lockInterruptibly() throws java.lang.InterruptedException;
+    method public java.util.concurrent.locks.Condition newCondition();
+    method public boolean tryLock();
+    method public boolean tryLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock();
+  }
+
+  public class StampedLock implements java.io.Serializable {
+    ctor public StampedLock();
+    method public java.util.concurrent.locks.Lock asReadLock();
+    method public java.util.concurrent.locks.ReadWriteLock asReadWriteLock();
+    method public java.util.concurrent.locks.Lock asWriteLock();
+    method public int getReadLockCount();
+    method public boolean isReadLocked();
+    method public boolean isWriteLocked();
+    method public long readLock();
+    method public long readLockInterruptibly() throws java.lang.InterruptedException;
+    method public long tryConvertToOptimisticRead(long);
+    method public long tryConvertToReadLock(long);
+    method public long tryConvertToWriteLock(long);
+    method public long tryOptimisticRead();
+    method public long tryReadLock();
+    method public long tryReadLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public boolean tryUnlockRead();
+    method public boolean tryUnlockWrite();
+    method public long tryWriteLock();
+    method public long tryWriteLock(long, java.util.concurrent.TimeUnit) throws java.lang.InterruptedException;
+    method public void unlock(long);
+    method public void unlockRead(long);
+    method public void unlockWrite(long);
+    method public boolean validate(long);
+    method public long writeLock();
+    method public long writeLockInterruptibly() throws java.lang.InterruptedException;
+  }
+
+}
+
+package java.util.function {
+
+  @java.lang.FunctionalInterface public interface BiConsumer<T, U> {
+    method public void accept(T, U);
+    method public default java.util.function.BiConsumer<T,U> andThen(java.util.function.BiConsumer<? super T,? super U>);
+  }
+
+  @java.lang.FunctionalInterface public interface BiFunction<T, U, R> {
+    method public default <V> java.util.function.BiFunction<T,U,V> andThen(java.util.function.Function<? super R,? extends V>);
+    method public R apply(T, U);
+  }
+
+  @java.lang.FunctionalInterface public interface BiPredicate<T, U> {
+    method public default java.util.function.BiPredicate<T,U> and(java.util.function.BiPredicate<? super T,? super U>);
+    method public default java.util.function.BiPredicate<T,U> negate();
+    method public default java.util.function.BiPredicate<T,U> or(java.util.function.BiPredicate<? super T,? super U>);
+    method public boolean test(T, U);
+  }
+
+  @java.lang.FunctionalInterface public interface BinaryOperator<T> extends java.util.function.BiFunction<T,T,T> {
+    method public static <T> java.util.function.BinaryOperator<T> maxBy(java.util.Comparator<? super T>);
+    method public static <T> java.util.function.BinaryOperator<T> minBy(java.util.Comparator<? super T>);
+  }
+
+  @java.lang.FunctionalInterface public interface BooleanSupplier {
+    method public boolean getAsBoolean();
+  }
+
+  @java.lang.FunctionalInterface public interface Consumer<T> {
+    method public void accept(T);
+    method public default java.util.function.Consumer<T> andThen(java.util.function.Consumer<? super T>);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleBinaryOperator {
+    method public double applyAsDouble(double, double);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleConsumer {
+    method public void accept(double);
+    method public default java.util.function.DoubleConsumer andThen(java.util.function.DoubleConsumer);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleFunction<R> {
+    method public R apply(double);
+  }
+
+  @java.lang.FunctionalInterface public interface DoublePredicate {
+    method public default java.util.function.DoublePredicate and(java.util.function.DoublePredicate);
+    method public default java.util.function.DoublePredicate negate();
+    method public default java.util.function.DoublePredicate or(java.util.function.DoublePredicate);
+    method public boolean test(double);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleSupplier {
+    method public double getAsDouble();
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleToIntFunction {
+    method public int applyAsInt(double);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleToLongFunction {
+    method public long applyAsLong(double);
+  }
+
+  @java.lang.FunctionalInterface public interface DoubleUnaryOperator {
+    method public default java.util.function.DoubleUnaryOperator andThen(java.util.function.DoubleUnaryOperator);
+    method public double applyAsDouble(double);
+    method public default java.util.function.DoubleUnaryOperator compose(java.util.function.DoubleUnaryOperator);
+    method public static java.util.function.DoubleUnaryOperator identity();
+  }
+
+  @java.lang.FunctionalInterface public interface Function<T, R> {
+    method public default <V> java.util.function.Function<T,V> andThen(java.util.function.Function<? super R,? extends V>);
+    method public R apply(T);
+    method public default <V> java.util.function.Function<V,R> compose(java.util.function.Function<? super V,? extends T>);
+    method public static <T> java.util.function.Function<T,T> identity();
+  }
+
+  @java.lang.FunctionalInterface public interface IntBinaryOperator {
+    method public int applyAsInt(int, int);
+  }
+
+  @java.lang.FunctionalInterface public interface IntConsumer {
+    method public void accept(int);
+    method public default java.util.function.IntConsumer andThen(java.util.function.IntConsumer);
+  }
+
+  @java.lang.FunctionalInterface public interface IntFunction<R> {
+    method public R apply(int);
+  }
+
+  @java.lang.FunctionalInterface public interface IntPredicate {
+    method public default java.util.function.IntPredicate and(java.util.function.IntPredicate);
+    method public default java.util.function.IntPredicate negate();
+    method public default java.util.function.IntPredicate or(java.util.function.IntPredicate);
+    method public boolean test(int);
+  }
+
+  @java.lang.FunctionalInterface public interface IntSupplier {
+    method public int getAsInt();
+  }
+
+  @java.lang.FunctionalInterface public interface IntToDoubleFunction {
+    method public double applyAsDouble(int);
+  }
+
+  @java.lang.FunctionalInterface public interface IntToLongFunction {
+    method public long applyAsLong(int);
+  }
+
+  @java.lang.FunctionalInterface public interface IntUnaryOperator {
+    method public default java.util.function.IntUnaryOperator andThen(java.util.function.IntUnaryOperator);
+    method public int applyAsInt(int);
+    method public default java.util.function.IntUnaryOperator compose(java.util.function.IntUnaryOperator);
+    method public static java.util.function.IntUnaryOperator identity();
+  }
+
+  @java.lang.FunctionalInterface public interface LongBinaryOperator {
+    method public long applyAsLong(long, long);
+  }
+
+  @java.lang.FunctionalInterface public interface LongConsumer {
+    method public void accept(long);
+    method public default java.util.function.LongConsumer andThen(java.util.function.LongConsumer);
+  }
+
+  @java.lang.FunctionalInterface public interface LongFunction<R> {
+    method public R apply(long);
+  }
+
+  @java.lang.FunctionalInterface public interface LongPredicate {
+    method public default java.util.function.LongPredicate and(java.util.function.LongPredicate);
+    method public default java.util.function.LongPredicate negate();
+    method public default java.util.function.LongPredicate or(java.util.function.LongPredicate);
+    method public boolean test(long);
+  }
+
+  @java.lang.FunctionalInterface public interface LongSupplier {
+    method public long getAsLong();
+  }
+
+  @java.lang.FunctionalInterface public interface LongToDoubleFunction {
+    method public double applyAsDouble(long);
+  }
+
+  @java.lang.FunctionalInterface public interface LongToIntFunction {
+    method public int applyAsInt(long);
+  }
+
+  @java.lang.FunctionalInterface public interface LongUnaryOperator {
+    method public default java.util.function.LongUnaryOperator andThen(java.util.function.LongUnaryOperator);
+    method public long applyAsLong(long);
+    method public default java.util.function.LongUnaryOperator compose(java.util.function.LongUnaryOperator);
+    method public static java.util.function.LongUnaryOperator identity();
+  }
+
+  @java.lang.FunctionalInterface public interface ObjDoubleConsumer<T> {
+    method public void accept(T, double);
+  }
+
+  @java.lang.FunctionalInterface public interface ObjIntConsumer<T> {
+    method public void accept(T, int);
+  }
+
+  @java.lang.FunctionalInterface public interface ObjLongConsumer<T> {
+    method public void accept(T, long);
+  }
+
+  @java.lang.FunctionalInterface public interface Predicate<T> {
+    method public default java.util.function.Predicate<T> and(java.util.function.Predicate<? super T>);
+    method public static <T> java.util.function.Predicate<T> isEqual(Object);
+    method public default java.util.function.Predicate<T> negate();
+    method public default java.util.function.Predicate<T> or(java.util.function.Predicate<? super T>);
+    method public boolean test(T);
+  }
+
+  @java.lang.FunctionalInterface public interface Supplier<T> {
+    method public T get();
+  }
+
+  @java.lang.FunctionalInterface public interface ToDoubleBiFunction<T, U> {
+    method public double applyAsDouble(T, U);
+  }
+
+  @java.lang.FunctionalInterface public interface ToDoubleFunction<T> {
+    method public double applyAsDouble(T);
+  }
+
+  @java.lang.FunctionalInterface public interface ToIntBiFunction<T, U> {
+    method public int applyAsInt(T, U);
+  }
+
+  @java.lang.FunctionalInterface public interface ToIntFunction<T> {
+    method public int applyAsInt(T);
+  }
+
+  @java.lang.FunctionalInterface public interface ToLongBiFunction<T, U> {
+    method public long applyAsLong(T, U);
+  }
+
+  @java.lang.FunctionalInterface public interface ToLongFunction<T> {
+    method public long applyAsLong(T);
+  }
+
+  @java.lang.FunctionalInterface public interface UnaryOperator<T> extends java.util.function.Function<T,T> {
+    method public static <T> java.util.function.UnaryOperator<T> identity();
+  }
+
+}
+
+package java.util.jar {
+
+  public class Attributes implements java.lang.Cloneable java.util.Map<java.lang.Object,java.lang.Object> {
+    ctor public Attributes();
+    ctor public Attributes(int);
+    ctor public Attributes(java.util.jar.Attributes);
+    method public void clear();
+    method public Object clone();
+    method public boolean containsKey(Object);
+    method public boolean containsValue(Object);
+    method public java.util.Set<java.util.Map.Entry<java.lang.Object,java.lang.Object>> entrySet();
+    method public Object get(Object);
+    method public String getValue(String);
+    method public String getValue(java.util.jar.Attributes.Name);
+    method public boolean isEmpty();
+    method public java.util.Set<java.lang.Object> keySet();
+    method public Object put(Object, Object);
+    method public void putAll(java.util.Map<?,?>);
+    method public String putValue(String, String);
+    method public Object remove(Object);
+    method public int size();
+    method public java.util.Collection<java.lang.Object> values();
+    field protected java.util.Map<java.lang.Object,java.lang.Object> map;
+  }
+
+  public static class Attributes.Name {
+    ctor public Attributes.Name(String);
+    field public static final java.util.jar.Attributes.Name CLASS_PATH;
+    field public static final java.util.jar.Attributes.Name CONTENT_TYPE;
+    field @Deprecated public static final java.util.jar.Attributes.Name EXTENSION_INSTALLATION;
+    field public static final java.util.jar.Attributes.Name EXTENSION_LIST;
+    field public static final java.util.jar.Attributes.Name EXTENSION_NAME;
+    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_TITLE;
+    field @Deprecated public static final java.util.jar.Attributes.Name IMPLEMENTATION_URL;
+    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_VENDOR;
+    field @Deprecated public static final java.util.jar.Attributes.Name IMPLEMENTATION_VENDOR_ID;
+    field public static final java.util.jar.Attributes.Name IMPLEMENTATION_VERSION;
+    field public static final java.util.jar.Attributes.Name MAIN_CLASS;
+    field public static final java.util.jar.Attributes.Name MANIFEST_VERSION;
+    field public static final java.util.jar.Attributes.Name SEALED;
+    field public static final java.util.jar.Attributes.Name SIGNATURE_VERSION;
+    field public static final java.util.jar.Attributes.Name SPECIFICATION_TITLE;
+    field public static final java.util.jar.Attributes.Name SPECIFICATION_VENDOR;
+    field public static final java.util.jar.Attributes.Name SPECIFICATION_VERSION;
+  }
+
+  public class JarEntry extends java.util.zip.ZipEntry {
+    ctor public JarEntry(String);
+    ctor public JarEntry(java.util.zip.ZipEntry);
+    ctor public JarEntry(java.util.jar.JarEntry);
+    method public java.util.jar.Attributes getAttributes() throws java.io.IOException;
+    method public java.security.cert.Certificate[] getCertificates();
+    method public java.security.CodeSigner[] getCodeSigners();
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+  }
+
+  public class JarException extends java.util.zip.ZipException {
+    ctor public JarException();
+    ctor public JarException(String);
+  }
+
+  public class JarFile extends java.util.zip.ZipFile {
+    ctor public JarFile(String) throws java.io.IOException;
+    ctor public JarFile(String, boolean) throws java.io.IOException;
+    ctor public JarFile(java.io.File) throws java.io.IOException;
+    ctor public JarFile(java.io.File, boolean) throws java.io.IOException;
+    ctor public JarFile(java.io.File, boolean, int) throws java.io.IOException;
+    method public java.util.Enumeration<java.util.jar.JarEntry> entries();
+    method public java.util.jar.JarEntry getJarEntry(String);
+    method public java.util.jar.Manifest getManifest() throws java.io.IOException;
+    method public java.util.stream.Stream<java.util.jar.JarEntry> stream();
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+    field public static final String MANIFEST_NAME = "META-INF/MANIFEST.MF";
+  }
+
+  public class JarInputStream extends java.util.zip.ZipInputStream {
+    ctor public JarInputStream(java.io.InputStream) throws java.io.IOException;
+    ctor public JarInputStream(java.io.InputStream, boolean) throws java.io.IOException;
+    method public java.util.jar.Manifest getManifest();
+    method public java.util.jar.JarEntry getNextJarEntry() throws java.io.IOException;
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+  }
+
+  public class JarOutputStream extends java.util.zip.ZipOutputStream {
+    ctor public JarOutputStream(java.io.OutputStream, java.util.jar.Manifest) throws java.io.IOException;
+    ctor public JarOutputStream(java.io.OutputStream) throws java.io.IOException;
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+  }
+
+  public class Manifest implements java.lang.Cloneable {
+    ctor public Manifest();
+    ctor public Manifest(java.io.InputStream) throws java.io.IOException;
+    ctor public Manifest(java.util.jar.Manifest);
+    method public void clear();
+    method public Object clone();
+    method public java.util.jar.Attributes getAttributes(String);
+    method public java.util.Map<java.lang.String,java.util.jar.Attributes> getEntries();
+    method public java.util.jar.Attributes getMainAttributes();
+    method public void read(java.io.InputStream) throws java.io.IOException;
+    method public void write(java.io.OutputStream) throws java.io.IOException;
+  }
+
+  public abstract class Pack200 {
+    method public static java.util.jar.Pack200.Packer newPacker();
+    method public static java.util.jar.Pack200.Unpacker newUnpacker();
+  }
+
+  public static interface Pack200.Packer {
+    method @Deprecated public default void addPropertyChangeListener(java.beans.PropertyChangeListener);
+    method public void pack(java.util.jar.JarFile, java.io.OutputStream) throws java.io.IOException;
+    method public void pack(java.util.jar.JarInputStream, java.io.OutputStream) throws java.io.IOException;
+    method public java.util.SortedMap<java.lang.String,java.lang.String> properties();
+    method @Deprecated public default void removePropertyChangeListener(java.beans.PropertyChangeListener);
+    field public static final String CLASS_ATTRIBUTE_PFX = "pack.class.attribute.";
+    field public static final String CODE_ATTRIBUTE_PFX = "pack.code.attribute.";
+    field public static final String DEFLATE_HINT = "pack.deflate.hint";
+    field public static final String EFFORT = "pack.effort";
+    field public static final String ERROR = "error";
+    field public static final String FALSE = "false";
+    field public static final String FIELD_ATTRIBUTE_PFX = "pack.field.attribute.";
+    field public static final String KEEP = "keep";
+    field public static final String KEEP_FILE_ORDER = "pack.keep.file.order";
+    field public static final String LATEST = "latest";
+    field public static final String METHOD_ATTRIBUTE_PFX = "pack.method.attribute.";
+    field public static final String MODIFICATION_TIME = "pack.modification.time";
+    field public static final String PASS = "pass";
+    field public static final String PASS_FILE_PFX = "pack.pass.file.";
+    field public static final String PROGRESS = "pack.progress";
+    field public static final String SEGMENT_LIMIT = "pack.segment.limit";
+    field public static final String STRIP = "strip";
+    field public static final String TRUE = "true";
+    field public static final String UNKNOWN_ATTRIBUTE = "pack.unknown.attribute";
+  }
+
+  public static interface Pack200.Unpacker {
+    method @Deprecated public default void addPropertyChangeListener(java.beans.PropertyChangeListener);
+    method public java.util.SortedMap<java.lang.String,java.lang.String> properties();
+    method @Deprecated public default void removePropertyChangeListener(java.beans.PropertyChangeListener);
+    method public void unpack(java.io.InputStream, java.util.jar.JarOutputStream) throws java.io.IOException;
+    method public void unpack(java.io.File, java.util.jar.JarOutputStream) throws java.io.IOException;
+    field public static final String DEFLATE_HINT = "unpack.deflate.hint";
+    field public static final String FALSE = "false";
+    field public static final String KEEP = "keep";
+    field public static final String PROGRESS = "unpack.progress";
+    field public static final String TRUE = "true";
+  }
+
+}
+
+package java.util.logging {
+
+  public class ConsoleHandler extends java.util.logging.StreamHandler {
+    ctor public ConsoleHandler();
+    method public void close();
+  }
+
+  public class ErrorManager {
+    ctor public ErrorManager();
+    method public void error(String, Exception, int);
+    field public static final int CLOSE_FAILURE = 3; // 0x3
+    field public static final int FLUSH_FAILURE = 2; // 0x2
+    field public static final int FORMAT_FAILURE = 5; // 0x5
+    field public static final int GENERIC_FAILURE = 0; // 0x0
+    field public static final int OPEN_FAILURE = 4; // 0x4
+    field public static final int WRITE_FAILURE = 1; // 0x1
+  }
+
+  public class FileHandler extends java.util.logging.StreamHandler {
+    ctor public FileHandler() throws java.io.IOException, java.lang.SecurityException;
+    ctor public FileHandler(String) throws java.io.IOException, java.lang.SecurityException;
+    ctor public FileHandler(String, boolean) throws java.io.IOException, java.lang.SecurityException;
+    ctor public FileHandler(String, int, int) throws java.io.IOException, java.lang.SecurityException;
+    ctor public FileHandler(String, int, int, boolean) throws java.io.IOException, java.lang.SecurityException;
+  }
+
+  @java.lang.FunctionalInterface public interface Filter {
+    method public boolean isLoggable(java.util.logging.LogRecord);
+  }
+
+  public abstract class Formatter {
+    ctor protected Formatter();
+    method public abstract String format(java.util.logging.LogRecord);
+    method public String formatMessage(java.util.logging.LogRecord);
+    method public String getHead(java.util.logging.Handler);
+    method public String getTail(java.util.logging.Handler);
+  }
+
+  public abstract class Handler {
+    ctor protected Handler();
+    method public abstract void close() throws java.lang.SecurityException;
+    method public abstract void flush();
+    method public String getEncoding();
+    method public java.util.logging.ErrorManager getErrorManager();
+    method public java.util.logging.Filter getFilter();
+    method public java.util.logging.Formatter getFormatter();
+    method public java.util.logging.Level getLevel();
+    method public boolean isLoggable(java.util.logging.LogRecord);
+    method public abstract void publish(java.util.logging.LogRecord);
+    method protected void reportError(String, Exception, int);
+    method public void setEncoding(String) throws java.lang.SecurityException, java.io.UnsupportedEncodingException;
+    method public void setErrorManager(java.util.logging.ErrorManager);
+    method public void setFilter(java.util.logging.Filter) throws java.lang.SecurityException;
+    method public void setFormatter(java.util.logging.Formatter) throws java.lang.SecurityException;
+    method public void setLevel(java.util.logging.Level) throws java.lang.SecurityException;
+  }
+
+  public class Level implements java.io.Serializable {
+    ctor protected Level(@NonNull String, int);
+    ctor protected Level(@NonNull String, int, @Nullable String);
+    method @NonNull public String getLocalizedName();
+    method @NonNull public String getName();
+    method @Nullable public String getResourceBundleName();
+    method public final int intValue();
+    method @NonNull public static java.util.logging.Level parse(@NonNull String) throws java.lang.IllegalArgumentException;
+    method @NonNull public final String toString();
+    field @NonNull public static final java.util.logging.Level ALL;
+    field @NonNull public static final java.util.logging.Level CONFIG;
+    field @NonNull public static final java.util.logging.Level FINE;
+    field @NonNull public static final java.util.logging.Level FINER;
+    field @NonNull public static final java.util.logging.Level FINEST;
+    field @NonNull public static final java.util.logging.Level INFO;
+    field @NonNull public static final java.util.logging.Level OFF;
+    field @NonNull public static final java.util.logging.Level SEVERE;
+    field @NonNull public static final java.util.logging.Level WARNING;
+  }
+
+  public class LogManager {
+    ctor protected LogManager();
+    method public boolean addLogger(java.util.logging.Logger);
+    method @Deprecated public void addPropertyChangeListener(java.beans.PropertyChangeListener) throws java.lang.SecurityException;
+    method public void checkAccess() throws java.lang.SecurityException;
+    method public static java.util.logging.LogManager getLogManager();
+    method public java.util.logging.Logger getLogger(String);
+    method public java.util.Enumeration<java.lang.String> getLoggerNames();
+    method public static java.util.logging.LoggingMXBean getLoggingMXBean();
+    method public String getProperty(String);
+    method public void readConfiguration() throws java.io.IOException, java.lang.SecurityException;
+    method public void readConfiguration(java.io.InputStream) throws java.io.IOException, java.lang.SecurityException;
+    method @Deprecated public void removePropertyChangeListener(java.beans.PropertyChangeListener) throws java.lang.SecurityException;
+    method public void reset() throws java.lang.SecurityException;
+    field public static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging";
+  }
+
+  public class LogRecord implements java.io.Serializable {
+    ctor public LogRecord(java.util.logging.Level, String);
+    method public java.util.logging.Level getLevel();
+    method public String getLoggerName();
+    method public String getMessage();
+    method public long getMillis();
+    method public Object[] getParameters();
+    method public java.util.ResourceBundle getResourceBundle();
+    method public String getResourceBundleName();
+    method public long getSequenceNumber();
+    method public String getSourceClassName();
+    method public String getSourceMethodName();
+    method public int getThreadID();
+    method public Throwable getThrown();
+    method public void setLevel(java.util.logging.Level);
+    method public void setLoggerName(String);
+    method public void setMessage(String);
+    method public void setMillis(long);
+    method public void setParameters(Object[]);
+    method public void setResourceBundle(java.util.ResourceBundle);
+    method public void setResourceBundleName(String);
+    method public void setSequenceNumber(long);
+    method public void setSourceClassName(String);
+    method public void setSourceMethodName(String);
+    method public void setThreadID(int);
+    method public void setThrown(Throwable);
+  }
+
+  public class Logger {
+    ctor protected Logger(@Nullable String, @Nullable String);
+    method public void addHandler(@NonNull java.util.logging.Handler) throws java.lang.SecurityException;
+    method public void config(@Nullable String);
+    method public void config(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public void entering(@Nullable String, @Nullable String);
+    method public void entering(@Nullable String, @Nullable String, @Nullable Object);
+    method public void entering(@Nullable String, @Nullable String, @Nullable Object[]);
+    method public void exiting(@Nullable String, @Nullable String);
+    method public void exiting(@Nullable String, @Nullable String, @Nullable Object);
+    method public void fine(@Nullable String);
+    method public void fine(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public void finer(@Nullable String);
+    method public void finer(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public void finest(@Nullable String);
+    method public void finest(@NonNull java.util.function.Supplier<java.lang.String>);
+    method @NonNull public static java.util.logging.Logger getAnonymousLogger();
+    method @NonNull public static java.util.logging.Logger getAnonymousLogger(@Nullable String);
+    method @Nullable public java.util.logging.Filter getFilter();
+    method @NonNull public static final java.util.logging.Logger getGlobal();
+    method @NonNull public java.util.logging.Handler[] getHandlers();
+    method @Nullable public java.util.logging.Level getLevel();
+    method @NonNull public static java.util.logging.Logger getLogger(@NonNull String);
+    method @NonNull public static java.util.logging.Logger getLogger(@NonNull String, @Nullable String);
+    method @Nullable public String getName();
+    method @Nullable public java.util.logging.Logger getParent();
+    method @Nullable public java.util.ResourceBundle getResourceBundle();
+    method @Nullable public String getResourceBundleName();
+    method public boolean getUseParentHandlers();
+    method public void info(@Nullable String);
+    method public void info(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public boolean isLoggable(@NonNull java.util.logging.Level);
+    method public void log(@NonNull java.util.logging.LogRecord);
+    method public void log(@NonNull java.util.logging.Level, @Nullable String);
+    method public void log(@NonNull java.util.logging.Level, @NonNull java.util.function.Supplier<java.lang.String>);
+    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object);
+    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Object[]);
+    method public void log(@NonNull java.util.logging.Level, @Nullable String, @Nullable Throwable);
+    method public void log(@NonNull java.util.logging.Level, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @NonNull java.util.function.Supplier<java.lang.String>);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Object);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Object[]);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable Throwable);
+    method public void logp(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable Throwable, @NonNull java.util.function.Supplier<java.lang.String>);
+    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
+    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object);
+    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Object[]);
+    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable java.lang.Object...);
+    method @Deprecated public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable String, @Nullable String, @Nullable Throwable);
+    method public void logrb(@NonNull java.util.logging.Level, @Nullable String, @Nullable String, @Nullable java.util.ResourceBundle, @Nullable String, @Nullable Throwable);
+    method public void removeHandler(@Nullable java.util.logging.Handler) throws java.lang.SecurityException;
+    method public void setFilter(@Nullable java.util.logging.Filter) throws java.lang.SecurityException;
+    method public void setLevel(@Nullable java.util.logging.Level) throws java.lang.SecurityException;
+    method public void setParent(@NonNull java.util.logging.Logger);
+    method public void setResourceBundle(@NonNull java.util.ResourceBundle);
+    method public void setUseParentHandlers(boolean);
+    method public void severe(@Nullable String);
+    method public void severe(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public void throwing(@Nullable String, @Nullable String, @Nullable Throwable);
+    method public void warning(@Nullable String);
+    method public void warning(@NonNull java.util.function.Supplier<java.lang.String>);
+    field @NonNull public static final String GLOBAL_LOGGER_NAME = "global";
+    field @Deprecated @NonNull public static final java.util.logging.Logger global;
+  }
+
+  public interface LoggingMXBean {
+    method public String getLoggerLevel(String);
+    method public java.util.List<java.lang.String> getLoggerNames();
+    method public String getParentLoggerName(String);
+    method public void setLoggerLevel(String, String);
+  }
+
+  public final class LoggingPermission extends java.security.BasicPermission {
+    ctor public LoggingPermission(String, String) throws java.lang.IllegalArgumentException;
+  }
+
+  public class MemoryHandler extends java.util.logging.Handler {
+    ctor public MemoryHandler();
+    ctor public MemoryHandler(java.util.logging.Handler, int, java.util.logging.Level);
+    method public void close() throws java.lang.SecurityException;
+    method public void flush();
+    method public java.util.logging.Level getPushLevel();
+    method public void publish(java.util.logging.LogRecord);
+    method public void push();
+    method public void setPushLevel(java.util.logging.Level) throws java.lang.SecurityException;
+  }
+
+  public class SimpleFormatter extends java.util.logging.Formatter {
+    ctor public SimpleFormatter();
+    method public String format(java.util.logging.LogRecord);
+  }
+
+  public class SocketHandler extends java.util.logging.StreamHandler {
+    ctor public SocketHandler() throws java.io.IOException;
+    ctor public SocketHandler(String, int) throws java.io.IOException;
+  }
+
+  public class StreamHandler extends java.util.logging.Handler {
+    ctor public StreamHandler();
+    ctor public StreamHandler(java.io.OutputStream, java.util.logging.Formatter);
+    method public void close() throws java.lang.SecurityException;
+    method public void flush();
+    method public void publish(java.util.logging.LogRecord);
+    method protected void setOutputStream(java.io.OutputStream) throws java.lang.SecurityException;
+  }
+
+  public class XMLFormatter extends java.util.logging.Formatter {
+    ctor public XMLFormatter();
+    method public String format(java.util.logging.LogRecord);
+  }
+
+}
+
+package java.util.prefs {
+
+  public abstract class AbstractPreferences extends java.util.prefs.Preferences {
+    ctor protected AbstractPreferences(java.util.prefs.AbstractPreferences, String);
+    method public String absolutePath();
+    method public void addNodeChangeListener(java.util.prefs.NodeChangeListener);
+    method public void addPreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
+    method protected final java.util.prefs.AbstractPreferences[] cachedChildren();
+    method protected abstract java.util.prefs.AbstractPreferences childSpi(String);
+    method public String[] childrenNames() throws java.util.prefs.BackingStoreException;
+    method protected abstract String[] childrenNamesSpi() throws java.util.prefs.BackingStoreException;
+    method public void clear() throws java.util.prefs.BackingStoreException;
+    method public void exportNode(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
+    method public void exportSubtree(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
+    method public void flush() throws java.util.prefs.BackingStoreException;
+    method protected abstract void flushSpi() throws java.util.prefs.BackingStoreException;
+    method public String get(String, String);
+    method public boolean getBoolean(String, boolean);
+    method public byte[] getByteArray(String, byte[]);
+    method protected java.util.prefs.AbstractPreferences getChild(String) throws java.util.prefs.BackingStoreException;
+    method public double getDouble(String, double);
+    method public float getFloat(String, float);
+    method public int getInt(String, int);
+    method public long getLong(String, long);
+    method protected abstract String getSpi(String);
+    method protected boolean isRemoved();
+    method public boolean isUserNode();
+    method public String[] keys() throws java.util.prefs.BackingStoreException;
+    method protected abstract String[] keysSpi() throws java.util.prefs.BackingStoreException;
+    method public String name();
+    method public java.util.prefs.Preferences node(String);
+    method public boolean nodeExists(String) throws java.util.prefs.BackingStoreException;
+    method public java.util.prefs.Preferences parent();
+    method public void put(String, String);
+    method public void putBoolean(String, boolean);
+    method public void putByteArray(String, byte[]);
+    method public void putDouble(String, double);
+    method public void putFloat(String, float);
+    method public void putInt(String, int);
+    method public void putLong(String, long);
+    method protected abstract void putSpi(String, String);
+    method public void remove(String);
+    method public void removeNode() throws java.util.prefs.BackingStoreException;
+    method public void removeNodeChangeListener(java.util.prefs.NodeChangeListener);
+    method protected abstract void removeNodeSpi() throws java.util.prefs.BackingStoreException;
+    method public void removePreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
+    method protected abstract void removeSpi(String);
+    method public void sync() throws java.util.prefs.BackingStoreException;
+    method protected abstract void syncSpi() throws java.util.prefs.BackingStoreException;
+    field protected final Object lock;
+    field protected boolean newNode;
+  }
+
+  public class BackingStoreException extends java.lang.Exception {
+    ctor public BackingStoreException(String);
+    ctor public BackingStoreException(Throwable);
+  }
+
+  public class InvalidPreferencesFormatException extends java.lang.Exception {
+    ctor public InvalidPreferencesFormatException(Throwable);
+    ctor public InvalidPreferencesFormatException(String);
+    ctor public InvalidPreferencesFormatException(String, Throwable);
+  }
+
+  public class NodeChangeEvent extends java.util.EventObject {
+    ctor public NodeChangeEvent(java.util.prefs.Preferences, java.util.prefs.Preferences);
+    method public java.util.prefs.Preferences getChild();
+    method public java.util.prefs.Preferences getParent();
+  }
+
+  public interface NodeChangeListener extends java.util.EventListener {
+    method public void childAdded(java.util.prefs.NodeChangeEvent);
+    method public void childRemoved(java.util.prefs.NodeChangeEvent);
+  }
+
+  public class PreferenceChangeEvent extends java.util.EventObject {
+    ctor public PreferenceChangeEvent(java.util.prefs.Preferences, String, String);
+    method public String getKey();
+    method public String getNewValue();
+    method public java.util.prefs.Preferences getNode();
+  }
+
+  @java.lang.FunctionalInterface public interface PreferenceChangeListener extends java.util.EventListener {
+    method public void preferenceChange(java.util.prefs.PreferenceChangeEvent);
+  }
+
+  public abstract class Preferences {
+    ctor protected Preferences();
+    method public abstract String absolutePath();
+    method public abstract void addNodeChangeListener(java.util.prefs.NodeChangeListener);
+    method public abstract void addPreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
+    method public abstract String[] childrenNames() throws java.util.prefs.BackingStoreException;
+    method public abstract void clear() throws java.util.prefs.BackingStoreException;
+    method public abstract void exportNode(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
+    method public abstract void exportSubtree(java.io.OutputStream) throws java.util.prefs.BackingStoreException, java.io.IOException;
+    method public abstract void flush() throws java.util.prefs.BackingStoreException;
+    method public abstract String get(String, String);
+    method public abstract boolean getBoolean(String, boolean);
+    method public abstract byte[] getByteArray(String, byte[]);
+    method public abstract double getDouble(String, double);
+    method public abstract float getFloat(String, float);
+    method public abstract int getInt(String, int);
+    method public abstract long getLong(String, long);
+    method public static void importPreferences(java.io.InputStream) throws java.io.IOException, java.util.prefs.InvalidPreferencesFormatException;
+    method public abstract boolean isUserNode();
+    method public abstract String[] keys() throws java.util.prefs.BackingStoreException;
+    method public abstract String name();
+    method public abstract java.util.prefs.Preferences node(String);
+    method public abstract boolean nodeExists(String) throws java.util.prefs.BackingStoreException;
+    method public abstract java.util.prefs.Preferences parent();
+    method public abstract void put(String, String);
+    method public abstract void putBoolean(String, boolean);
+    method public abstract void putByteArray(String, byte[]);
+    method public abstract void putDouble(String, double);
+    method public abstract void putFloat(String, float);
+    method public abstract void putInt(String, int);
+    method public abstract void putLong(String, long);
+    method public abstract void remove(String);
+    method public abstract void removeNode() throws java.util.prefs.BackingStoreException;
+    method public abstract void removeNodeChangeListener(java.util.prefs.NodeChangeListener);
+    method public abstract void removePreferenceChangeListener(java.util.prefs.PreferenceChangeListener);
+    method public abstract void sync() throws java.util.prefs.BackingStoreException;
+    method public static java.util.prefs.Preferences systemNodeForPackage(Class<?>);
+    method public static java.util.prefs.Preferences systemRoot();
+    method public abstract String toString();
+    method public static java.util.prefs.Preferences userNodeForPackage(Class<?>);
+    method public static java.util.prefs.Preferences userRoot();
+    field public static final int MAX_KEY_LENGTH = 80; // 0x50
+    field public static final int MAX_NAME_LENGTH = 80; // 0x50
+    field public static final int MAX_VALUE_LENGTH = 8192; // 0x2000
+  }
+
+  public interface PreferencesFactory {
+    method public java.util.prefs.Preferences systemRoot();
+    method public java.util.prefs.Preferences userRoot();
+  }
+
+}
+
+package java.util.regex {
+
+  public interface MatchResult {
+    method public int end();
+    method public int end(int);
+    method public String group();
+    method public String group(int);
+    method public int groupCount();
+    method public int start();
+    method public int start(int);
+  }
+
+  public final class Matcher implements java.util.regex.MatchResult {
+    method @NonNull public java.util.regex.Matcher appendReplacement(@NonNull StringBuffer, @NonNull String);
+    method @NonNull public StringBuffer appendTail(@NonNull StringBuffer);
+    method public int end();
+    method public int end(int);
+    method public int end(@NonNull String);
+    method public boolean find();
+    method public boolean find(int);
+    method @NonNull public String group();
+    method @Nullable public String group(int);
+    method @Nullable public String group(@NonNull String);
+    method public int groupCount();
+    method public boolean hasAnchoringBounds();
+    method public boolean hasTransparentBounds();
+    method public boolean hitEnd();
+    method public boolean lookingAt();
+    method public boolean matches();
+    method @NonNull public java.util.regex.Pattern pattern();
+    method @NonNull public static String quoteReplacement(@NonNull String);
+    method @NonNull public java.util.regex.Matcher region(int, int);
+    method public int regionEnd();
+    method public int regionStart();
+    method @NonNull public String replaceAll(@NonNull String);
+    method @NonNull public String replaceFirst(@NonNull String);
+    method public boolean requireEnd();
+    method @NonNull public java.util.regex.Matcher reset();
+    method @NonNull public java.util.regex.Matcher reset(@NonNull CharSequence);
+    method public int start();
+    method public int start(int);
+    method public int start(@NonNull String);
+    method @NonNull public java.util.regex.MatchResult toMatchResult();
+    method @NonNull public java.util.regex.Matcher useAnchoringBounds(boolean);
+    method @NonNull public java.util.regex.Matcher usePattern(@NonNull java.util.regex.Pattern);
+    method @NonNull public java.util.regex.Matcher useTransparentBounds(boolean);
+  }
+
+  public final class Pattern implements java.io.Serializable {
+    method @NonNull public java.util.function.Predicate<java.lang.String> asPredicate();
+    method @NonNull public static java.util.regex.Pattern compile(@NonNull String);
+    method @NonNull public static java.util.regex.Pattern compile(@NonNull String, int);
+    method public int flags();
+    method @NonNull public java.util.regex.Matcher matcher(@NonNull CharSequence);
+    method public static boolean matches(@NonNull String, @NonNull CharSequence);
+    method @NonNull public String pattern();
+    method @NonNull public static String quote(@NonNull String);
+    method @NonNull public String[] split(@NonNull CharSequence, int);
+    method @NonNull public String[] split(@NonNull CharSequence);
+    method @NonNull public java.util.stream.Stream<java.lang.String> splitAsStream(@NonNull CharSequence);
+    field public static final int CANON_EQ = 128; // 0x80
+    field public static final int CASE_INSENSITIVE = 2; // 0x2
+    field public static final int COMMENTS = 4; // 0x4
+    field public static final int DOTALL = 32; // 0x20
+    field public static final int LITERAL = 16; // 0x10
+    field public static final int MULTILINE = 8; // 0x8
+    field public static final int UNICODE_CASE = 64; // 0x40
+    field public static final int UNICODE_CHARACTER_CLASS = 256; // 0x100
+    field public static final int UNIX_LINES = 1; // 0x1
+  }
+
+  public class PatternSyntaxException extends java.lang.IllegalArgumentException {
+    ctor public PatternSyntaxException(String, String, int);
+    method public String getDescription();
+    method public int getIndex();
+    method public String getPattern();
+  }
+
+}
+
+package java.util.stream {
+
+  public interface BaseStream<T, S extends java.util.stream.BaseStream<T, S>> extends java.lang.AutoCloseable {
+    method public void close();
+    method public boolean isParallel();
+    method public java.util.Iterator<T> iterator();
+    method public S onClose(Runnable);
+    method public S parallel();
+    method public S sequential();
+    method public java.util.Spliterator<T> spliterator();
+    method public S unordered();
+  }
+
+  public interface Collector<T, A, R> {
+    method public java.util.function.BiConsumer<A,T> accumulator();
+    method public java.util.Set<java.util.stream.Collector.Characteristics> characteristics();
+    method public java.util.function.BinaryOperator<A> combiner();
+    method public java.util.function.Function<A,R> finisher();
+    method public static <T, R> java.util.stream.Collector<T,R,R> of(java.util.function.Supplier<R>, java.util.function.BiConsumer<R,T>, java.util.function.BinaryOperator<R>, java.util.stream.Collector.Characteristics...);
+    method public static <T, A, R> java.util.stream.Collector<T,A,R> of(java.util.function.Supplier<A>, java.util.function.BiConsumer<A,T>, java.util.function.BinaryOperator<A>, java.util.function.Function<A,R>, java.util.stream.Collector.Characteristics...);
+    method public java.util.function.Supplier<A> supplier();
+  }
+
+  public enum Collector.Characteristics {
+    enum_constant public static final java.util.stream.Collector.Characteristics CONCURRENT;
+    enum_constant public static final java.util.stream.Collector.Characteristics IDENTITY_FINISH;
+    enum_constant public static final java.util.stream.Collector.Characteristics UNORDERED;
+  }
+
+  public final class Collectors {
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingInt(java.util.function.ToIntFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> averagingLong(java.util.function.ToLongFunction<? super T>);
+    method public static <T, A, R, RR> java.util.stream.Collector<T,A,RR> collectingAndThen(java.util.stream.Collector<T,A,R>, java.util.function.Function<R,RR>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Long> counting();
+    method public static <T, K> java.util.stream.Collector<T,?,java.util.Map<K,java.util.List<T>>> groupingBy(java.util.function.Function<? super T,? extends K>);
+    method public static <T, K, A, D> java.util.stream.Collector<T,?,java.util.Map<K,D>> groupingBy(java.util.function.Function<? super T,? extends K>, java.util.stream.Collector<? super T,A,D>);
+    method public static <T, K, D, A, M extends java.util.Map<K, D>> java.util.stream.Collector<T,?,M> groupingBy(java.util.function.Function<? super T,? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T,A,D>);
+    method public static <T, K> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,java.util.List<T>>> groupingByConcurrent(java.util.function.Function<? super T,? extends K>);
+    method public static <T, K, A, D> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,D>> groupingByConcurrent(java.util.function.Function<? super T,? extends K>, java.util.stream.Collector<? super T,A,D>);
+    method public static <T, K, A, D, M extends java.util.concurrent.ConcurrentMap<K, D>> java.util.stream.Collector<T,?,M> groupingByConcurrent(java.util.function.Function<? super T,? extends K>, java.util.function.Supplier<M>, java.util.stream.Collector<? super T,A,D>);
+    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining();
+    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining(CharSequence);
+    method public static java.util.stream.Collector<java.lang.CharSequence,?,java.lang.String> joining(CharSequence, CharSequence, CharSequence);
+    method public static <T, U, A, R> java.util.stream.Collector<T,?,R> mapping(java.util.function.Function<? super T,? extends U>, java.util.stream.Collector<? super U,A,R>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> maxBy(java.util.Comparator<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> minBy(java.util.Comparator<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.Map<java.lang.Boolean,java.util.List<T>>> partitioningBy(java.util.function.Predicate<? super T>);
+    method public static <T, D, A> java.util.stream.Collector<T,?,java.util.Map<java.lang.Boolean,D>> partitioningBy(java.util.function.Predicate<? super T>, java.util.stream.Collector<? super T,A,D>);
+    method public static <T> java.util.stream.Collector<T,?,T> reducing(T, java.util.function.BinaryOperator<T>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.Optional<T>> reducing(java.util.function.BinaryOperator<T>);
+    method public static <T, U> java.util.stream.Collector<T,?,U> reducing(U, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.DoubleSummaryStatistics> summarizingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.IntSummaryStatistics> summarizingInt(java.util.function.ToIntFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.LongSummaryStatistics> summarizingLong(java.util.function.ToLongFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Double> summingDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Integer> summingInt(java.util.function.ToIntFunction<? super T>);
+    method public static <T> java.util.stream.Collector<T,?,java.lang.Long> summingLong(java.util.function.ToLongFunction<? super T>);
+    method public static <T, C extends java.util.Collection<T>> java.util.stream.Collector<T,?,C> toCollection(java.util.function.Supplier<C>);
+    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,U>> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>);
+    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.concurrent.ConcurrentMap<K,U>> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
+    method public static <T, K, U, M extends java.util.concurrent.ConcurrentMap<K, U>> java.util.stream.Collector<T,?,M> toConcurrentMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.List<T>> toList();
+    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.Map<K,U>> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>);
+    method public static <T, K, U> java.util.stream.Collector<T,?,java.util.Map<K,U>> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>);
+    method public static <T, K, U, M extends java.util.Map<K, U>> java.util.stream.Collector<T,?,M> toMap(java.util.function.Function<? super T,? extends K>, java.util.function.Function<? super T,? extends U>, java.util.function.BinaryOperator<U>, java.util.function.Supplier<M>);
+    method public static <T> java.util.stream.Collector<T,?,java.util.Set<T>> toSet();
+  }
+
+  public interface DoubleStream extends java.util.stream.BaseStream<java.lang.Double,java.util.stream.DoubleStream> {
+    method public boolean allMatch(java.util.function.DoublePredicate);
+    method public boolean anyMatch(java.util.function.DoublePredicate);
+    method public java.util.OptionalDouble average();
+    method public java.util.stream.Stream<java.lang.Double> boxed();
+    method public static java.util.stream.DoubleStream.Builder builder();
+    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjDoubleConsumer<R>, java.util.function.BiConsumer<R,R>);
+    method public static java.util.stream.DoubleStream concat(java.util.stream.DoubleStream, java.util.stream.DoubleStream);
+    method public long count();
+    method public java.util.stream.DoubleStream distinct();
+    method public static java.util.stream.DoubleStream empty();
+    method public java.util.stream.DoubleStream filter(java.util.function.DoublePredicate);
+    method public java.util.OptionalDouble findAny();
+    method public java.util.OptionalDouble findFirst();
+    method public java.util.stream.DoubleStream flatMap(java.util.function.DoubleFunction<? extends java.util.stream.DoubleStream>);
+    method public void forEach(java.util.function.DoubleConsumer);
+    method public void forEachOrdered(java.util.function.DoubleConsumer);
+    method public static java.util.stream.DoubleStream generate(java.util.function.DoubleSupplier);
+    method public static java.util.stream.DoubleStream iterate(double, java.util.function.DoubleUnaryOperator);
+    method public java.util.PrimitiveIterator.OfDouble iterator();
+    method public java.util.stream.DoubleStream limit(long);
+    method public java.util.stream.DoubleStream map(java.util.function.DoubleUnaryOperator);
+    method public java.util.stream.IntStream mapToInt(java.util.function.DoubleToIntFunction);
+    method public java.util.stream.LongStream mapToLong(java.util.function.DoubleToLongFunction);
+    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.DoubleFunction<? extends U>);
+    method public java.util.OptionalDouble max();
+    method public java.util.OptionalDouble min();
+    method public boolean noneMatch(java.util.function.DoublePredicate);
+    method public static java.util.stream.DoubleStream of(double);
+    method public static java.util.stream.DoubleStream of(double...);
+    method public java.util.stream.DoubleStream parallel();
+    method public java.util.stream.DoubleStream peek(java.util.function.DoubleConsumer);
+    method public double reduce(double, java.util.function.DoubleBinaryOperator);
+    method public java.util.OptionalDouble reduce(java.util.function.DoubleBinaryOperator);
+    method public java.util.stream.DoubleStream sequential();
+    method public java.util.stream.DoubleStream skip(long);
+    method public java.util.stream.DoubleStream sorted();
+    method public java.util.Spliterator.OfDouble spliterator();
+    method public double sum();
+    method public java.util.DoubleSummaryStatistics summaryStatistics();
+    method public double[] toArray();
+  }
+
+  public static interface DoubleStream.Builder extends java.util.function.DoubleConsumer {
+    method public default java.util.stream.DoubleStream.Builder add(double);
+    method public java.util.stream.DoubleStream build();
+  }
+
+  public interface IntStream extends java.util.stream.BaseStream<java.lang.Integer,java.util.stream.IntStream> {
+    method public boolean allMatch(java.util.function.IntPredicate);
+    method public boolean anyMatch(java.util.function.IntPredicate);
+    method public java.util.stream.DoubleStream asDoubleStream();
+    method public java.util.stream.LongStream asLongStream();
+    method public java.util.OptionalDouble average();
+    method public java.util.stream.Stream<java.lang.Integer> boxed();
+    method public static java.util.stream.IntStream.Builder builder();
+    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjIntConsumer<R>, java.util.function.BiConsumer<R,R>);
+    method public static java.util.stream.IntStream concat(java.util.stream.IntStream, java.util.stream.IntStream);
+    method public long count();
+    method public java.util.stream.IntStream distinct();
+    method public static java.util.stream.IntStream empty();
+    method public java.util.stream.IntStream filter(java.util.function.IntPredicate);
+    method public java.util.OptionalInt findAny();
+    method public java.util.OptionalInt findFirst();
+    method public java.util.stream.IntStream flatMap(java.util.function.IntFunction<? extends java.util.stream.IntStream>);
+    method public void forEach(java.util.function.IntConsumer);
+    method public void forEachOrdered(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream generate(java.util.function.IntSupplier);
+    method public static java.util.stream.IntStream iterate(int, java.util.function.IntUnaryOperator);
+    method public java.util.PrimitiveIterator.OfInt iterator();
+    method public java.util.stream.IntStream limit(long);
+    method public java.util.stream.IntStream map(java.util.function.IntUnaryOperator);
+    method public java.util.stream.DoubleStream mapToDouble(java.util.function.IntToDoubleFunction);
+    method public java.util.stream.LongStream mapToLong(java.util.function.IntToLongFunction);
+    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.IntFunction<? extends U>);
+    method public java.util.OptionalInt max();
+    method public java.util.OptionalInt min();
+    method public boolean noneMatch(java.util.function.IntPredicate);
+    method public static java.util.stream.IntStream of(int);
+    method public static java.util.stream.IntStream of(int...);
+    method public java.util.stream.IntStream parallel();
+    method public java.util.stream.IntStream peek(java.util.function.IntConsumer);
+    method public static java.util.stream.IntStream range(int, int);
+    method public static java.util.stream.IntStream rangeClosed(int, int);
+    method public int reduce(int, java.util.function.IntBinaryOperator);
+    method public java.util.OptionalInt reduce(java.util.function.IntBinaryOperator);
+    method public java.util.stream.IntStream sequential();
+    method public java.util.stream.IntStream skip(long);
+    method public java.util.stream.IntStream sorted();
+    method public java.util.Spliterator.OfInt spliterator();
+    method public int sum();
+    method public java.util.IntSummaryStatistics summaryStatistics();
+    method public int[] toArray();
+  }
+
+  public static interface IntStream.Builder extends java.util.function.IntConsumer {
+    method public default java.util.stream.IntStream.Builder add(int);
+    method public java.util.stream.IntStream build();
+  }
+
+  public interface LongStream extends java.util.stream.BaseStream<java.lang.Long,java.util.stream.LongStream> {
+    method public boolean allMatch(java.util.function.LongPredicate);
+    method public boolean anyMatch(java.util.function.LongPredicate);
+    method public java.util.stream.DoubleStream asDoubleStream();
+    method public java.util.OptionalDouble average();
+    method public java.util.stream.Stream<java.lang.Long> boxed();
+    method public static java.util.stream.LongStream.Builder builder();
+    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.ObjLongConsumer<R>, java.util.function.BiConsumer<R,R>);
+    method public static java.util.stream.LongStream concat(java.util.stream.LongStream, java.util.stream.LongStream);
+    method public long count();
+    method public java.util.stream.LongStream distinct();
+    method public static java.util.stream.LongStream empty();
+    method public java.util.stream.LongStream filter(java.util.function.LongPredicate);
+    method public java.util.OptionalLong findAny();
+    method public java.util.OptionalLong findFirst();
+    method public java.util.stream.LongStream flatMap(java.util.function.LongFunction<? extends java.util.stream.LongStream>);
+    method public void forEach(java.util.function.LongConsumer);
+    method public void forEachOrdered(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream generate(java.util.function.LongSupplier);
+    method public static java.util.stream.LongStream iterate(long, java.util.function.LongUnaryOperator);
+    method public java.util.PrimitiveIterator.OfLong iterator();
+    method public java.util.stream.LongStream limit(long);
+    method public java.util.stream.LongStream map(java.util.function.LongUnaryOperator);
+    method public java.util.stream.DoubleStream mapToDouble(java.util.function.LongToDoubleFunction);
+    method public java.util.stream.IntStream mapToInt(java.util.function.LongToIntFunction);
+    method public <U> java.util.stream.Stream<U> mapToObj(java.util.function.LongFunction<? extends U>);
+    method public java.util.OptionalLong max();
+    method public java.util.OptionalLong min();
+    method public boolean noneMatch(java.util.function.LongPredicate);
+    method public static java.util.stream.LongStream of(long);
+    method public static java.util.stream.LongStream of(long...);
+    method public java.util.stream.LongStream parallel();
+    method public java.util.stream.LongStream peek(java.util.function.LongConsumer);
+    method public static java.util.stream.LongStream range(long, long);
+    method public static java.util.stream.LongStream rangeClosed(long, long);
+    method public long reduce(long, java.util.function.LongBinaryOperator);
+    method public java.util.OptionalLong reduce(java.util.function.LongBinaryOperator);
+    method public java.util.stream.LongStream sequential();
+    method public java.util.stream.LongStream skip(long);
+    method public java.util.stream.LongStream sorted();
+    method public java.util.Spliterator.OfLong spliterator();
+    method public long sum();
+    method public java.util.LongSummaryStatistics summaryStatistics();
+    method public long[] toArray();
+  }
+
+  public static interface LongStream.Builder extends java.util.function.LongConsumer {
+    method public default java.util.stream.LongStream.Builder add(long);
+    method public java.util.stream.LongStream build();
+  }
+
+  public interface Stream<T> extends java.util.stream.BaseStream<T,java.util.stream.Stream<T>> {
+    method public boolean allMatch(java.util.function.Predicate<? super T>);
+    method public boolean anyMatch(java.util.function.Predicate<? super T>);
+    method public static <T> java.util.stream.Stream.Builder<T> builder();
+    method public <R> R collect(java.util.function.Supplier<R>, java.util.function.BiConsumer<R,? super T>, java.util.function.BiConsumer<R,R>);
+    method public <R, A> R collect(java.util.stream.Collector<? super T,A,R>);
+    method public static <T> java.util.stream.Stream<T> concat(java.util.stream.Stream<? extends T>, java.util.stream.Stream<? extends T>);
+    method public long count();
+    method public java.util.stream.Stream<T> distinct();
+    method public static <T> java.util.stream.Stream<T> empty();
+    method public java.util.stream.Stream<T> filter(java.util.function.Predicate<? super T>);
+    method public java.util.Optional<T> findAny();
+    method public java.util.Optional<T> findFirst();
+    method public <R> java.util.stream.Stream<R> flatMap(java.util.function.Function<? super T,? extends java.util.stream.Stream<? extends R>>);
+    method public java.util.stream.DoubleStream flatMapToDouble(java.util.function.Function<? super T,? extends java.util.stream.DoubleStream>);
+    method public java.util.stream.IntStream flatMapToInt(java.util.function.Function<? super T,? extends java.util.stream.IntStream>);
+    method public java.util.stream.LongStream flatMapToLong(java.util.function.Function<? super T,? extends java.util.stream.LongStream>);
+    method public void forEach(java.util.function.Consumer<? super T>);
+    method public void forEachOrdered(java.util.function.Consumer<? super T>);
+    method public static <T> java.util.stream.Stream<T> generate(java.util.function.Supplier<T>);
+    method public static <T> java.util.stream.Stream<T> iterate(T, java.util.function.UnaryOperator<T>);
+    method public java.util.stream.Stream<T> limit(long);
+    method public <R> java.util.stream.Stream<R> map(java.util.function.Function<? super T,? extends R>);
+    method public java.util.stream.DoubleStream mapToDouble(java.util.function.ToDoubleFunction<? super T>);
+    method public java.util.stream.IntStream mapToInt(java.util.function.ToIntFunction<? super T>);
+    method public java.util.stream.LongStream mapToLong(java.util.function.ToLongFunction<? super T>);
+    method public java.util.Optional<T> max(java.util.Comparator<? super T>);
+    method public java.util.Optional<T> min(java.util.Comparator<? super T>);
+    method public boolean noneMatch(java.util.function.Predicate<? super T>);
+    method public static <T> java.util.stream.Stream<T> of(T);
+    method @java.lang.SafeVarargs public static <T> java.util.stream.Stream<T> of(T...);
+    method public java.util.stream.Stream<T> peek(java.util.function.Consumer<? super T>);
+    method public T reduce(T, java.util.function.BinaryOperator<T>);
+    method public java.util.Optional<T> reduce(java.util.function.BinaryOperator<T>);
+    method public <U> U reduce(U, java.util.function.BiFunction<U,? super T,U>, java.util.function.BinaryOperator<U>);
+    method public java.util.stream.Stream<T> skip(long);
+    method public java.util.stream.Stream<T> sorted();
+    method public java.util.stream.Stream<T> sorted(java.util.Comparator<? super T>);
+    method public Object[] toArray();
+    method public <A> A[] toArray(java.util.function.IntFunction<A[]>);
+  }
+
+  public static interface Stream.Builder<T> extends java.util.function.Consumer<T> {
+    method public default java.util.stream.Stream.Builder<T> add(T);
+    method public java.util.stream.Stream<T> build();
+  }
+
+  public final class StreamSupport {
+    method public static java.util.stream.DoubleStream doubleStream(java.util.Spliterator.OfDouble, boolean);
+    method public static java.util.stream.DoubleStream doubleStream(java.util.function.Supplier<? extends java.util.Spliterator.OfDouble>, int, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.Spliterator.OfInt, boolean);
+    method public static java.util.stream.IntStream intStream(java.util.function.Supplier<? extends java.util.Spliterator.OfInt>, int, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.Spliterator.OfLong, boolean);
+    method public static java.util.stream.LongStream longStream(java.util.function.Supplier<? extends java.util.Spliterator.OfLong>, int, boolean);
+    method public static <T> java.util.stream.Stream<T> stream(java.util.Spliterator<T>, boolean);
+    method public static <T> java.util.stream.Stream<T> stream(java.util.function.Supplier<? extends java.util.Spliterator<T>>, int, boolean);
+  }
+
+}
+
+package java.util.zip {
+
+  public class Adler32 implements java.util.zip.Checksum {
+    ctor public Adler32();
+    method public long getValue();
+    method public void reset();
+    method public void update(int);
+    method public void update(byte[], int, int);
+    method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
+  }
+
+  public class CRC32 implements java.util.zip.Checksum {
+    ctor public CRC32();
+    method public long getValue();
+    method public void reset();
+    method public void update(int);
+    method public void update(byte[], int, int);
+    method public void update(byte[]);
+    method public void update(java.nio.ByteBuffer);
+  }
+
+  public class CheckedInputStream extends java.io.FilterInputStream {
+    ctor public CheckedInputStream(java.io.InputStream, java.util.zip.Checksum);
+    method public java.util.zip.Checksum getChecksum();
+  }
+
+  public class CheckedOutputStream extends java.io.FilterOutputStream {
+    ctor public CheckedOutputStream(java.io.OutputStream, java.util.zip.Checksum);
+    method public java.util.zip.Checksum getChecksum();
+  }
+
+  public interface Checksum {
+    method public long getValue();
+    method public void reset();
+    method public void update(int);
+    method public void update(byte[], int, int);
+  }
+
+  public class DataFormatException extends java.lang.Exception {
+    ctor public DataFormatException();
+    ctor public DataFormatException(String);
+  }
+
+  public class Deflater {
+    ctor public Deflater(int, boolean);
+    ctor public Deflater(int);
+    ctor public Deflater();
+    method public int deflate(byte[], int, int);
+    method public int deflate(byte[]);
+    method public int deflate(byte[], int, int, int);
+    method public void end();
+    method protected void finalize();
+    method public void finish();
+    method public boolean finished();
+    method public int getAdler();
+    method public long getBytesRead();
+    method public long getBytesWritten();
+    method public int getTotalIn();
+    method public int getTotalOut();
+    method public boolean needsInput();
+    method public void reset();
+    method public void setDictionary(byte[], int, int);
+    method public void setDictionary(byte[]);
+    method public void setInput(byte[], int, int);
+    method public void setInput(byte[]);
+    method public void setLevel(int);
+    method public void setStrategy(int);
+    field public static final int BEST_COMPRESSION = 9; // 0x9
+    field public static final int BEST_SPEED = 1; // 0x1
+    field public static final int DEFAULT_COMPRESSION = -1; // 0xffffffff
+    field public static final int DEFAULT_STRATEGY = 0; // 0x0
+    field public static final int DEFLATED = 8; // 0x8
+    field public static final int FILTERED = 1; // 0x1
+    field public static final int FULL_FLUSH = 3; // 0x3
+    field public static final int HUFFMAN_ONLY = 2; // 0x2
+    field public static final int NO_COMPRESSION = 0; // 0x0
+    field public static final int NO_FLUSH = 0; // 0x0
+    field public static final int SYNC_FLUSH = 2; // 0x2
+  }
+
+  public class DeflaterInputStream extends java.io.FilterInputStream {
+    ctor public DeflaterInputStream(java.io.InputStream);
+    ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater);
+    ctor public DeflaterInputStream(java.io.InputStream, java.util.zip.Deflater, int);
+    field protected final byte[] buf;
+    field protected final java.util.zip.Deflater def;
+  }
+
+  public class DeflaterOutputStream extends java.io.FilterOutputStream {
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int, boolean);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, int);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater, boolean);
+    ctor public DeflaterOutputStream(java.io.OutputStream, java.util.zip.Deflater);
+    ctor public DeflaterOutputStream(java.io.OutputStream, boolean);
+    ctor public DeflaterOutputStream(java.io.OutputStream);
+    method protected void deflate() throws java.io.IOException;
+    method public void finish() throws java.io.IOException;
+    field protected byte[] buf;
+    field protected java.util.zip.Deflater def;
+  }
+
+  public class GZIPInputStream extends java.util.zip.InflaterInputStream {
+    ctor public GZIPInputStream(java.io.InputStream, int) throws java.io.IOException;
+    ctor public GZIPInputStream(java.io.InputStream) throws java.io.IOException;
+    field public static final int GZIP_MAGIC = 35615; // 0x8b1f
+    field protected java.util.zip.CRC32 crc;
+    field protected boolean eos;
+  }
+
+  public class GZIPOutputStream extends java.util.zip.DeflaterOutputStream {
+    ctor public GZIPOutputStream(java.io.OutputStream, int) throws java.io.IOException;
+    ctor public GZIPOutputStream(java.io.OutputStream, int, boolean) throws java.io.IOException;
+    ctor public GZIPOutputStream(java.io.OutputStream) throws java.io.IOException;
+    ctor public GZIPOutputStream(java.io.OutputStream, boolean) throws java.io.IOException;
+    field protected java.util.zip.CRC32 crc;
+  }
+
+  public class Inflater {
+    ctor public Inflater(boolean);
+    ctor public Inflater();
+    method public void end();
+    method protected void finalize();
+    method public boolean finished();
+    method public int getAdler();
+    method public long getBytesRead();
+    method public long getBytesWritten();
+    method public int getRemaining();
+    method public int getTotalIn();
+    method public int getTotalOut();
+    method public int inflate(byte[], int, int) throws java.util.zip.DataFormatException;
+    method public int inflate(byte[]) throws java.util.zip.DataFormatException;
+    method public boolean needsDictionary();
+    method public boolean needsInput();
+    method public void reset();
+    method public void setDictionary(byte[], int, int);
+    method public void setDictionary(byte[]);
+    method public void setInput(byte[], int, int);
+    method public void setInput(byte[]);
+  }
+
+  public class InflaterInputStream extends java.io.FilterInputStream {
+    ctor public InflaterInputStream(java.io.InputStream, java.util.zip.Inflater, int);
+    ctor public InflaterInputStream(java.io.InputStream, java.util.zip.Inflater);
+    ctor public InflaterInputStream(java.io.InputStream);
+    method protected void fill() throws java.io.IOException;
+    field protected byte[] buf;
+    field @Deprecated protected boolean closed;
+    field protected java.util.zip.Inflater inf;
+    field protected int len;
+  }
+
+  public class InflaterOutputStream extends java.io.FilterOutputStream {
+    ctor public InflaterOutputStream(java.io.OutputStream);
+    ctor public InflaterOutputStream(java.io.OutputStream, java.util.zip.Inflater);
+    ctor public InflaterOutputStream(java.io.OutputStream, java.util.zip.Inflater, int);
+    method public void finish() throws java.io.IOException;
+    field protected final byte[] buf;
+    field protected final java.util.zip.Inflater inf;
+  }
+
+  public class ZipEntry implements java.lang.Cloneable {
+    ctor public ZipEntry(String);
+    ctor public ZipEntry(java.util.zip.ZipEntry);
+    method public Object clone();
+    method public String getComment();
+    method public long getCompressedSize();
+    method public long getCrc();
+    method public java.nio.file.attribute.FileTime getCreationTime();
+    method public byte[] getExtra();
+    method public java.nio.file.attribute.FileTime getLastAccessTime();
+    method public java.nio.file.attribute.FileTime getLastModifiedTime();
+    method public int getMethod();
+    method public String getName();
+    method public long getSize();
+    method public long getTime();
+    method public boolean isDirectory();
+    method public void setComment(String);
+    method public void setCompressedSize(long);
+    method public void setCrc(long);
+    method public java.util.zip.ZipEntry setCreationTime(java.nio.file.attribute.FileTime);
+    method public void setExtra(byte[]);
+    method public java.util.zip.ZipEntry setLastAccessTime(java.nio.file.attribute.FileTime);
+    method public java.util.zip.ZipEntry setLastModifiedTime(java.nio.file.attribute.FileTime);
+    method public void setMethod(int);
+    method public void setSize(long);
+    method public void setTime(long);
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int DEFLATED = 8; // 0x8
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+    field public static final int STORED = 0; // 0x0
+  }
+
+  public class ZipError extends java.lang.InternalError {
+    ctor public ZipError(String);
+  }
+
+  public class ZipException extends java.io.IOException {
+    ctor public ZipException();
+    ctor public ZipException(String);
+  }
+
+  public class ZipFile implements java.io.Closeable {
+    ctor public ZipFile(String) throws java.io.IOException;
+    ctor public ZipFile(java.io.File, int) throws java.io.IOException;
+    ctor public ZipFile(java.io.File) throws java.io.IOException, java.util.zip.ZipException;
+    ctor public ZipFile(java.io.File, int, java.nio.charset.Charset) throws java.io.IOException;
+    ctor public ZipFile(String, java.nio.charset.Charset) throws java.io.IOException;
+    ctor public ZipFile(java.io.File, java.nio.charset.Charset) throws java.io.IOException;
+    method public void close() throws java.io.IOException;
+    method public java.util.Enumeration<? extends java.util.zip.ZipEntry> entries();
+    method protected void finalize() throws java.io.IOException;
+    method public String getComment();
+    method public java.util.zip.ZipEntry getEntry(String);
+    method public java.io.InputStream getInputStream(java.util.zip.ZipEntry) throws java.io.IOException;
+    method public String getName();
+    method public int size();
+    method public java.util.stream.Stream<? extends java.util.zip.ZipEntry> stream();
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+    field public static final int OPEN_DELETE = 4; // 0x4
+    field public static final int OPEN_READ = 1; // 0x1
+  }
+
+  public class ZipInputStream extends java.util.zip.InflaterInputStream {
+    ctor public ZipInputStream(java.io.InputStream);
+    ctor public ZipInputStream(java.io.InputStream, java.nio.charset.Charset);
+    method public void closeEntry() throws java.io.IOException;
+    method protected java.util.zip.ZipEntry createZipEntry(String);
+    method public java.util.zip.ZipEntry getNextEntry() throws java.io.IOException;
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+  }
+
+  public class ZipOutputStream extends java.util.zip.DeflaterOutputStream {
+    ctor public ZipOutputStream(java.io.OutputStream);
+    ctor public ZipOutputStream(java.io.OutputStream, java.nio.charset.Charset);
+    method public void closeEntry() throws java.io.IOException;
+    method public void putNextEntry(java.util.zip.ZipEntry) throws java.io.IOException;
+    method public void setComment(String);
+    method public void setLevel(int);
+    method public void setMethod(int);
+    field public static final int CENATT = 36; // 0x24
+    field public static final int CENATX = 38; // 0x26
+    field public static final int CENCOM = 32; // 0x20
+    field public static final int CENCRC = 16; // 0x10
+    field public static final int CENDSK = 34; // 0x22
+    field public static final int CENEXT = 30; // 0x1e
+    field public static final int CENFLG = 8; // 0x8
+    field public static final int CENHDR = 46; // 0x2e
+    field public static final int CENHOW = 10; // 0xa
+    field public static final int CENLEN = 24; // 0x18
+    field public static final int CENNAM = 28; // 0x1c
+    field public static final int CENOFF = 42; // 0x2a
+    field public static final long CENSIG = 33639248L; // 0x2014b50L
+    field public static final int CENSIZ = 20; // 0x14
+    field public static final int CENTIM = 12; // 0xc
+    field public static final int CENVEM = 4; // 0x4
+    field public static final int CENVER = 6; // 0x6
+    field public static final int DEFLATED = 8; // 0x8
+    field public static final int ENDCOM = 20; // 0x14
+    field public static final int ENDHDR = 22; // 0x16
+    field public static final int ENDOFF = 16; // 0x10
+    field public static final long ENDSIG = 101010256L; // 0x6054b50L
+    field public static final int ENDSIZ = 12; // 0xc
+    field public static final int ENDSUB = 8; // 0x8
+    field public static final int ENDTOT = 10; // 0xa
+    field public static final int EXTCRC = 4; // 0x4
+    field public static final int EXTHDR = 16; // 0x10
+    field public static final int EXTLEN = 12; // 0xc
+    field public static final long EXTSIG = 134695760L; // 0x8074b50L
+    field public static final int EXTSIZ = 8; // 0x8
+    field public static final int LOCCRC = 14; // 0xe
+    field public static final int LOCEXT = 28; // 0x1c
+    field public static final int LOCFLG = 6; // 0x6
+    field public static final int LOCHDR = 30; // 0x1e
+    field public static final int LOCHOW = 8; // 0x8
+    field public static final int LOCLEN = 22; // 0x16
+    field public static final int LOCNAM = 26; // 0x1a
+    field public static final long LOCSIG = 67324752L; // 0x4034b50L
+    field public static final int LOCSIZ = 18; // 0x12
+    field public static final int LOCTIM = 10; // 0xa
+    field public static final int LOCVER = 4; // 0x4
+    field public static final int STORED = 0; // 0x0
+  }
+
+}
+
+package javax.crypto {
+
+  public class AEADBadTagException extends javax.crypto.BadPaddingException {
+    ctor public AEADBadTagException();
+    ctor public AEADBadTagException(String);
+  }
+
+  public class BadPaddingException extends java.security.GeneralSecurityException {
+    ctor public BadPaddingException();
+    ctor public BadPaddingException(String);
+  }
+
+  public class Cipher {
+    ctor protected Cipher(javax.crypto.CipherSpi, java.security.Provider, String);
+    method public final byte[] doFinal() throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
+    method public final int doFinal(byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method public final byte[] doFinal(byte[]) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
+    method public final byte[] doFinal(byte[], int, int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
+    method public final int doFinal(byte[], int, int, byte[]) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method public final int doFinal(byte[], int, int, byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method public final int doFinal(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method public final String getAlgorithm();
+    method public final int getBlockSize();
+    method public final javax.crypto.ExemptionMechanism getExemptionMechanism();
+    method public final byte[] getIV();
+    method public static final javax.crypto.Cipher getInstance(String) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException;
+    method public static final javax.crypto.Cipher getInstance(String, String) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.Cipher getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException, javax.crypto.NoSuchPaddingException;
+    method public static final int getMaxAllowedKeyLength(String) throws java.security.NoSuchAlgorithmException;
+    method public static final java.security.spec.AlgorithmParameterSpec getMaxAllowedParameterSpec(String) throws java.security.NoSuchAlgorithmException;
+    method public final int getOutputSize(int);
+    method public final java.security.AlgorithmParameters getParameters();
+    method public final java.security.Provider getProvider();
+    method public final void init(int, java.security.Key) throws java.security.InvalidKeyException;
+    method public final void init(int, java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method public final void init(int, java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(int, java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(int, java.security.Key, java.security.AlgorithmParameters) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(int, java.security.Key, java.security.AlgorithmParameters, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(int, java.security.cert.Certificate) throws java.security.InvalidKeyException;
+    method public final void init(int, java.security.cert.Certificate, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method public final java.security.Key unwrap(byte[], String, int) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method public final byte[] update(byte[]);
+    method public final byte[] update(byte[], int, int);
+    method public final int update(byte[], int, int, byte[]) throws javax.crypto.ShortBufferException;
+    method public final int update(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
+    method public final int update(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
+    method public final void updateAAD(byte[]);
+    method public final void updateAAD(byte[], int, int);
+    method public final void updateAAD(java.nio.ByteBuffer);
+    method public final byte[] wrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
+    field public static final int DECRYPT_MODE = 2; // 0x2
+    field public static final int ENCRYPT_MODE = 1; // 0x1
+    field public static final int PRIVATE_KEY = 2; // 0x2
+    field public static final int PUBLIC_KEY = 1; // 0x1
+    field public static final int SECRET_KEY = 3; // 0x3
+    field public static final int UNWRAP_MODE = 4; // 0x4
+    field public static final int WRAP_MODE = 3; // 0x3
+  }
+
+  public class CipherInputStream extends java.io.FilterInputStream {
+    ctor public CipherInputStream(java.io.InputStream, javax.crypto.Cipher);
+    ctor protected CipherInputStream(java.io.InputStream);
+  }
+
+  public class CipherOutputStream extends java.io.FilterOutputStream {
+    ctor public CipherOutputStream(java.io.OutputStream, javax.crypto.Cipher);
+    ctor protected CipherOutputStream(java.io.OutputStream);
+  }
+
+  public abstract class CipherSpi {
+    ctor public CipherSpi();
+    method protected abstract byte[] engineDoFinal(byte[], int, int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException;
+    method protected abstract int engineDoFinal(byte[], int, int, byte[], int) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method protected int engineDoFinal(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.BadPaddingException, javax.crypto.IllegalBlockSizeException, javax.crypto.ShortBufferException;
+    method protected abstract int engineGetBlockSize();
+    method protected abstract byte[] engineGetIV();
+    method protected int engineGetKeySize(java.security.Key) throws java.security.InvalidKeyException;
+    method protected abstract int engineGetOutputSize(int);
+    method protected abstract java.security.AlgorithmParameters engineGetParameters();
+    method protected abstract void engineInit(int, java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method protected abstract void engineInit(int, java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method protected abstract void engineInit(int, java.security.Key, java.security.AlgorithmParameters, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method protected abstract void engineSetMode(String) throws java.security.NoSuchAlgorithmException;
+    method protected abstract void engineSetPadding(String) throws javax.crypto.NoSuchPaddingException;
+    method protected java.security.Key engineUnwrap(byte[], String, int) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method protected abstract byte[] engineUpdate(byte[], int, int);
+    method protected abstract int engineUpdate(byte[], int, int, byte[], int) throws javax.crypto.ShortBufferException;
+    method protected int engineUpdate(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.crypto.ShortBufferException;
+    method protected void engineUpdateAAD(byte[], int, int);
+    method protected void engineUpdateAAD(java.nio.ByteBuffer);
+    method protected byte[] engineWrap(java.security.Key) throws javax.crypto.IllegalBlockSizeException, java.security.InvalidKeyException;
+  }
+
+  public class EncryptedPrivateKeyInfo {
+    ctor public EncryptedPrivateKeyInfo(byte[]) throws java.io.IOException;
+    ctor public EncryptedPrivateKeyInfo(String, byte[]) throws java.security.NoSuchAlgorithmException;
+    ctor public EncryptedPrivateKeyInfo(java.security.AlgorithmParameters, byte[]) throws java.security.NoSuchAlgorithmException;
+    method public String getAlgName();
+    method public java.security.AlgorithmParameters getAlgParameters();
+    method public byte[] getEncoded() throws java.io.IOException;
+    method public byte[] getEncryptedData();
+    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(javax.crypto.Cipher) throws java.security.spec.InvalidKeySpecException;
+    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key, String) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public java.security.spec.PKCS8EncodedKeySpec getKeySpec(java.security.Key, java.security.Provider) throws java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+  }
+
+  public class ExemptionMechanism {
+    ctor protected ExemptionMechanism(javax.crypto.ExemptionMechanismSpi, java.security.Provider, String);
+    method public final byte[] genExemptionBlob() throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException;
+    method public final int genExemptionBlob(byte[]) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
+    method public final int genExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, java.lang.IllegalStateException, javax.crypto.ShortBufferException;
+    method public static final javax.crypto.ExemptionMechanism getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.crypto.ExemptionMechanism getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.ExemptionMechanism getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final String getName();
+    method public final int getOutputSize(int) throws java.lang.IllegalStateException;
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.Key) throws javax.crypto.ExemptionMechanismException, java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.AlgorithmParameters) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final boolean isCryptoAllowed(java.security.Key) throws javax.crypto.ExemptionMechanismException;
+  }
+
+  public class ExemptionMechanismException extends java.security.GeneralSecurityException {
+    ctor public ExemptionMechanismException();
+    ctor public ExemptionMechanismException(String);
+  }
+
+  public abstract class ExemptionMechanismSpi {
+    ctor public ExemptionMechanismSpi();
+    method protected abstract byte[] engineGenExemptionBlob() throws javax.crypto.ExemptionMechanismException;
+    method protected abstract int engineGenExemptionBlob(byte[], int) throws javax.crypto.ExemptionMechanismException, javax.crypto.ShortBufferException;
+    method protected abstract int engineGetOutputSize(int);
+    method protected abstract void engineInit(java.security.Key) throws javax.crypto.ExemptionMechanismException, java.security.InvalidKeyException;
+    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method protected abstract void engineInit(java.security.Key, java.security.AlgorithmParameters) throws javax.crypto.ExemptionMechanismException, java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+  }
+
+  public class IllegalBlockSizeException extends java.security.GeneralSecurityException {
+    ctor public IllegalBlockSizeException();
+    ctor public IllegalBlockSizeException(String);
+  }
+
+  public class KeyAgreement {
+    ctor protected KeyAgreement(javax.crypto.KeyAgreementSpi, java.security.Provider, String);
+    method public final java.security.Key doPhase(java.security.Key, boolean) throws java.lang.IllegalStateException, java.security.InvalidKeyException;
+    method public final byte[] generateSecret() throws java.lang.IllegalStateException;
+    method public final int generateSecret(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
+    method public final javax.crypto.SecretKey generateSecret(String) throws java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method public final String getAlgorithm();
+    method public static final javax.crypto.KeyAgreement getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.crypto.KeyAgreement getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.KeyAgreement getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.Key) throws java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+  }
+
+  public abstract class KeyAgreementSpi {
+    ctor public KeyAgreementSpi();
+    method protected abstract java.security.Key engineDoPhase(java.security.Key, boolean) throws java.lang.IllegalStateException, java.security.InvalidKeyException;
+    method protected abstract byte[] engineGenerateSecret() throws java.lang.IllegalStateException;
+    method protected abstract int engineGenerateSecret(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
+    method protected abstract javax.crypto.SecretKey engineGenerateSecret(String) throws java.lang.IllegalStateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method protected abstract void engineInit(java.security.Key, java.security.SecureRandom) throws java.security.InvalidKeyException;
+    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+  }
+
+  public class KeyGenerator {
+    ctor protected KeyGenerator(javax.crypto.KeyGeneratorSpi, java.security.Provider, String);
+    method public final javax.crypto.SecretKey generateKey();
+    method public final String getAlgorithm();
+    method public static final javax.crypto.KeyGenerator getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.crypto.KeyGenerator getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.KeyGenerator getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.SecureRandom);
+    method public final void init(java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException;
+    method public final void init(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
+    method public final void init(int);
+    method public final void init(int, java.security.SecureRandom);
+  }
+
+  public abstract class KeyGeneratorSpi {
+    ctor public KeyGeneratorSpi();
+    method protected abstract javax.crypto.SecretKey engineGenerateKey();
+    method protected abstract void engineInit(java.security.SecureRandom);
+    method protected abstract void engineInit(java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom) throws java.security.InvalidAlgorithmParameterException;
+    method protected abstract void engineInit(int, java.security.SecureRandom);
+  }
+
+  public class Mac implements java.lang.Cloneable {
+    ctor protected Mac(javax.crypto.MacSpi, java.security.Provider, String);
+    method public final Object clone() throws java.lang.CloneNotSupportedException;
+    method public final byte[] doFinal() throws java.lang.IllegalStateException;
+    method public final void doFinal(byte[], int) throws java.lang.IllegalStateException, javax.crypto.ShortBufferException;
+    method public final byte[] doFinal(byte[]) throws java.lang.IllegalStateException;
+    method public final String getAlgorithm();
+    method public static final javax.crypto.Mac getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.crypto.Mac getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.Mac getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final int getMacLength();
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.Key) throws java.security.InvalidKeyException;
+    method public final void init(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method public final void reset();
+    method public final void update(byte) throws java.lang.IllegalStateException;
+    method public final void update(byte[]) throws java.lang.IllegalStateException;
+    method public final void update(byte[], int, int) throws java.lang.IllegalStateException;
+    method public final void update(java.nio.ByteBuffer);
+  }
+
+  public abstract class MacSpi {
+    ctor public MacSpi();
+    method public Object clone() throws java.lang.CloneNotSupportedException;
+    method protected abstract byte[] engineDoFinal();
+    method protected abstract int engineGetMacLength();
+    method protected abstract void engineInit(java.security.Key, java.security.spec.AlgorithmParameterSpec) throws java.security.InvalidAlgorithmParameterException, java.security.InvalidKeyException;
+    method protected abstract void engineReset();
+    method protected abstract void engineUpdate(byte);
+    method protected abstract void engineUpdate(byte[], int, int);
+    method protected void engineUpdate(java.nio.ByteBuffer);
+  }
+
+  public class NoSuchPaddingException extends java.security.GeneralSecurityException {
+    ctor public NoSuchPaddingException();
+    ctor public NoSuchPaddingException(String);
+  }
+
+  public class NullCipher extends javax.crypto.Cipher {
+    ctor public NullCipher();
+  }
+
+  public class SealedObject implements java.io.Serializable {
+    ctor public SealedObject(java.io.Serializable, javax.crypto.Cipher) throws java.io.IOException, javax.crypto.IllegalBlockSizeException;
+    ctor protected SealedObject(javax.crypto.SealedObject);
+    method public final String getAlgorithm();
+    method public final Object getObject(java.security.Key) throws java.lang.ClassNotFoundException, java.io.IOException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException;
+    method public final Object getObject(javax.crypto.Cipher) throws javax.crypto.BadPaddingException, java.lang.ClassNotFoundException, java.io.IOException, javax.crypto.IllegalBlockSizeException;
+    method public final Object getObject(java.security.Key, String) throws java.lang.ClassNotFoundException, java.io.IOException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    field protected byte[] encodedParams;
+  }
+
+  public interface SecretKey extends java.security.Key javax.security.auth.Destroyable {
+    field public static final long serialVersionUID = -4795878709595146952L; // 0xbd719db928b8f538L
+  }
+
+  public class SecretKeyFactory {
+    ctor protected SecretKeyFactory(javax.crypto.SecretKeyFactorySpi, java.security.Provider, String);
+    method public final javax.crypto.SecretKey generateSecret(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method public final String getAlgorithm();
+    method public static final javax.crypto.SecretKeyFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.crypto.SecretKeyFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.crypto.SecretKeyFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.spec.KeySpec getKeySpec(javax.crypto.SecretKey, Class<?>) throws java.security.spec.InvalidKeySpecException;
+    method public final java.security.Provider getProvider();
+    method public final javax.crypto.SecretKey translateKey(javax.crypto.SecretKey) throws java.security.InvalidKeyException;
+  }
+
+  public abstract class SecretKeyFactorySpi {
+    ctor public SecretKeyFactorySpi();
+    method protected abstract javax.crypto.SecretKey engineGenerateSecret(java.security.spec.KeySpec) throws java.security.spec.InvalidKeySpecException;
+    method protected abstract java.security.spec.KeySpec engineGetKeySpec(javax.crypto.SecretKey, Class<?>) throws java.security.spec.InvalidKeySpecException;
+    method protected abstract javax.crypto.SecretKey engineTranslateKey(javax.crypto.SecretKey) throws java.security.InvalidKeyException;
+  }
+
+  public class ShortBufferException extends java.security.GeneralSecurityException {
+    ctor public ShortBufferException();
+    ctor public ShortBufferException(String);
+  }
+
+}
+
+package javax.crypto.interfaces {
+
+  public interface DHKey {
+    method public javax.crypto.spec.DHParameterSpec getParams();
+  }
+
+  public interface DHPrivateKey extends javax.crypto.interfaces.DHKey java.security.PrivateKey {
+    method public java.math.BigInteger getX();
+    field public static final long serialVersionUID = 2211791113380396553L; // 0x1eb1dc4c8e677e09L
+  }
+
+  public interface DHPublicKey extends javax.crypto.interfaces.DHKey java.security.PublicKey {
+    method public java.math.BigInteger getY();
+    field public static final long serialVersionUID = -6628103563352519193L; // 0xa4043eed23df4de7L
+  }
+
+  public interface PBEKey extends javax.crypto.SecretKey {
+    method public int getIterationCount();
+    method public char[] getPassword();
+    method public byte[] getSalt();
+    field public static final long serialVersionUID = -1430015993304333921L; // 0xec279007d7f7c19fL
+  }
+
+}
+
+package javax.crypto.spec {
+
+  public class DESKeySpec implements java.security.spec.KeySpec {
+    ctor public DESKeySpec(byte[]) throws java.security.InvalidKeyException;
+    ctor public DESKeySpec(byte[], int) throws java.security.InvalidKeyException;
+    method public byte[] getKey();
+    method public static boolean isParityAdjusted(byte[], int) throws java.security.InvalidKeyException;
+    method public static boolean isWeak(byte[], int) throws java.security.InvalidKeyException;
+    field public static final int DES_KEY_LEN = 8; // 0x8
+  }
+
+  public class DESedeKeySpec implements java.security.spec.KeySpec {
+    ctor public DESedeKeySpec(byte[]) throws java.security.InvalidKeyException;
+    ctor public DESedeKeySpec(byte[], int) throws java.security.InvalidKeyException;
+    method public byte[] getKey();
+    method public static boolean isParityAdjusted(byte[], int) throws java.security.InvalidKeyException;
+    field public static final int DES_EDE_KEY_LEN = 24; // 0x18
+  }
+
+  public class DHGenParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public DHGenParameterSpec(int, int);
+    method public int getExponentSize();
+    method public int getPrimeSize();
+  }
+
+  public class DHParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public DHParameterSpec(java.math.BigInteger, java.math.BigInteger);
+    ctor public DHParameterSpec(java.math.BigInteger, java.math.BigInteger, int);
+    method public java.math.BigInteger getG();
+    method public int getL();
+    method public java.math.BigInteger getP();
+  }
+
+  public class DHPrivateKeySpec implements java.security.spec.KeySpec {
+    ctor public DHPrivateKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getX();
+  }
+
+  public class DHPublicKeySpec implements java.security.spec.KeySpec {
+    ctor public DHPublicKeySpec(java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public java.math.BigInteger getG();
+    method public java.math.BigInteger getP();
+    method public java.math.BigInteger getY();
+  }
+
+  public class GCMParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public GCMParameterSpec(int, byte[]);
+    ctor public GCMParameterSpec(int, byte[], int, int);
+    method public byte[] getIV();
+    method public int getTLen();
+  }
+
+  public class IvParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public IvParameterSpec(byte[]);
+    ctor public IvParameterSpec(byte[], int, int);
+    method public byte[] getIV();
+  }
+
+  public class OAEPParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public OAEPParameterSpec(String, String, java.security.spec.AlgorithmParameterSpec, javax.crypto.spec.PSource);
+    method public String getDigestAlgorithm();
+    method public String getMGFAlgorithm();
+    method public java.security.spec.AlgorithmParameterSpec getMGFParameters();
+    method public javax.crypto.spec.PSource getPSource();
+    field public static final javax.crypto.spec.OAEPParameterSpec DEFAULT;
+  }
+
+  public class PBEKeySpec implements java.security.spec.KeySpec {
+    ctor public PBEKeySpec(char[]);
+    ctor public PBEKeySpec(char[], byte[], int, int);
+    ctor public PBEKeySpec(char[], byte[], int);
+    method public final void clearPassword();
+    method public final int getIterationCount();
+    method public final int getKeyLength();
+    method public final char[] getPassword();
+    method public final byte[] getSalt();
+  }
+
+  public class PBEParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public PBEParameterSpec(byte[], int);
+    ctor public PBEParameterSpec(byte[], int, java.security.spec.AlgorithmParameterSpec);
+    method public int getIterationCount();
+    method public java.security.spec.AlgorithmParameterSpec getParameterSpec();
+    method public byte[] getSalt();
+  }
+
+  public class PSource {
+    ctor protected PSource(String);
+    method public String getAlgorithm();
+  }
+
+  public static final class PSource.PSpecified extends javax.crypto.spec.PSource {
+    ctor public PSource.PSpecified(byte[]);
+    method public byte[] getValue();
+    field public static final javax.crypto.spec.PSource.PSpecified DEFAULT;
+  }
+
+  public class RC2ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public RC2ParameterSpec(int);
+    ctor public RC2ParameterSpec(int, byte[]);
+    ctor public RC2ParameterSpec(int, byte[], int);
+    method public int getEffectiveKeyBits();
+    method public byte[] getIV();
+  }
+
+  public class RC5ParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    ctor public RC5ParameterSpec(int, int, int);
+    ctor public RC5ParameterSpec(int, int, int, byte[]);
+    ctor public RC5ParameterSpec(int, int, int, byte[], int);
+    method public byte[] getIV();
+    method public int getRounds();
+    method public int getVersion();
+    method public int getWordSize();
+  }
+
+  public class SecretKeySpec implements java.security.spec.KeySpec javax.crypto.SecretKey {
+    ctor public SecretKeySpec(byte[], String);
+    ctor public SecretKeySpec(byte[], int, int, String);
+    method public String getAlgorithm();
+    method public byte[] getEncoded();
+    method public String getFormat();
+  }
+
+}
+
+package javax.net {
+
+  public abstract class ServerSocketFactory {
+    ctor protected ServerSocketFactory();
+    method public java.net.ServerSocket createServerSocket() throws java.io.IOException;
+    method public abstract java.net.ServerSocket createServerSocket(int) throws java.io.IOException;
+    method public abstract java.net.ServerSocket createServerSocket(int, int) throws java.io.IOException;
+    method public abstract java.net.ServerSocket createServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
+    method public static javax.net.ServerSocketFactory getDefault();
+  }
+
+  public abstract class SocketFactory {
+    ctor protected SocketFactory();
+    method public java.net.Socket createSocket() throws java.io.IOException;
+    method public abstract java.net.Socket createSocket(String, int) throws java.io.IOException, java.net.UnknownHostException;
+    method public abstract java.net.Socket createSocket(String, int, java.net.InetAddress, int) throws java.io.IOException, java.net.UnknownHostException;
+    method public abstract java.net.Socket createSocket(java.net.InetAddress, int) throws java.io.IOException;
+    method public abstract java.net.Socket createSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
+    method public static javax.net.SocketFactory getDefault();
+  }
+
+}
+
+package javax.net.ssl {
+
+  public class CertPathTrustManagerParameters implements javax.net.ssl.ManagerFactoryParameters {
+    ctor public CertPathTrustManagerParameters(java.security.cert.CertPathParameters);
+    method public java.security.cert.CertPathParameters getParameters();
+  }
+
+  public abstract class ExtendedSSLSession implements javax.net.ssl.SSLSession {
+    ctor public ExtendedSSLSession();
+    method public abstract String[] getLocalSupportedSignatureAlgorithms();
+    method public abstract String[] getPeerSupportedSignatureAlgorithms();
+    method public java.util.List<javax.net.ssl.SNIServerName> getRequestedServerNames();
+  }
+
+  public class HandshakeCompletedEvent extends java.util.EventObject {
+    ctor public HandshakeCompletedEvent(javax.net.ssl.SSLSocket, javax.net.ssl.SSLSession);
+    method public String getCipherSuite();
+    method public java.security.cert.Certificate[] getLocalCertificates();
+    method public java.security.Principal getLocalPrincipal();
+    method public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public java.security.cert.Certificate[] getPeerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public javax.net.ssl.SSLSession getSession();
+    method public javax.net.ssl.SSLSocket getSocket();
+  }
+
+  public interface HandshakeCompletedListener extends java.util.EventListener {
+    method public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent);
+  }
+
+  public interface HostnameVerifier {
+    method public boolean verify(String, javax.net.ssl.SSLSession);
+  }
+
+  public abstract class HttpsURLConnection extends java.net.HttpURLConnection {
+    ctor protected HttpsURLConnection(java.net.URL);
+    method public abstract String getCipherSuite();
+    method public static javax.net.ssl.HostnameVerifier getDefaultHostnameVerifier();
+    method public static javax.net.ssl.SSLSocketFactory getDefaultSSLSocketFactory();
+    method public javax.net.ssl.HostnameVerifier getHostnameVerifier();
+    method public abstract java.security.cert.Certificate[] getLocalCertificates();
+    method public java.security.Principal getLocalPrincipal();
+    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public javax.net.ssl.SSLSocketFactory getSSLSocketFactory();
+    method public abstract java.security.cert.Certificate[] getServerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public static void setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier);
+    method public static void setDefaultSSLSocketFactory(javax.net.ssl.SSLSocketFactory);
+    method public void setHostnameVerifier(javax.net.ssl.HostnameVerifier);
+    method public void setSSLSocketFactory(javax.net.ssl.SSLSocketFactory);
+    field protected javax.net.ssl.HostnameVerifier hostnameVerifier;
+  }
+
+  public interface KeyManager {
+  }
+
+  public class KeyManagerFactory {
+    ctor protected KeyManagerFactory(javax.net.ssl.KeyManagerFactorySpi, java.security.Provider, String);
+    method public final String getAlgorithm();
+    method public static final String getDefaultAlgorithm();
+    method public static final javax.net.ssl.KeyManagerFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.net.ssl.KeyManagerFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.net.ssl.KeyManagerFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final javax.net.ssl.KeyManager[] getKeyManagers();
+    method public final java.security.Provider getProvider();
+    method public final void init(java.security.KeyStore, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
+    method public final void init(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public abstract class KeyManagerFactorySpi {
+    ctor public KeyManagerFactorySpi();
+    method protected abstract javax.net.ssl.KeyManager[] engineGetKeyManagers();
+    method protected abstract void engineInit(java.security.KeyStore, char[]) throws java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException;
+    method protected abstract void engineInit(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public class KeyStoreBuilderParameters implements javax.net.ssl.ManagerFactoryParameters {
+    ctor public KeyStoreBuilderParameters(java.security.KeyStore.Builder);
+    ctor public KeyStoreBuilderParameters(java.util.List<java.security.KeyStore.Builder>);
+    method public java.util.List<java.security.KeyStore.Builder> getParameters();
+  }
+
+  public interface ManagerFactoryParameters {
+  }
+
+  public final class SNIHostName extends javax.net.ssl.SNIServerName {
+    ctor public SNIHostName(String);
+    ctor public SNIHostName(byte[]);
+    method public static javax.net.ssl.SNIMatcher createSNIMatcher(String);
+    method public String getAsciiName();
+  }
+
+  public abstract class SNIMatcher {
+    ctor protected SNIMatcher(int);
+    method public final int getType();
+    method public abstract boolean matches(javax.net.ssl.SNIServerName);
+  }
+
+  public abstract class SNIServerName {
+    ctor protected SNIServerName(int, byte[]);
+    method public final byte[] getEncoded();
+    method public final int getType();
+  }
+
+  public class SSLContext {
+    ctor protected SSLContext(javax.net.ssl.SSLContextSpi, java.security.Provider, String);
+    method public final javax.net.ssl.SSLEngine createSSLEngine();
+    method public final javax.net.ssl.SSLEngine createSSLEngine(String, int);
+    method public final javax.net.ssl.SSLSessionContext getClientSessionContext();
+    method public static javax.net.ssl.SSLContext getDefault() throws java.security.NoSuchAlgorithmException;
+    method public final javax.net.ssl.SSLParameters getDefaultSSLParameters();
+    method public static javax.net.ssl.SSLContext getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static javax.net.ssl.SSLContext getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static javax.net.ssl.SSLContext getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final String getProtocol();
+    method public final java.security.Provider getProvider();
+    method public final javax.net.ssl.SSLSessionContext getServerSessionContext();
+    method public final javax.net.ssl.SSLServerSocketFactory getServerSocketFactory();
+    method public final javax.net.ssl.SSLSocketFactory getSocketFactory();
+    method public final javax.net.ssl.SSLParameters getSupportedSSLParameters();
+    method public final void init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) throws java.security.KeyManagementException;
+    method public static void setDefault(javax.net.ssl.SSLContext);
+  }
+
+  public abstract class SSLContextSpi {
+    ctor public SSLContextSpi();
+    method protected abstract javax.net.ssl.SSLEngine engineCreateSSLEngine();
+    method protected abstract javax.net.ssl.SSLEngine engineCreateSSLEngine(String, int);
+    method protected abstract javax.net.ssl.SSLSessionContext engineGetClientSessionContext();
+    method protected javax.net.ssl.SSLParameters engineGetDefaultSSLParameters();
+    method protected abstract javax.net.ssl.SSLSessionContext engineGetServerSessionContext();
+    method protected abstract javax.net.ssl.SSLServerSocketFactory engineGetServerSocketFactory();
+    method protected abstract javax.net.ssl.SSLSocketFactory engineGetSocketFactory();
+    method protected javax.net.ssl.SSLParameters engineGetSupportedSSLParameters();
+    method protected abstract void engineInit(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) throws java.security.KeyManagementException;
+  }
+
+  public abstract class SSLEngine {
+    ctor protected SSLEngine();
+    ctor protected SSLEngine(String, int);
+    method public abstract void beginHandshake() throws javax.net.ssl.SSLException;
+    method public abstract void closeInbound() throws javax.net.ssl.SSLException;
+    method public abstract void closeOutbound();
+    method public String getApplicationProtocol();
+    method public abstract Runnable getDelegatedTask();
+    method public abstract boolean getEnableSessionCreation();
+    method public abstract String[] getEnabledCipherSuites();
+    method public abstract String[] getEnabledProtocols();
+    method public String getHandshakeApplicationProtocol();
+    method public java.util.function.BiFunction<javax.net.ssl.SSLEngine,java.util.List<java.lang.String>,java.lang.String> getHandshakeApplicationProtocolSelector();
+    method public javax.net.ssl.SSLSession getHandshakeSession();
+    method public abstract javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus();
+    method public abstract boolean getNeedClientAuth();
+    method public String getPeerHost();
+    method public int getPeerPort();
+    method public javax.net.ssl.SSLParameters getSSLParameters();
+    method public abstract javax.net.ssl.SSLSession getSession();
+    method public abstract String[] getSupportedCipherSuites();
+    method public abstract String[] getSupportedProtocols();
+    method public abstract boolean getUseClientMode();
+    method public abstract boolean getWantClientAuth();
+    method public abstract boolean isInboundDone();
+    method public abstract boolean isOutboundDone();
+    method public abstract void setEnableSessionCreation(boolean);
+    method public abstract void setEnabledCipherSuites(String[]);
+    method public abstract void setEnabledProtocols(String[]);
+    method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLEngine,java.util.List<java.lang.String>,java.lang.String>);
+    method public abstract void setNeedClientAuth(boolean);
+    method public void setSSLParameters(javax.net.ssl.SSLParameters);
+    method public abstract void setUseClientMode(boolean);
+    method public abstract void setWantClientAuth(boolean);
+    method public javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
+    method public javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer[]) throws javax.net.ssl.SSLException;
+    method public abstract javax.net.ssl.SSLEngineResult unwrap(java.nio.ByteBuffer, java.nio.ByteBuffer[], int, int) throws javax.net.ssl.SSLException;
+    method public javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
+    method public javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer[], java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
+    method public abstract javax.net.ssl.SSLEngineResult wrap(java.nio.ByteBuffer[], int, int, java.nio.ByteBuffer) throws javax.net.ssl.SSLException;
+  }
+
+  public class SSLEngineResult {
+    ctor public SSLEngineResult(javax.net.ssl.SSLEngineResult.Status, javax.net.ssl.SSLEngineResult.HandshakeStatus, int, int);
+    method public final int bytesConsumed();
+    method public final int bytesProduced();
+    method public final javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus();
+    method public final javax.net.ssl.SSLEngineResult.Status getStatus();
+  }
+
+  public enum SSLEngineResult.HandshakeStatus {
+    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus FINISHED;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_TASK;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_UNWRAP;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NEED_WRAP;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.HandshakeStatus NOT_HANDSHAKING;
+  }
+
+  public enum SSLEngineResult.Status {
+    enum_constant public static final javax.net.ssl.SSLEngineResult.Status BUFFER_OVERFLOW;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.Status BUFFER_UNDERFLOW;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.Status CLOSED;
+    enum_constant public static final javax.net.ssl.SSLEngineResult.Status OK;
+  }
+
+  public class SSLException extends java.io.IOException {
+    ctor public SSLException(String);
+    ctor public SSLException(String, Throwable);
+    ctor public SSLException(Throwable);
+  }
+
+  public class SSLHandshakeException extends javax.net.ssl.SSLException {
+    ctor public SSLHandshakeException(String);
+  }
+
+  public class SSLKeyException extends javax.net.ssl.SSLException {
+    ctor public SSLKeyException(String);
+  }
+
+  public class SSLParameters {
+    ctor public SSLParameters();
+    ctor public SSLParameters(String[]);
+    ctor public SSLParameters(String[], String[]);
+    method public java.security.AlgorithmConstraints getAlgorithmConstraints();
+    method public String[] getApplicationProtocols();
+    method public String[] getCipherSuites();
+    method public String getEndpointIdentificationAlgorithm();
+    method public boolean getNeedClientAuth();
+    method public String[] getProtocols();
+    method public final java.util.Collection<javax.net.ssl.SNIMatcher> getSNIMatchers();
+    method public final java.util.List<javax.net.ssl.SNIServerName> getServerNames();
+    method public final boolean getUseCipherSuitesOrder();
+    method public boolean getWantClientAuth();
+    method public void setAlgorithmConstraints(java.security.AlgorithmConstraints);
+    method public void setApplicationProtocols(String[]);
+    method public void setCipherSuites(String[]);
+    method public void setEndpointIdentificationAlgorithm(String);
+    method public void setNeedClientAuth(boolean);
+    method public void setProtocols(String[]);
+    method public final void setSNIMatchers(java.util.Collection<javax.net.ssl.SNIMatcher>);
+    method public final void setServerNames(java.util.List<javax.net.ssl.SNIServerName>);
+    method public final void setUseCipherSuitesOrder(boolean);
+    method public void setWantClientAuth(boolean);
+  }
+
+  public class SSLPeerUnverifiedException extends javax.net.ssl.SSLException {
+    ctor public SSLPeerUnverifiedException(String);
+  }
+
+  public final class SSLPermission extends java.security.BasicPermission {
+    ctor public SSLPermission(String);
+    ctor public SSLPermission(String, String);
+  }
+
+  public class SSLProtocolException extends javax.net.ssl.SSLException {
+    ctor public SSLProtocolException(String);
+  }
+
+  public abstract class SSLServerSocket extends java.net.ServerSocket {
+    ctor protected SSLServerSocket() throws java.io.IOException;
+    ctor protected SSLServerSocket(int) throws java.io.IOException;
+    ctor protected SSLServerSocket(int, int) throws java.io.IOException;
+    ctor protected SSLServerSocket(int, int, java.net.InetAddress) throws java.io.IOException;
+    method public abstract boolean getEnableSessionCreation();
+    method public abstract String[] getEnabledCipherSuites();
+    method public abstract String[] getEnabledProtocols();
+    method public abstract boolean getNeedClientAuth();
+    method public javax.net.ssl.SSLParameters getSSLParameters();
+    method public abstract String[] getSupportedCipherSuites();
+    method public abstract String[] getSupportedProtocols();
+    method public abstract boolean getUseClientMode();
+    method public abstract boolean getWantClientAuth();
+    method public abstract void setEnableSessionCreation(boolean);
+    method public abstract void setEnabledCipherSuites(String[]);
+    method public abstract void setEnabledProtocols(String[]);
+    method public abstract void setNeedClientAuth(boolean);
+    method public void setSSLParameters(javax.net.ssl.SSLParameters);
+    method public abstract void setUseClientMode(boolean);
+    method public abstract void setWantClientAuth(boolean);
+  }
+
+  public abstract class SSLServerSocketFactory extends javax.net.ServerSocketFactory {
+    ctor protected SSLServerSocketFactory();
+    method public static javax.net.ServerSocketFactory getDefault();
+    method public abstract String[] getDefaultCipherSuites();
+    method public abstract String[] getSupportedCipherSuites();
+  }
+
+  public interface SSLSession {
+    method public int getApplicationBufferSize();
+    method public String getCipherSuite();
+    method public long getCreationTime();
+    method public byte[] getId();
+    method public long getLastAccessedTime();
+    method public java.security.cert.Certificate[] getLocalCertificates();
+    method public java.security.Principal getLocalPrincipal();
+    method public int getPacketBufferSize();
+    method public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public java.security.cert.Certificate[] getPeerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public String getPeerHost();
+    method public int getPeerPort();
+    method public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException;
+    method public String getProtocol();
+    method public javax.net.ssl.SSLSessionContext getSessionContext();
+    method public Object getValue(String);
+    method public String[] getValueNames();
+    method public void invalidate();
+    method public boolean isValid();
+    method public void putValue(String, Object);
+    method public void removeValue(String);
+  }
+
+  public class SSLSessionBindingEvent extends java.util.EventObject {
+    ctor public SSLSessionBindingEvent(javax.net.ssl.SSLSession, String);
+    method public String getName();
+    method public javax.net.ssl.SSLSession getSession();
+  }
+
+  public interface SSLSessionBindingListener extends java.util.EventListener {
+    method public void valueBound(javax.net.ssl.SSLSessionBindingEvent);
+    method public void valueUnbound(javax.net.ssl.SSLSessionBindingEvent);
+  }
+
+  public interface SSLSessionContext {
+    method public java.util.Enumeration<byte[]> getIds();
+    method public javax.net.ssl.SSLSession getSession(byte[]);
+    method public int getSessionCacheSize();
+    method public int getSessionTimeout();
+    method public void setSessionCacheSize(int) throws java.lang.IllegalArgumentException;
+    method public void setSessionTimeout(int) throws java.lang.IllegalArgumentException;
+  }
+
+  public abstract class SSLSocket extends java.net.Socket {
+    ctor protected SSLSocket();
+    ctor protected SSLSocket(String, int) throws java.io.IOException, java.net.UnknownHostException;
+    ctor protected SSLSocket(java.net.InetAddress, int) throws java.io.IOException;
+    ctor protected SSLSocket(String, int, java.net.InetAddress, int) throws java.io.IOException, java.net.UnknownHostException;
+    ctor protected SSLSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException;
+    method public abstract void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
+    method public String getApplicationProtocol();
+    method public abstract boolean getEnableSessionCreation();
+    method public abstract String[] getEnabledCipherSuites();
+    method public abstract String[] getEnabledProtocols();
+    method public String getHandshakeApplicationProtocol();
+    method public java.util.function.BiFunction<javax.net.ssl.SSLSocket,java.util.List<java.lang.String>,java.lang.String> getHandshakeApplicationProtocolSelector();
+    method public javax.net.ssl.SSLSession getHandshakeSession();
+    method public abstract boolean getNeedClientAuth();
+    method public javax.net.ssl.SSLParameters getSSLParameters();
+    method public abstract javax.net.ssl.SSLSession getSession();
+    method public abstract String[] getSupportedCipherSuites();
+    method public abstract String[] getSupportedProtocols();
+    method public abstract boolean getUseClientMode();
+    method public abstract boolean getWantClientAuth();
+    method public abstract void removeHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener);
+    method public abstract void setEnableSessionCreation(boolean);
+    method public abstract void setEnabledCipherSuites(String[]);
+    method public abstract void setEnabledProtocols(String[]);
+    method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLSocket,java.util.List<java.lang.String>,java.lang.String>);
+    method public abstract void setNeedClientAuth(boolean);
+    method public void setSSLParameters(javax.net.ssl.SSLParameters);
+    method public abstract void setUseClientMode(boolean);
+    method public abstract void setWantClientAuth(boolean);
+    method public abstract void startHandshake() throws java.io.IOException;
+  }
+
+  public abstract class SSLSocketFactory extends javax.net.SocketFactory {
+    ctor public SSLSocketFactory();
+    method public abstract java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException;
+    method public static javax.net.SocketFactory getDefault();
+    method public abstract String[] getDefaultCipherSuites();
+    method public abstract String[] getSupportedCipherSuites();
+  }
+
+  public final class StandardConstants {
+    field public static final int SNI_HOST_NAME = 0; // 0x0
+  }
+
+  public interface TrustManager {
+  }
+
+  public class TrustManagerFactory {
+    ctor protected TrustManagerFactory(javax.net.ssl.TrustManagerFactorySpi, java.security.Provider, String);
+    method public final String getAlgorithm();
+    method public static final String getDefaultAlgorithm();
+    method public static final javax.net.ssl.TrustManagerFactory getInstance(String) throws java.security.NoSuchAlgorithmException;
+    method public static final javax.net.ssl.TrustManagerFactory getInstance(String, String) throws java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException;
+    method public static final javax.net.ssl.TrustManagerFactory getInstance(String, java.security.Provider) throws java.security.NoSuchAlgorithmException;
+    method public final java.security.Provider getProvider();
+    method public final javax.net.ssl.TrustManager[] getTrustManagers();
+    method public final void init(java.security.KeyStore) throws java.security.KeyStoreException;
+    method public final void init(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public abstract class TrustManagerFactorySpi {
+    ctor public TrustManagerFactorySpi();
+    method protected abstract javax.net.ssl.TrustManager[] engineGetTrustManagers();
+    method protected abstract void engineInit(java.security.KeyStore) throws java.security.KeyStoreException;
+    method protected abstract void engineInit(javax.net.ssl.ManagerFactoryParameters) throws java.security.InvalidAlgorithmParameterException;
+  }
+
+  public abstract class X509ExtendedKeyManager implements javax.net.ssl.X509KeyManager {
+    ctor protected X509ExtendedKeyManager();
+    method public String chooseEngineClientAlias(String[], java.security.Principal[], javax.net.ssl.SSLEngine);
+    method public String chooseEngineServerAlias(String, java.security.Principal[], javax.net.ssl.SSLEngine);
+  }
+
+  public abstract class X509ExtendedTrustManager implements javax.net.ssl.X509TrustManager {
+    ctor public X509ExtendedTrustManager();
+    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
+    method public abstract void checkClientTrusted(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
+    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], String, java.net.Socket) throws java.security.cert.CertificateException;
+    method public abstract void checkServerTrusted(java.security.cert.X509Certificate[], String, javax.net.ssl.SSLEngine) throws java.security.cert.CertificateException;
+  }
+
+  public interface X509KeyManager extends javax.net.ssl.KeyManager {
+    method public String chooseClientAlias(String[], java.security.Principal[], java.net.Socket);
+    method public String chooseServerAlias(String, java.security.Principal[], java.net.Socket);
+    method public java.security.cert.X509Certificate[] getCertificateChain(String);
+    method public String[] getClientAliases(String, java.security.Principal[]);
+    method public java.security.PrivateKey getPrivateKey(String);
+    method public String[] getServerAliases(String, java.security.Principal[]);
+  }
+
+  public interface X509TrustManager extends javax.net.ssl.TrustManager {
+    method public void checkClientTrusted(java.security.cert.X509Certificate[], String) throws java.security.cert.CertificateException;
+    method public void checkServerTrusted(java.security.cert.X509Certificate[], String) throws java.security.cert.CertificateException;
+    method public java.security.cert.X509Certificate[] getAcceptedIssuers();
+  }
+
+}
+
+package javax.security.auth {
+
+  public final class AuthPermission extends java.security.BasicPermission {
+    ctor public AuthPermission(String);
+    ctor public AuthPermission(String, String);
+  }
+
+  public class DestroyFailedException extends java.lang.Exception {
+    ctor public DestroyFailedException();
+    ctor public DestroyFailedException(String);
+  }
+
+  public interface Destroyable {
+    method public default void destroy() throws javax.security.auth.DestroyFailedException;
+    method public default boolean isDestroyed();
+  }
+
+  public final class PrivateCredentialPermission extends java.security.Permission {
+    ctor public PrivateCredentialPermission(String, String);
+    method public String getActions();
+    method public String getCredentialClass();
+    method public String[][] getPrincipals();
+    method public boolean implies(java.security.Permission);
+  }
+
+  public final class Subject implements java.io.Serializable {
+    ctor public Subject();
+    ctor public Subject(boolean, java.util.Set<? extends java.security.Principal>, java.util.Set<?>, java.util.Set<?>);
+    method public static <T> T doAs(javax.security.auth.Subject, java.security.PrivilegedAction<T>);
+    method public static <T> T doAs(javax.security.auth.Subject, java.security.PrivilegedExceptionAction<T>) throws java.security.PrivilegedActionException;
+    method public static <T> T doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedAction<T>, java.security.AccessControlContext);
+    method public static <T> T doAsPrivileged(javax.security.auth.Subject, java.security.PrivilegedExceptionAction<T>, java.security.AccessControlContext) throws java.security.PrivilegedActionException;
+    method public java.util.Set<java.security.Principal> getPrincipals();
+    method public <T extends java.security.Principal> java.util.Set<T> getPrincipals(Class<T>);
+    method public java.util.Set<java.lang.Object> getPrivateCredentials();
+    method public <T> java.util.Set<T> getPrivateCredentials(Class<T>);
+    method public java.util.Set<java.lang.Object> getPublicCredentials();
+    method public <T> java.util.Set<T> getPublicCredentials(Class<T>);
+    method public static javax.security.auth.Subject getSubject(java.security.AccessControlContext);
+    method public boolean isReadOnly();
+    method public void setReadOnly();
+  }
+
+  public class SubjectDomainCombiner implements java.security.DomainCombiner {
+    ctor public SubjectDomainCombiner(javax.security.auth.Subject);
+    method public java.security.ProtectionDomain[] combine(java.security.ProtectionDomain[], java.security.ProtectionDomain[]);
+    method public javax.security.auth.Subject getSubject();
+  }
+
+}
+
+package javax.security.auth.callback {
+
+  public interface Callback {
+  }
+
+  public interface CallbackHandler {
+    method public void handle(javax.security.auth.callback.Callback[]) throws java.io.IOException, javax.security.auth.callback.UnsupportedCallbackException;
+  }
+
+  public class PasswordCallback implements javax.security.auth.callback.Callback java.io.Serializable {
+    ctor public PasswordCallback(String, boolean);
+    method public void clearPassword();
+    method public char[] getPassword();
+    method public String getPrompt();
+    method public boolean isEchoOn();
+    method public void setPassword(char[]);
+  }
+
+  public class UnsupportedCallbackException extends java.lang.Exception {
+    ctor public UnsupportedCallbackException(javax.security.auth.callback.Callback);
+    ctor public UnsupportedCallbackException(javax.security.auth.callback.Callback, String);
+    method public javax.security.auth.callback.Callback getCallback();
+  }
+
+}
+
+package javax.security.auth.login {
+
+  public class LoginException extends java.security.GeneralSecurityException {
+    ctor public LoginException();
+    ctor public LoginException(String);
+  }
+
+}
+
+package javax.security.auth.x500 {
+
+  public final class X500Principal implements java.security.Principal java.io.Serializable {
+    ctor public X500Principal(String);
+    ctor public X500Principal(String, java.util.Map<java.lang.String,java.lang.String>);
+    ctor public X500Principal(byte[]);
+    ctor public X500Principal(java.io.InputStream);
+    method public byte[] getEncoded();
+    method public String getName();
+    method public String getName(String);
+    method public String getName(String, java.util.Map<java.lang.String,java.lang.String>);
+    field public static final String CANONICAL = "CANONICAL";
+    field public static final String RFC1779 = "RFC1779";
+    field public static final String RFC2253 = "RFC2253";
+  }
+
+}
+
+package javax.security.cert {
+
+  public abstract class Certificate {
+    ctor public Certificate();
+    method public abstract byte[] getEncoded() throws javax.security.cert.CertificateEncodingException;
+    method public abstract java.security.PublicKey getPublicKey();
+    method public abstract String toString();
+    method public abstract void verify(java.security.PublicKey) throws javax.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+    method public abstract void verify(java.security.PublicKey, String) throws javax.security.cert.CertificateException, java.security.InvalidKeyException, java.security.NoSuchAlgorithmException, java.security.NoSuchProviderException, java.security.SignatureException;
+  }
+
+  public class CertificateEncodingException extends javax.security.cert.CertificateException {
+    ctor public CertificateEncodingException();
+    ctor public CertificateEncodingException(String);
+  }
+
+  public class CertificateException extends java.lang.Exception {
+    ctor public CertificateException();
+    ctor public CertificateException(String);
+  }
+
+  public class CertificateExpiredException extends javax.security.cert.CertificateException {
+    ctor public CertificateExpiredException();
+    ctor public CertificateExpiredException(String);
+  }
+
+  public class CertificateNotYetValidException extends javax.security.cert.CertificateException {
+    ctor public CertificateNotYetValidException();
+    ctor public CertificateNotYetValidException(String);
+  }
+
+  public class CertificateParsingException extends javax.security.cert.CertificateException {
+    ctor public CertificateParsingException();
+    ctor public CertificateParsingException(String);
+  }
+
+  public abstract class X509Certificate extends javax.security.cert.Certificate {
+    ctor public X509Certificate();
+    method public abstract void checkValidity() throws javax.security.cert.CertificateExpiredException, javax.security.cert.CertificateNotYetValidException;
+    method public abstract void checkValidity(java.util.Date) throws javax.security.cert.CertificateExpiredException, javax.security.cert.CertificateNotYetValidException;
+    method public static final javax.security.cert.X509Certificate getInstance(java.io.InputStream) throws javax.security.cert.CertificateException;
+    method public static final javax.security.cert.X509Certificate getInstance(byte[]) throws javax.security.cert.CertificateException;
+    method public abstract java.security.Principal getIssuerDN();
+    method public abstract java.util.Date getNotAfter();
+    method public abstract java.util.Date getNotBefore();
+    method public abstract java.math.BigInteger getSerialNumber();
+    method public abstract String getSigAlgName();
+    method public abstract String getSigAlgOID();
+    method public abstract byte[] getSigAlgParams();
+    method public abstract java.security.Principal getSubjectDN();
+    method public abstract int getVersion();
+  }
+
+}
+
+package javax.sql {
+
+  public interface CommonDataSource {
+    method public java.io.PrintWriter getLogWriter() throws java.sql.SQLException;
+    method public int getLoginTimeout() throws java.sql.SQLException;
+    method public java.util.logging.Logger getParentLogger() throws java.sql.SQLFeatureNotSupportedException;
+    method public void setLogWriter(java.io.PrintWriter) throws java.sql.SQLException;
+    method public void setLoginTimeout(int) throws java.sql.SQLException;
+  }
+
+  public class ConnectionEvent extends java.util.EventObject {
+    ctor public ConnectionEvent(javax.sql.PooledConnection);
+    ctor public ConnectionEvent(javax.sql.PooledConnection, java.sql.SQLException);
+    method public java.sql.SQLException getSQLException();
+  }
+
+  public interface ConnectionEventListener extends java.util.EventListener {
+    method public void connectionClosed(javax.sql.ConnectionEvent);
+    method public void connectionErrorOccurred(javax.sql.ConnectionEvent);
+  }
+
+  public interface ConnectionPoolDataSource extends javax.sql.CommonDataSource {
+    method public javax.sql.PooledConnection getPooledConnection() throws java.sql.SQLException;
+    method public javax.sql.PooledConnection getPooledConnection(String, String) throws java.sql.SQLException;
+  }
+
+  public interface DataSource extends javax.sql.CommonDataSource java.sql.Wrapper {
+    method public java.sql.Connection getConnection() throws java.sql.SQLException;
+    method public java.sql.Connection getConnection(String, String) throws java.sql.SQLException;
+  }
+
+  public interface PooledConnection {
+    method public void addConnectionEventListener(javax.sql.ConnectionEventListener);
+    method public void addStatementEventListener(javax.sql.StatementEventListener);
+    method public void close() throws java.sql.SQLException;
+    method public java.sql.Connection getConnection() throws java.sql.SQLException;
+    method public void removeConnectionEventListener(javax.sql.ConnectionEventListener);
+    method public void removeStatementEventListener(javax.sql.StatementEventListener);
+  }
+
+  public interface RowSet extends java.sql.ResultSet {
+    method public void addRowSetListener(javax.sql.RowSetListener);
+    method public void clearParameters() throws java.sql.SQLException;
+    method public void execute() throws java.sql.SQLException;
+    method public String getCommand();
+    method public String getDataSourceName();
+    method public boolean getEscapeProcessing() throws java.sql.SQLException;
+    method public int getMaxFieldSize() throws java.sql.SQLException;
+    method public int getMaxRows() throws java.sql.SQLException;
+    method public String getPassword();
+    method public int getQueryTimeout() throws java.sql.SQLException;
+    method public int getTransactionIsolation();
+    method public java.util.Map<java.lang.String,java.lang.Class<?>> getTypeMap() throws java.sql.SQLException;
+    method public String getUrl() throws java.sql.SQLException;
+    method public String getUsername();
+    method public boolean isReadOnly();
+    method public void removeRowSetListener(javax.sql.RowSetListener);
+    method public void setArray(int, java.sql.Array) throws java.sql.SQLException;
+    method public void setAsciiStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setAsciiStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setAsciiStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setAsciiStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBigDecimal(int, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void setBigDecimal(String, java.math.BigDecimal) throws java.sql.SQLException;
+    method public void setBinaryStream(int, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setBinaryStream(String, java.io.InputStream, int) throws java.sql.SQLException;
+    method public void setBinaryStream(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBinaryStream(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBlob(int, java.sql.Blob) throws java.sql.SQLException;
+    method public void setBlob(int, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBlob(int, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBlob(String, java.io.InputStream, long) throws java.sql.SQLException;
+    method public void setBlob(String, java.sql.Blob) throws java.sql.SQLException;
+    method public void setBlob(String, java.io.InputStream) throws java.sql.SQLException;
+    method public void setBoolean(int, boolean) throws java.sql.SQLException;
+    method public void setBoolean(String, boolean) throws java.sql.SQLException;
+    method public void setByte(int, byte) throws java.sql.SQLException;
+    method public void setByte(String, byte) throws java.sql.SQLException;
+    method public void setBytes(int, byte[]) throws java.sql.SQLException;
+    method public void setBytes(String, byte[]) throws java.sql.SQLException;
+    method public void setCharacterStream(int, java.io.Reader, int) throws java.sql.SQLException;
+    method public void setCharacterStream(String, java.io.Reader, int) throws java.sql.SQLException;
+    method public void setCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setClob(int, java.sql.Clob) throws java.sql.SQLException;
+    method public void setClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setClob(String, java.sql.Clob) throws java.sql.SQLException;
+    method public void setClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setCommand(String) throws java.sql.SQLException;
+    method public void setConcurrency(int) throws java.sql.SQLException;
+    method public void setDataSourceName(String) throws java.sql.SQLException;
+    method public void setDate(int, java.sql.Date) throws java.sql.SQLException;
+    method public void setDate(int, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
+    method public void setDate(String, java.sql.Date) throws java.sql.SQLException;
+    method public void setDate(String, java.sql.Date, java.util.Calendar) throws java.sql.SQLException;
+    method public void setDouble(int, double) throws java.sql.SQLException;
+    method public void setDouble(String, double) throws java.sql.SQLException;
+    method public void setEscapeProcessing(boolean) throws java.sql.SQLException;
+    method public void setFloat(int, float) throws java.sql.SQLException;
+    method public void setFloat(String, float) throws java.sql.SQLException;
+    method public void setInt(int, int) throws java.sql.SQLException;
+    method public void setInt(String, int) throws java.sql.SQLException;
+    method public void setLong(int, long) throws java.sql.SQLException;
+    method public void setLong(String, long) throws java.sql.SQLException;
+    method public void setMaxFieldSize(int) throws java.sql.SQLException;
+    method public void setMaxRows(int) throws java.sql.SQLException;
+    method public void setNCharacterStream(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setNCharacterStream(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNCharacterStream(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setNClob(String, java.sql.NClob) throws java.sql.SQLException;
+    method public void setNClob(String, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNClob(String, java.io.Reader) throws java.sql.SQLException;
+    method public void setNClob(int, java.io.Reader, long) throws java.sql.SQLException;
+    method public void setNClob(int, java.sql.NClob) throws java.sql.SQLException;
+    method public void setNClob(int, java.io.Reader) throws java.sql.SQLException;
+    method public void setNString(int, String) throws java.sql.SQLException;
+    method public void setNString(String, String) throws java.sql.SQLException;
+    method public void setNull(int, int) throws java.sql.SQLException;
+    method public void setNull(String, int) throws java.sql.SQLException;
+    method public void setNull(int, int, String) throws java.sql.SQLException;
+    method public void setNull(String, int, String) throws java.sql.SQLException;
+    method public void setObject(int, Object, int, int) throws java.sql.SQLException;
+    method public void setObject(String, Object, int, int) throws java.sql.SQLException;
+    method public void setObject(int, Object, int) throws java.sql.SQLException;
+    method public void setObject(String, Object, int) throws java.sql.SQLException;
+    method public void setObject(String, Object) throws java.sql.SQLException;
+    method public void setObject(int, Object) throws java.sql.SQLException;
+    method public void setPassword(String) throws java.sql.SQLException;
+    method public void setQueryTimeout(int) throws java.sql.SQLException;
+    method public void setReadOnly(boolean) throws java.sql.SQLException;
+    method public void setRef(int, java.sql.Ref) throws java.sql.SQLException;
+    method public void setRowId(int, java.sql.RowId) throws java.sql.SQLException;
+    method public void setRowId(String, java.sql.RowId) throws java.sql.SQLException;
+    method public void setSQLXML(int, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void setSQLXML(String, java.sql.SQLXML) throws java.sql.SQLException;
+    method public void setShort(int, short) throws java.sql.SQLException;
+    method public void setShort(String, short) throws java.sql.SQLException;
+    method public void setString(int, String) throws java.sql.SQLException;
+    method public void setString(String, String) throws java.sql.SQLException;
+    method public void setTime(int, java.sql.Time) throws java.sql.SQLException;
+    method public void setTime(int, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTime(String, java.sql.Time) throws java.sql.SQLException;
+    method public void setTime(String, java.sql.Time, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTimestamp(int, java.sql.Timestamp) throws java.sql.SQLException;
+    method public void setTimestamp(String, java.sql.Timestamp) throws java.sql.SQLException;
+    method public void setTimestamp(int, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTimestamp(String, java.sql.Timestamp, java.util.Calendar) throws java.sql.SQLException;
+    method public void setTransactionIsolation(int) throws java.sql.SQLException;
+    method public void setType(int) throws java.sql.SQLException;
+    method public void setTypeMap(java.util.Map<java.lang.String,java.lang.Class<?>>) throws java.sql.SQLException;
+    method public void setURL(int, java.net.URL) throws java.sql.SQLException;
+    method public void setUrl(String) throws java.sql.SQLException;
+    method public void setUsername(String) throws java.sql.SQLException;
+  }
+
+  public class RowSetEvent extends java.util.EventObject {
+    ctor public RowSetEvent(javax.sql.RowSet);
+  }
+
+  public interface RowSetInternal {
+    method public java.sql.Connection getConnection() throws java.sql.SQLException;
+    method public java.sql.ResultSet getOriginal() throws java.sql.SQLException;
+    method public java.sql.ResultSet getOriginalRow() throws java.sql.SQLException;
+    method public Object[] getParams() throws java.sql.SQLException;
+    method public void setMetaData(javax.sql.RowSetMetaData) throws java.sql.SQLException;
+  }
+
+  public interface RowSetListener extends java.util.EventListener {
+    method public void cursorMoved(javax.sql.RowSetEvent);
+    method public void rowChanged(javax.sql.RowSetEvent);
+    method public void rowSetChanged(javax.sql.RowSetEvent);
+  }
+
+  public interface RowSetMetaData extends java.sql.ResultSetMetaData {
+    method public void setAutoIncrement(int, boolean) throws java.sql.SQLException;
+    method public void setCaseSensitive(int, boolean) throws java.sql.SQLException;
+    method public void setCatalogName(int, String) throws java.sql.SQLException;
+    method public void setColumnCount(int) throws java.sql.SQLException;
+    method public void setColumnDisplaySize(int, int) throws java.sql.SQLException;
+    method public void setColumnLabel(int, String) throws java.sql.SQLException;
+    method public void setColumnName(int, String) throws java.sql.SQLException;
+    method public void setColumnType(int, int) throws java.sql.SQLException;
+    method public void setColumnTypeName(int, String) throws java.sql.SQLException;
+    method public void setCurrency(int, boolean) throws java.sql.SQLException;
+    method public void setNullable(int, int) throws java.sql.SQLException;
+    method public void setPrecision(int, int) throws java.sql.SQLException;
+    method public void setScale(int, int) throws java.sql.SQLException;
+    method public void setSchemaName(int, String) throws java.sql.SQLException;
+    method public void setSearchable(int, boolean) throws java.sql.SQLException;
+    method public void setSigned(int, boolean) throws java.sql.SQLException;
+    method public void setTableName(int, String) throws java.sql.SQLException;
+  }
+
+  public interface RowSetReader {
+    method public void readData(javax.sql.RowSetInternal) throws java.sql.SQLException;
+  }
+
+  public interface RowSetWriter {
+    method public boolean writeData(javax.sql.RowSetInternal) throws java.sql.SQLException;
+  }
+
+  public class StatementEvent extends java.util.EventObject {
+    ctor public StatementEvent(javax.sql.PooledConnection, java.sql.PreparedStatement);
+    ctor public StatementEvent(javax.sql.PooledConnection, java.sql.PreparedStatement, java.sql.SQLException);
+    method public java.sql.SQLException getSQLException();
+    method public java.sql.PreparedStatement getStatement();
+  }
+
+  public interface StatementEventListener extends java.util.EventListener {
+    method public void statementClosed(javax.sql.StatementEvent);
+    method public void statementErrorOccurred(javax.sql.StatementEvent);
+  }
+
+}
+
+package javax.xml {
+
+  public final class XMLConstants {
+    field public static final String DEFAULT_NS_PREFIX = "";
+    field public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing";
+    field public static final String NULL_NS_URI = "";
+    field public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0";
+    field public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = "http://www.w3.org/2001/XMLSchema-instance";
+    field public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema";
+    field public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes";
+    field public static final String XMLNS_ATTRIBUTE = "xmlns";
+    field public static final String XMLNS_ATTRIBUTE_NS_URI = "http://www.w3.org/2000/xmlns/";
+    field public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml";
+    field public static final String XML_NS_PREFIX = "xml";
+    field public static final String XML_NS_URI = "http://www.w3.org/XML/1998/namespace";
+  }
+
+}
+
+package javax.xml.datatype {
+
+  public class DatatypeConfigurationException extends java.lang.Exception {
+    ctor public DatatypeConfigurationException();
+    ctor public DatatypeConfigurationException(String);
+    ctor public DatatypeConfigurationException(String, Throwable);
+    ctor public DatatypeConfigurationException(Throwable);
+  }
+
+  public final class DatatypeConstants {
+    field public static final int APRIL = 4; // 0x4
+    field public static final int AUGUST = 8; // 0x8
+    field public static final javax.xml.namespace.QName DATE;
+    field public static final javax.xml.namespace.QName DATETIME;
+    field public static final javax.xml.datatype.DatatypeConstants.Field DAYS;
+    field public static final int DECEMBER = 12; // 0xc
+    field public static final javax.xml.namespace.QName DURATION;
+    field public static final javax.xml.namespace.QName DURATION_DAYTIME;
+    field public static final javax.xml.namespace.QName DURATION_YEARMONTH;
+    field public static final int EQUAL = 0; // 0x0
+    field public static final int FEBRUARY = 2; // 0x2
+    field public static final int FIELD_UNDEFINED = -2147483648; // 0x80000000
+    field public static final javax.xml.namespace.QName GDAY;
+    field public static final javax.xml.namespace.QName GMONTH;
+    field public static final javax.xml.namespace.QName GMONTHDAY;
+    field public static final int GREATER = 1; // 0x1
+    field public static final javax.xml.namespace.QName GYEAR;
+    field public static final javax.xml.namespace.QName GYEARMONTH;
+    field public static final javax.xml.datatype.DatatypeConstants.Field HOURS;
+    field public static final int INDETERMINATE = 2; // 0x2
+    field public static final int JANUARY = 1; // 0x1
+    field public static final int JULY = 7; // 0x7
+    field public static final int JUNE = 6; // 0x6
+    field public static final int LESSER = -1; // 0xffffffff
+    field public static final int MARCH = 3; // 0x3
+    field public static final int MAX_TIMEZONE_OFFSET = -840; // 0xfffffcb8
+    field public static final int MAY = 5; // 0x5
+    field public static final javax.xml.datatype.DatatypeConstants.Field MINUTES;
+    field public static final int MIN_TIMEZONE_OFFSET = 840; // 0x348
+    field public static final javax.xml.datatype.DatatypeConstants.Field MONTHS;
+    field public static final int NOVEMBER = 11; // 0xb
+    field public static final int OCTOBER = 10; // 0xa
+    field public static final javax.xml.datatype.DatatypeConstants.Field SECONDS;
+    field public static final int SEPTEMBER = 9; // 0x9
+    field public static final javax.xml.namespace.QName TIME;
+    field public static final javax.xml.datatype.DatatypeConstants.Field YEARS;
+  }
+
+  public static final class DatatypeConstants.Field {
+    method public int getId();
+  }
+
+  public abstract class DatatypeFactory {
+    ctor protected DatatypeFactory();
+    method public abstract javax.xml.datatype.Duration newDuration(String);
+    method public abstract javax.xml.datatype.Duration newDuration(long);
+    method public abstract javax.xml.datatype.Duration newDuration(boolean, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigDecimal);
+    method public javax.xml.datatype.Duration newDuration(boolean, int, int, int, int, int, int);
+    method public javax.xml.datatype.Duration newDurationDayTime(String);
+    method public javax.xml.datatype.Duration newDurationDayTime(long);
+    method public javax.xml.datatype.Duration newDurationDayTime(boolean, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger, java.math.BigInteger);
+    method public javax.xml.datatype.Duration newDurationDayTime(boolean, int, int, int, int);
+    method public javax.xml.datatype.Duration newDurationYearMonth(String);
+    method public javax.xml.datatype.Duration newDurationYearMonth(long);
+    method public javax.xml.datatype.Duration newDurationYearMonth(boolean, java.math.BigInteger, java.math.BigInteger);
+    method public javax.xml.datatype.Duration newDurationYearMonth(boolean, int, int);
+    method public static javax.xml.datatype.DatatypeFactory newInstance() throws javax.xml.datatype.DatatypeConfigurationException;
+    method public static javax.xml.datatype.DatatypeFactory newInstance(String, ClassLoader) throws javax.xml.datatype.DatatypeConfigurationException;
+    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar();
+    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(String);
+    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(java.util.GregorianCalendar);
+    method public abstract javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(java.math.BigInteger, int, int, int, int, int, java.math.BigDecimal, int);
+    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendar(int, int, int, int, int, int, int, int);
+    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarDate(int, int, int, int);
+    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, int);
+    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, java.math.BigDecimal, int);
+    method public javax.xml.datatype.XMLGregorianCalendar newXMLGregorianCalendarTime(int, int, int, int, int);
+    field public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS;
+    field public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory";
+  }
+
+  public abstract class Duration {
+    ctor public Duration();
+    method public abstract javax.xml.datatype.Duration add(javax.xml.datatype.Duration);
+    method public abstract void addTo(java.util.Calendar);
+    method public void addTo(java.util.Date);
+    method public abstract int compare(javax.xml.datatype.Duration);
+    method public int getDays();
+    method public abstract Number getField(javax.xml.datatype.DatatypeConstants.Field);
+    method public int getHours();
+    method public int getMinutes();
+    method public int getMonths();
+    method public int getSeconds();
+    method public abstract int getSign();
+    method public long getTimeInMillis(java.util.Calendar);
+    method public long getTimeInMillis(java.util.Date);
+    method public javax.xml.namespace.QName getXMLSchemaType();
+    method public int getYears();
+    method public abstract int hashCode();
+    method public boolean isLongerThan(javax.xml.datatype.Duration);
+    method public abstract boolean isSet(javax.xml.datatype.DatatypeConstants.Field);
+    method public boolean isShorterThan(javax.xml.datatype.Duration);
+    method public javax.xml.datatype.Duration multiply(int);
+    method public abstract javax.xml.datatype.Duration multiply(java.math.BigDecimal);
+    method public abstract javax.xml.datatype.Duration negate();
+    method public abstract javax.xml.datatype.Duration normalizeWith(java.util.Calendar);
+    method public javax.xml.datatype.Duration subtract(javax.xml.datatype.Duration);
+  }
+
+  public abstract class XMLGregorianCalendar implements java.lang.Cloneable {
+    ctor public XMLGregorianCalendar();
+    method public abstract void add(javax.xml.datatype.Duration);
+    method public abstract void clear();
+    method public abstract Object clone();
+    method public abstract int compare(javax.xml.datatype.XMLGregorianCalendar);
+    method public abstract int getDay();
+    method public abstract java.math.BigInteger getEon();
+    method public abstract java.math.BigInteger getEonAndYear();
+    method public abstract java.math.BigDecimal getFractionalSecond();
+    method public abstract int getHour();
+    method public int getMillisecond();
+    method public abstract int getMinute();
+    method public abstract int getMonth();
+    method public abstract int getSecond();
+    method public abstract java.util.TimeZone getTimeZone(int);
+    method public abstract int getTimezone();
+    method public abstract javax.xml.namespace.QName getXMLSchemaType();
+    method public abstract int getYear();
+    method public abstract boolean isValid();
+    method public abstract javax.xml.datatype.XMLGregorianCalendar normalize();
+    method public abstract void reset();
+    method public abstract void setDay(int);
+    method public abstract void setFractionalSecond(java.math.BigDecimal);
+    method public abstract void setHour(int);
+    method public abstract void setMillisecond(int);
+    method public abstract void setMinute(int);
+    method public abstract void setMonth(int);
+    method public abstract void setSecond(int);
+    method public void setTime(int, int, int);
+    method public void setTime(int, int, int, java.math.BigDecimal);
+    method public void setTime(int, int, int, int);
+    method public abstract void setTimezone(int);
+    method public abstract void setYear(java.math.BigInteger);
+    method public abstract void setYear(int);
+    method public abstract java.util.GregorianCalendar toGregorianCalendar();
+    method public abstract java.util.GregorianCalendar toGregorianCalendar(java.util.TimeZone, java.util.Locale, javax.xml.datatype.XMLGregorianCalendar);
+    method public abstract String toXMLFormat();
+  }
+
+}
+
+package javax.xml.namespace {
+
+  public interface NamespaceContext {
+    method public String getNamespaceURI(String);
+    method public String getPrefix(String);
+    method public java.util.Iterator getPrefixes(String);
+  }
+
+  public class QName implements java.io.Serializable {
+    ctor public QName(String, String);
+    ctor public QName(String, String, String);
+    ctor public QName(String);
+    method public final boolean equals(Object);
+    method public String getLocalPart();
+    method public String getNamespaceURI();
+    method public String getPrefix();
+    method public final int hashCode();
+    method public static javax.xml.namespace.QName valueOf(String);
+  }
+
+}
+
+package javax.xml.parsers {
+
+  public abstract class DocumentBuilder {
+    ctor protected DocumentBuilder();
+    method public abstract org.w3c.dom.DOMImplementation getDOMImplementation();
+    method public javax.xml.validation.Schema getSchema();
+    method public abstract boolean isNamespaceAware();
+    method public abstract boolean isValidating();
+    method public boolean isXIncludeAware();
+    method public abstract org.w3c.dom.Document newDocument();
+    method public org.w3c.dom.Document parse(java.io.InputStream) throws java.io.IOException, org.xml.sax.SAXException;
+    method public org.w3c.dom.Document parse(java.io.InputStream, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public org.w3c.dom.Document parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public org.w3c.dom.Document parse(java.io.File) throws java.io.IOException, org.xml.sax.SAXException;
+    method public abstract org.w3c.dom.Document parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void reset();
+    method public abstract void setEntityResolver(org.xml.sax.EntityResolver);
+    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
+  }
+
+  public abstract class DocumentBuilderFactory {
+    ctor protected DocumentBuilderFactory();
+    method public abstract Object getAttribute(String) throws java.lang.IllegalArgumentException;
+    method public abstract boolean getFeature(String) throws javax.xml.parsers.ParserConfigurationException;
+    method public javax.xml.validation.Schema getSchema();
+    method public boolean isCoalescing();
+    method public boolean isExpandEntityReferences();
+    method public boolean isIgnoringComments();
+    method public boolean isIgnoringElementContentWhitespace();
+    method public boolean isNamespaceAware();
+    method public boolean isValidating();
+    method public boolean isXIncludeAware();
+    method public abstract javax.xml.parsers.DocumentBuilder newDocumentBuilder() throws javax.xml.parsers.ParserConfigurationException;
+    method public static javax.xml.parsers.DocumentBuilderFactory newInstance();
+    method public static javax.xml.parsers.DocumentBuilderFactory newInstance(String, ClassLoader);
+    method public abstract void setAttribute(String, Object) throws java.lang.IllegalArgumentException;
+    method public void setCoalescing(boolean);
+    method public void setExpandEntityReferences(boolean);
+    method public abstract void setFeature(String, boolean) throws javax.xml.parsers.ParserConfigurationException;
+    method public void setIgnoringComments(boolean);
+    method public void setIgnoringElementContentWhitespace(boolean);
+    method public void setNamespaceAware(boolean);
+    method public void setSchema(javax.xml.validation.Schema);
+    method public void setValidating(boolean);
+    method public void setXIncludeAware(boolean);
+  }
+
+  public class FactoryConfigurationError extends java.lang.Error {
+    ctor public FactoryConfigurationError();
+    ctor public FactoryConfigurationError(String);
+    ctor public FactoryConfigurationError(Exception);
+    ctor public FactoryConfigurationError(Exception, String);
+    method public Exception getException();
+  }
+
+  public class ParserConfigurationException extends java.lang.Exception {
+    ctor public ParserConfigurationException();
+    ctor public ParserConfigurationException(String);
+  }
+
+  public abstract class SAXParser {
+    ctor protected SAXParser();
+    method public abstract org.xml.sax.Parser getParser() throws org.xml.sax.SAXException;
+    method public abstract Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public javax.xml.validation.Schema getSchema();
+    method public abstract org.xml.sax.XMLReader getXMLReader() throws org.xml.sax.SAXException;
+    method public abstract boolean isNamespaceAware();
+    method public abstract boolean isValidating();
+    method public boolean isXIncludeAware();
+    method public void parse(java.io.InputStream, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(java.io.InputStream, org.xml.sax.HandlerBase, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(java.io.InputStream, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(java.io.InputStream, org.xml.sax.helpers.DefaultHandler, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(String, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(String, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(java.io.File, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(java.io.File, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(org.xml.sax.InputSource, org.xml.sax.HandlerBase) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(org.xml.sax.InputSource, org.xml.sax.helpers.DefaultHandler) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void reset();
+    method public abstract void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+  }
+
+  public abstract class SAXParserFactory {
+    ctor protected SAXParserFactory();
+    method public abstract boolean getFeature(String) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public javax.xml.validation.Schema getSchema();
+    method public boolean isNamespaceAware();
+    method public boolean isValidating();
+    method public boolean isXIncludeAware();
+    method public static javax.xml.parsers.SAXParserFactory newInstance();
+    method public static javax.xml.parsers.SAXParserFactory newInstance(String, ClassLoader);
+    method public abstract javax.xml.parsers.SAXParser newSAXParser() throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException;
+    method public abstract void setFeature(String, boolean) throws javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setNamespaceAware(boolean);
+    method public void setSchema(javax.xml.validation.Schema);
+    method public void setValidating(boolean);
+    method public void setXIncludeAware(boolean);
+  }
+
+}
+
+package javax.xml.transform {
+
+  public interface ErrorListener {
+    method public void error(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
+    method public void fatalError(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
+    method public void warning(javax.xml.transform.TransformerException) throws javax.xml.transform.TransformerException;
+  }
+
+  public class OutputKeys {
+    field public static final String CDATA_SECTION_ELEMENTS = "cdata-section-elements";
+    field public static final String DOCTYPE_PUBLIC = "doctype-public";
+    field public static final String DOCTYPE_SYSTEM = "doctype-system";
+    field public static final String ENCODING = "encoding";
+    field public static final String INDENT = "indent";
+    field public static final String MEDIA_TYPE = "media-type";
+    field public static final String METHOD = "method";
+    field public static final String OMIT_XML_DECLARATION = "omit-xml-declaration";
+    field public static final String STANDALONE = "standalone";
+    field public static final String VERSION = "version";
+  }
+
+  public interface Result {
+    method public String getSystemId();
+    method public void setSystemId(String);
+    field public static final String PI_DISABLE_OUTPUT_ESCAPING = "javax.xml.transform.disable-output-escaping";
+    field public static final String PI_ENABLE_OUTPUT_ESCAPING = "javax.xml.transform.enable-output-escaping";
+  }
+
+  public interface Source {
+    method public String getSystemId();
+    method public void setSystemId(String);
+  }
+
+  public interface SourceLocator {
+    method public int getColumnNumber();
+    method public int getLineNumber();
+    method public String getPublicId();
+    method public String getSystemId();
+  }
+
+  public interface Templates {
+    method public java.util.Properties getOutputProperties();
+    method public javax.xml.transform.Transformer newTransformer() throws javax.xml.transform.TransformerConfigurationException;
+  }
+
+  public abstract class Transformer {
+    ctor protected Transformer();
+    method public abstract void clearParameters();
+    method public abstract javax.xml.transform.ErrorListener getErrorListener();
+    method public abstract java.util.Properties getOutputProperties();
+    method public abstract String getOutputProperty(String) throws java.lang.IllegalArgumentException;
+    method public abstract Object getParameter(String);
+    method public abstract javax.xml.transform.URIResolver getURIResolver();
+    method public void reset();
+    method public abstract void setErrorListener(javax.xml.transform.ErrorListener) throws java.lang.IllegalArgumentException;
+    method public abstract void setOutputProperties(java.util.Properties);
+    method public abstract void setOutputProperty(String, String) throws java.lang.IllegalArgumentException;
+    method public abstract void setParameter(String, Object);
+    method public abstract void setURIResolver(javax.xml.transform.URIResolver);
+    method public abstract void transform(javax.xml.transform.Source, javax.xml.transform.Result) throws javax.xml.transform.TransformerException;
+  }
+
+  public class TransformerConfigurationException extends javax.xml.transform.TransformerException {
+    ctor public TransformerConfigurationException();
+    ctor public TransformerConfigurationException(String);
+    ctor public TransformerConfigurationException(Throwable);
+    ctor public TransformerConfigurationException(String, Throwable);
+    ctor public TransformerConfigurationException(String, javax.xml.transform.SourceLocator);
+    ctor public TransformerConfigurationException(String, javax.xml.transform.SourceLocator, Throwable);
+  }
+
+  public class TransformerException extends java.lang.Exception {
+    ctor public TransformerException(String);
+    ctor public TransformerException(Throwable);
+    ctor public TransformerException(String, Throwable);
+    ctor public TransformerException(String, javax.xml.transform.SourceLocator);
+    ctor public TransformerException(String, javax.xml.transform.SourceLocator, Throwable);
+    method public Throwable getException();
+    method public String getLocationAsString();
+    method public javax.xml.transform.SourceLocator getLocator();
+    method public String getMessageAndLocation();
+    method public void setLocator(javax.xml.transform.SourceLocator);
+  }
+
+  public abstract class TransformerFactory {
+    ctor protected TransformerFactory();
+    method public abstract javax.xml.transform.Source getAssociatedStylesheet(javax.xml.transform.Source, String, String, String) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract Object getAttribute(String);
+    method public abstract javax.xml.transform.ErrorListener getErrorListener();
+    method public abstract boolean getFeature(String);
+    method public abstract javax.xml.transform.URIResolver getURIResolver();
+    method public static javax.xml.transform.TransformerFactory newInstance() throws javax.xml.transform.TransformerFactoryConfigurationError;
+    method public static javax.xml.transform.TransformerFactory newInstance(String, ClassLoader) throws javax.xml.transform.TransformerFactoryConfigurationError;
+    method public abstract javax.xml.transform.Templates newTemplates(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract javax.xml.transform.Transformer newTransformer(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract javax.xml.transform.Transformer newTransformer() throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract void setAttribute(String, Object);
+    method public abstract void setErrorListener(javax.xml.transform.ErrorListener);
+    method public abstract void setFeature(String, boolean) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract void setURIResolver(javax.xml.transform.URIResolver);
+  }
+
+  public class TransformerFactoryConfigurationError extends java.lang.Error {
+    ctor public TransformerFactoryConfigurationError();
+    ctor public TransformerFactoryConfigurationError(String);
+    ctor public TransformerFactoryConfigurationError(Exception);
+    ctor public TransformerFactoryConfigurationError(Exception, String);
+    method public Exception getException();
+  }
+
+  public interface URIResolver {
+    method public javax.xml.transform.Source resolve(String, String) throws javax.xml.transform.TransformerException;
+  }
+
+}
+
+package javax.xml.transform.dom {
+
+  public interface DOMLocator extends javax.xml.transform.SourceLocator {
+    method public org.w3c.dom.Node getOriginatingNode();
+  }
+
+  public class DOMResult implements javax.xml.transform.Result {
+    ctor public DOMResult();
+    ctor public DOMResult(org.w3c.dom.Node);
+    ctor public DOMResult(org.w3c.dom.Node, String);
+    ctor public DOMResult(org.w3c.dom.Node, org.w3c.dom.Node);
+    ctor public DOMResult(org.w3c.dom.Node, org.w3c.dom.Node, String);
+    method public org.w3c.dom.Node getNextSibling();
+    method public org.w3c.dom.Node getNode();
+    method public String getSystemId();
+    method public void setNextSibling(org.w3c.dom.Node);
+    method public void setNode(org.w3c.dom.Node);
+    method public void setSystemId(String);
+    field public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature";
+  }
+
+  public class DOMSource implements javax.xml.transform.Source {
+    ctor public DOMSource();
+    ctor public DOMSource(org.w3c.dom.Node);
+    ctor public DOMSource(org.w3c.dom.Node, String);
+    method public org.w3c.dom.Node getNode();
+    method public String getSystemId();
+    method public void setNode(org.w3c.dom.Node);
+    method public void setSystemId(String);
+    field public static final String FEATURE = "http://javax.xml.transform.dom.DOMSource/feature";
+  }
+
+}
+
+package javax.xml.transform.sax {
+
+  public class SAXResult implements javax.xml.transform.Result {
+    ctor public SAXResult();
+    ctor public SAXResult(org.xml.sax.ContentHandler);
+    method public org.xml.sax.ContentHandler getHandler();
+    method public org.xml.sax.ext.LexicalHandler getLexicalHandler();
+    method public String getSystemId();
+    method public void setHandler(org.xml.sax.ContentHandler);
+    method public void setLexicalHandler(org.xml.sax.ext.LexicalHandler);
+    method public void setSystemId(String);
+    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXResult/feature";
+  }
+
+  public class SAXSource implements javax.xml.transform.Source {
+    ctor public SAXSource();
+    ctor public SAXSource(org.xml.sax.XMLReader, org.xml.sax.InputSource);
+    ctor public SAXSource(org.xml.sax.InputSource);
+    method public org.xml.sax.InputSource getInputSource();
+    method public String getSystemId();
+    method public org.xml.sax.XMLReader getXMLReader();
+    method public void setInputSource(org.xml.sax.InputSource);
+    method public void setSystemId(String);
+    method public void setXMLReader(org.xml.sax.XMLReader);
+    method public static org.xml.sax.InputSource sourceToInputSource(javax.xml.transform.Source);
+    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXSource/feature";
+  }
+
+  public abstract class SAXTransformerFactory extends javax.xml.transform.TransformerFactory {
+    ctor protected SAXTransformerFactory();
+    method public abstract javax.xml.transform.sax.TemplatesHandler newTemplatesHandler() throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler(javax.xml.transform.Templates) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract javax.xml.transform.sax.TransformerHandler newTransformerHandler() throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract org.xml.sax.XMLFilter newXMLFilter(javax.xml.transform.Source) throws javax.xml.transform.TransformerConfigurationException;
+    method public abstract org.xml.sax.XMLFilter newXMLFilter(javax.xml.transform.Templates) throws javax.xml.transform.TransformerConfigurationException;
+    field public static final String FEATURE = "http://javax.xml.transform.sax.SAXTransformerFactory/feature";
+    field public static final String FEATURE_XMLFILTER = "http://javax.xml.transform.sax.SAXTransformerFactory/feature/xmlfilter";
+  }
+
+  public interface TemplatesHandler extends org.xml.sax.ContentHandler {
+    method public String getSystemId();
+    method public javax.xml.transform.Templates getTemplates();
+    method public void setSystemId(String);
+  }
+
+  public interface TransformerHandler extends org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.ext.LexicalHandler {
+    method public String getSystemId();
+    method public javax.xml.transform.Transformer getTransformer();
+    method public void setResult(javax.xml.transform.Result) throws java.lang.IllegalArgumentException;
+    method public void setSystemId(String);
+  }
+
+}
+
+package javax.xml.transform.stream {
+
+  public class StreamResult implements javax.xml.transform.Result {
+    ctor public StreamResult();
+    ctor public StreamResult(java.io.OutputStream);
+    ctor public StreamResult(java.io.Writer);
+    ctor public StreamResult(String);
+    ctor public StreamResult(java.io.File);
+    method public java.io.OutputStream getOutputStream();
+    method public String getSystemId();
+    method public java.io.Writer getWriter();
+    method public void setOutputStream(java.io.OutputStream);
+    method public void setSystemId(String);
+    method public void setSystemId(java.io.File);
+    method public void setWriter(java.io.Writer);
+    field public static final String FEATURE = "http://javax.xml.transform.stream.StreamResult/feature";
+  }
+
+  public class StreamSource implements javax.xml.transform.Source {
+    ctor public StreamSource();
+    ctor public StreamSource(java.io.InputStream);
+    ctor public StreamSource(java.io.InputStream, String);
+    ctor public StreamSource(java.io.Reader);
+    ctor public StreamSource(java.io.Reader, String);
+    ctor public StreamSource(String);
+    ctor public StreamSource(java.io.File);
+    method public java.io.InputStream getInputStream();
+    method public String getPublicId();
+    method public java.io.Reader getReader();
+    method public String getSystemId();
+    method public void setInputStream(java.io.InputStream);
+    method public void setPublicId(String);
+    method public void setReader(java.io.Reader);
+    method public void setSystemId(String);
+    method public void setSystemId(java.io.File);
+    field public static final String FEATURE = "http://javax.xml.transform.stream.StreamSource/feature";
+  }
+
+}
+
+package javax.xml.validation {
+
+  public abstract class Schema {
+    ctor protected Schema();
+    method public abstract javax.xml.validation.Validator newValidator();
+    method public abstract javax.xml.validation.ValidatorHandler newValidatorHandler();
+  }
+
+  public abstract class SchemaFactory {
+    ctor protected SchemaFactory();
+    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
+    method public abstract boolean isSchemaLanguageSupported(String);
+    method public static javax.xml.validation.SchemaFactory newInstance(String);
+    method public static javax.xml.validation.SchemaFactory newInstance(String, String, ClassLoader);
+    method public javax.xml.validation.Schema newSchema(javax.xml.transform.Source) throws org.xml.sax.SAXException;
+    method public javax.xml.validation.Schema newSchema(java.io.File) throws org.xml.sax.SAXException;
+    method public javax.xml.validation.Schema newSchema(java.net.URL) throws org.xml.sax.SAXException;
+    method public abstract javax.xml.validation.Schema newSchema(javax.xml.transform.Source[]) throws org.xml.sax.SAXException;
+    method public abstract javax.xml.validation.Schema newSchema() throws org.xml.sax.SAXException;
+    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
+  }
+
+  public abstract class SchemaFactoryLoader {
+    ctor protected SchemaFactoryLoader();
+    method public abstract javax.xml.validation.SchemaFactory newFactory(String);
+  }
+
+  public abstract class TypeInfoProvider {
+    ctor protected TypeInfoProvider();
+    method public abstract org.w3c.dom.TypeInfo getAttributeTypeInfo(int);
+    method public abstract org.w3c.dom.TypeInfo getElementTypeInfo();
+    method public abstract boolean isIdAttribute(int);
+    method public abstract boolean isSpecified(int);
+  }
+
+  public abstract class Validator {
+    ctor protected Validator();
+    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
+    method public abstract void reset();
+    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
+    method public void validate(javax.xml.transform.Source) throws java.io.IOException, org.xml.sax.SAXException;
+    method public abstract void validate(javax.xml.transform.Source, javax.xml.transform.Result) throws java.io.IOException, org.xml.sax.SAXException;
+  }
+
+  public abstract class ValidatorHandler implements org.xml.sax.ContentHandler {
+    ctor protected ValidatorHandler();
+    method public abstract org.xml.sax.ContentHandler getContentHandler();
+    method public abstract org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract org.w3c.dom.ls.LSResourceResolver getResourceResolver();
+    method public abstract javax.xml.validation.TypeInfoProvider getTypeInfoProvider();
+    method public abstract void setContentHandler(org.xml.sax.ContentHandler);
+    method public abstract void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public abstract void setResourceResolver(org.w3c.dom.ls.LSResourceResolver);
+  }
+
+}
+
+package javax.xml.xpath {
+
+  public interface XPath {
+    method public javax.xml.xpath.XPathExpression compile(String) throws javax.xml.xpath.XPathExpressionException;
+    method public Object evaluate(String, Object, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
+    method public String evaluate(String, Object) throws javax.xml.xpath.XPathExpressionException;
+    method public Object evaluate(String, org.xml.sax.InputSource, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
+    method public String evaluate(String, org.xml.sax.InputSource) throws javax.xml.xpath.XPathExpressionException;
+    method public javax.xml.namespace.NamespaceContext getNamespaceContext();
+    method public javax.xml.xpath.XPathFunctionResolver getXPathFunctionResolver();
+    method public javax.xml.xpath.XPathVariableResolver getXPathVariableResolver();
+    method public void reset();
+    method public void setNamespaceContext(javax.xml.namespace.NamespaceContext);
+    method public void setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver);
+    method public void setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver);
+  }
+
+  public class XPathConstants {
+    field public static final javax.xml.namespace.QName BOOLEAN;
+    field public static final String DOM_OBJECT_MODEL = "http://java.sun.com/jaxp/xpath/dom";
+    field public static final javax.xml.namespace.QName NODE;
+    field public static final javax.xml.namespace.QName NODESET;
+    field public static final javax.xml.namespace.QName NUMBER;
+    field public static final javax.xml.namespace.QName STRING;
+  }
+
+  public class XPathException extends java.lang.Exception {
+    ctor public XPathException(String);
+    ctor public XPathException(Throwable);
+  }
+
+  public interface XPathExpression {
+    method public Object evaluate(Object, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
+    method public String evaluate(Object) throws javax.xml.xpath.XPathExpressionException;
+    method public Object evaluate(org.xml.sax.InputSource, javax.xml.namespace.QName) throws javax.xml.xpath.XPathExpressionException;
+    method public String evaluate(org.xml.sax.InputSource) throws javax.xml.xpath.XPathExpressionException;
+  }
+
+  public class XPathExpressionException extends javax.xml.xpath.XPathException {
+    ctor public XPathExpressionException(String);
+    ctor public XPathExpressionException(Throwable);
+  }
+
+  public abstract class XPathFactory {
+    ctor protected XPathFactory();
+    method public abstract boolean getFeature(String) throws javax.xml.xpath.XPathFactoryConfigurationException;
+    method public abstract boolean isObjectModelSupported(String);
+    method public static final javax.xml.xpath.XPathFactory newInstance();
+    method public static final javax.xml.xpath.XPathFactory newInstance(String) throws javax.xml.xpath.XPathFactoryConfigurationException;
+    method public static javax.xml.xpath.XPathFactory newInstance(String, String, ClassLoader) throws javax.xml.xpath.XPathFactoryConfigurationException;
+    method public abstract javax.xml.xpath.XPath newXPath();
+    method public abstract void setFeature(String, boolean) throws javax.xml.xpath.XPathFactoryConfigurationException;
+    method public abstract void setXPathFunctionResolver(javax.xml.xpath.XPathFunctionResolver);
+    method public abstract void setXPathVariableResolver(javax.xml.xpath.XPathVariableResolver);
+    field public static final String DEFAULT_OBJECT_MODEL_URI = "http://java.sun.com/jaxp/xpath/dom";
+    field public static final String DEFAULT_PROPERTY_NAME = "javax.xml.xpath.XPathFactory";
+  }
+
+  public class XPathFactoryConfigurationException extends javax.xml.xpath.XPathException {
+    ctor public XPathFactoryConfigurationException(String);
+    ctor public XPathFactoryConfigurationException(Throwable);
+  }
+
+  public interface XPathFunction {
+    method public Object evaluate(java.util.List) throws javax.xml.xpath.XPathFunctionException;
+  }
+
+  public class XPathFunctionException extends javax.xml.xpath.XPathExpressionException {
+    ctor public XPathFunctionException(String);
+    ctor public XPathFunctionException(Throwable);
+  }
+
+  public interface XPathFunctionResolver {
+    method public javax.xml.xpath.XPathFunction resolveFunction(javax.xml.namespace.QName, int);
+  }
+
+  public interface XPathVariableResolver {
+    method public Object resolveVariable(javax.xml.namespace.QName);
+  }
+
+}
+
+package org.json {
+
+  public class JSONArray {
+    ctor public JSONArray();
+    ctor public JSONArray(java.util.Collection);
+    ctor public JSONArray(org.json.JSONTokener) throws org.json.JSONException;
+    ctor public JSONArray(String) throws org.json.JSONException;
+    ctor public JSONArray(Object) throws org.json.JSONException;
+    method public Object get(int) throws org.json.JSONException;
+    method public boolean getBoolean(int) throws org.json.JSONException;
+    method public double getDouble(int) throws org.json.JSONException;
+    method public int getInt(int) throws org.json.JSONException;
+    method public org.json.JSONArray getJSONArray(int) throws org.json.JSONException;
+    method public org.json.JSONObject getJSONObject(int) throws org.json.JSONException;
+    method public long getLong(int) throws org.json.JSONException;
+    method public String getString(int) throws org.json.JSONException;
+    method public boolean isNull(int);
+    method public String join(String) throws org.json.JSONException;
+    method public int length();
+    method public Object opt(int);
+    method public boolean optBoolean(int);
+    method public boolean optBoolean(int, boolean);
+    method public double optDouble(int);
+    method public double optDouble(int, double);
+    method public int optInt(int);
+    method public int optInt(int, int);
+    method public org.json.JSONArray optJSONArray(int);
+    method public org.json.JSONObject optJSONObject(int);
+    method public long optLong(int);
+    method public long optLong(int, long);
+    method public String optString(int);
+    method public String optString(int, String);
+    method public org.json.JSONArray put(boolean);
+    method public org.json.JSONArray put(double) throws org.json.JSONException;
+    method public org.json.JSONArray put(int);
+    method public org.json.JSONArray put(long);
+    method public org.json.JSONArray put(Object);
+    method public org.json.JSONArray put(int, boolean) throws org.json.JSONException;
+    method public org.json.JSONArray put(int, double) throws org.json.JSONException;
+    method public org.json.JSONArray put(int, int) throws org.json.JSONException;
+    method public org.json.JSONArray put(int, long) throws org.json.JSONException;
+    method public org.json.JSONArray put(int, Object) throws org.json.JSONException;
+    method public Object remove(int);
+    method public org.json.JSONObject toJSONObject(org.json.JSONArray) throws org.json.JSONException;
+    method public String toString(int) throws org.json.JSONException;
+  }
+
+  public class JSONException extends java.lang.Exception {
+    ctor public JSONException(String);
+    ctor public JSONException(String, Throwable);
+    ctor public JSONException(Throwable);
+  }
+
+  public class JSONObject {
+    ctor public JSONObject();
+    ctor public JSONObject(@NonNull java.util.Map);
+    ctor public JSONObject(@NonNull org.json.JSONTokener) throws org.json.JSONException;
+    ctor public JSONObject(@NonNull String) throws org.json.JSONException;
+    ctor public JSONObject(@NonNull org.json.JSONObject, @NonNull String[]) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject accumulate(@NonNull String, @Nullable Object) throws org.json.JSONException;
+    method @NonNull public Object get(@NonNull String) throws org.json.JSONException;
+    method public boolean getBoolean(@NonNull String) throws org.json.JSONException;
+    method public double getDouble(@NonNull String) throws org.json.JSONException;
+    method public int getInt(@NonNull String) throws org.json.JSONException;
+    method @NonNull public org.json.JSONArray getJSONArray(@NonNull String) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject getJSONObject(@NonNull String) throws org.json.JSONException;
+    method public long getLong(@NonNull String) throws org.json.JSONException;
+    method @NonNull public String getString(@NonNull String) throws org.json.JSONException;
+    method public boolean has(@Nullable String);
+    method public boolean isNull(@Nullable String);
+    method @NonNull public java.util.Iterator<java.lang.String> keys();
+    method public int length();
+    method @Nullable public org.json.JSONArray names();
+    method @NonNull public static String numberToString(@NonNull Number) throws org.json.JSONException;
+    method @Nullable public Object opt(@Nullable String);
+    method public boolean optBoolean(@Nullable String);
+    method public boolean optBoolean(@Nullable String, boolean);
+    method public double optDouble(@Nullable String);
+    method public double optDouble(@Nullable String, double);
+    method public int optInt(@Nullable String);
+    method public int optInt(@Nullable String, int);
+    method @Nullable public org.json.JSONArray optJSONArray(@Nullable String);
+    method @Nullable public org.json.JSONObject optJSONObject(@Nullable String);
+    method public long optLong(@Nullable String);
+    method public long optLong(@Nullable String, long);
+    method @NonNull public String optString(@Nullable String);
+    method @NonNull public String optString(@Nullable String, @NonNull String);
+    method @NonNull public org.json.JSONObject put(@NonNull String, boolean) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject put(@NonNull String, double) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject put(@NonNull String, int) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject put(@NonNull String, long) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject put(@NonNull String, @Nullable Object) throws org.json.JSONException;
+    method @NonNull public org.json.JSONObject putOpt(@Nullable String, @Nullable Object) throws org.json.JSONException;
+    method @NonNull public static String quote(@Nullable String);
+    method @Nullable public Object remove(@Nullable String);
+    method @Nullable public org.json.JSONArray toJSONArray(@Nullable org.json.JSONArray) throws org.json.JSONException;
+    method @NonNull public String toString(int) throws org.json.JSONException;
+    method @Nullable public static Object wrap(@Nullable Object);
+    field @NonNull public static final Object NULL;
+  }
+
+  public class JSONStringer {
+    ctor public JSONStringer();
+    method public org.json.JSONStringer array() throws org.json.JSONException;
+    method public org.json.JSONStringer endArray() throws org.json.JSONException;
+    method public org.json.JSONStringer endObject() throws org.json.JSONException;
+    method public org.json.JSONStringer key(String) throws org.json.JSONException;
+    method public org.json.JSONStringer object() throws org.json.JSONException;
+    method public org.json.JSONStringer value(Object) throws org.json.JSONException;
+    method public org.json.JSONStringer value(boolean) throws org.json.JSONException;
+    method public org.json.JSONStringer value(double) throws org.json.JSONException;
+    method public org.json.JSONStringer value(long) throws org.json.JSONException;
+  }
+
+  public class JSONTokener {
+    ctor public JSONTokener(String);
+    method public void back();
+    method public static int dehexchar(char);
+    method public boolean more();
+    method public char next();
+    method public char next(char) throws org.json.JSONException;
+    method public String next(int) throws org.json.JSONException;
+    method public char nextClean() throws org.json.JSONException;
+    method public String nextString(char) throws org.json.JSONException;
+    method public String nextTo(String);
+    method public String nextTo(char);
+    method public Object nextValue() throws org.json.JSONException;
+    method public void skipPast(String);
+    method public char skipTo(char);
+    method public org.json.JSONException syntaxError(String);
+  }
+
+}
+
+package org.w3c.dom {
+
+  public interface Attr extends org.w3c.dom.Node {
+    method public String getName();
+    method public org.w3c.dom.Element getOwnerElement();
+    method public org.w3c.dom.TypeInfo getSchemaTypeInfo();
+    method public boolean getSpecified();
+    method public String getValue();
+    method public boolean isId();
+    method public void setValue(String) throws org.w3c.dom.DOMException;
+  }
+
+  public interface CDATASection extends org.w3c.dom.Text {
+  }
+
+  public interface CharacterData extends org.w3c.dom.Node {
+    method public void appendData(String) throws org.w3c.dom.DOMException;
+    method public void deleteData(int, int) throws org.w3c.dom.DOMException;
+    method public String getData() throws org.w3c.dom.DOMException;
+    method public int getLength();
+    method public void insertData(int, String) throws org.w3c.dom.DOMException;
+    method public void replaceData(int, int, String) throws org.w3c.dom.DOMException;
+    method public void setData(String) throws org.w3c.dom.DOMException;
+    method public String substringData(int, int) throws org.w3c.dom.DOMException;
+  }
+
+  public interface Comment extends org.w3c.dom.CharacterData {
+  }
+
+  public interface DOMConfiguration {
+    method public boolean canSetParameter(String, Object);
+    method public Object getParameter(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.DOMStringList getParameterNames();
+    method public void setParameter(String, Object) throws org.w3c.dom.DOMException;
+  }
+
+  public interface DOMError {
+    method public org.w3c.dom.DOMLocator getLocation();
+    method public String getMessage();
+    method public Object getRelatedData();
+    method public Object getRelatedException();
+    method public short getSeverity();
+    method public String getType();
+    field public static final short SEVERITY_ERROR = 2; // 0x2
+    field public static final short SEVERITY_FATAL_ERROR = 3; // 0x3
+    field public static final short SEVERITY_WARNING = 1; // 0x1
+  }
+
+  public interface DOMErrorHandler {
+    method public boolean handleError(org.w3c.dom.DOMError);
+  }
+
+  public class DOMException extends java.lang.RuntimeException {
+    ctor public DOMException(short, String);
+    field public static final short DOMSTRING_SIZE_ERR = 2; // 0x2
+    field public static final short HIERARCHY_REQUEST_ERR = 3; // 0x3
+    field public static final short INDEX_SIZE_ERR = 1; // 0x1
+    field public static final short INUSE_ATTRIBUTE_ERR = 10; // 0xa
+    field public static final short INVALID_ACCESS_ERR = 15; // 0xf
+    field public static final short INVALID_CHARACTER_ERR = 5; // 0x5
+    field public static final short INVALID_MODIFICATION_ERR = 13; // 0xd
+    field public static final short INVALID_STATE_ERR = 11; // 0xb
+    field public static final short NAMESPACE_ERR = 14; // 0xe
+    field public static final short NOT_FOUND_ERR = 8; // 0x8
+    field public static final short NOT_SUPPORTED_ERR = 9; // 0x9
+    field public static final short NO_DATA_ALLOWED_ERR = 6; // 0x6
+    field public static final short NO_MODIFICATION_ALLOWED_ERR = 7; // 0x7
+    field public static final short SYNTAX_ERR = 12; // 0xc
+    field public static final short TYPE_MISMATCH_ERR = 17; // 0x11
+    field public static final short VALIDATION_ERR = 16; // 0x10
+    field public static final short WRONG_DOCUMENT_ERR = 4; // 0x4
+    field public short code;
+  }
+
+  public interface DOMImplementation {
+    method public org.w3c.dom.Document createDocument(String, String, org.w3c.dom.DocumentType) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.DocumentType createDocumentType(String, String, String) throws org.w3c.dom.DOMException;
+    method public Object getFeature(String, String);
+    method public boolean hasFeature(String, String);
+  }
+
+  public interface DOMImplementationList {
+    method public int getLength();
+    method public org.w3c.dom.DOMImplementation item(int);
+  }
+
+  public interface DOMImplementationSource {
+    method public org.w3c.dom.DOMImplementation getDOMImplementation(String);
+    method public org.w3c.dom.DOMImplementationList getDOMImplementationList(String);
+  }
+
+  public interface DOMLocator {
+    method public int getByteOffset();
+    method public int getColumnNumber();
+    method public int getLineNumber();
+    method public org.w3c.dom.Node getRelatedNode();
+    method public String getUri();
+    method public int getUtf16Offset();
+  }
+
+  public interface DOMStringList {
+    method public boolean contains(String);
+    method public int getLength();
+    method public String item(int);
+  }
+
+  public interface Document extends org.w3c.dom.Node {
+    method public org.w3c.dom.Node adoptNode(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr createAttribute(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr createAttributeNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.CDATASection createCDATASection(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Comment createComment(String);
+    method public org.w3c.dom.DocumentFragment createDocumentFragment();
+    method public org.w3c.dom.Element createElement(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Element createElementNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.EntityReference createEntityReference(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.ProcessingInstruction createProcessingInstruction(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Text createTextNode(String);
+    method public org.w3c.dom.DocumentType getDoctype();
+    method public org.w3c.dom.Element getDocumentElement();
+    method public String getDocumentURI();
+    method public org.w3c.dom.DOMConfiguration getDomConfig();
+    method public org.w3c.dom.Element getElementById(String);
+    method public org.w3c.dom.NodeList getElementsByTagName(String);
+    method public org.w3c.dom.NodeList getElementsByTagNameNS(String, String);
+    method public org.w3c.dom.DOMImplementation getImplementation();
+    method public String getInputEncoding();
+    method public boolean getStrictErrorChecking();
+    method public String getXmlEncoding();
+    method public boolean getXmlStandalone();
+    method public String getXmlVersion();
+    method public org.w3c.dom.Node importNode(org.w3c.dom.Node, boolean) throws org.w3c.dom.DOMException;
+    method public void normalizeDocument();
+    method public org.w3c.dom.Node renameNode(org.w3c.dom.Node, String, String) throws org.w3c.dom.DOMException;
+    method public void setDocumentURI(String);
+    method public void setStrictErrorChecking(boolean);
+    method public void setXmlStandalone(boolean) throws org.w3c.dom.DOMException;
+    method public void setXmlVersion(String) throws org.w3c.dom.DOMException;
+  }
+
+  public interface DocumentFragment extends org.w3c.dom.Node {
+  }
+
+  public interface DocumentType extends org.w3c.dom.Node {
+    method public org.w3c.dom.NamedNodeMap getEntities();
+    method public String getInternalSubset();
+    method public String getName();
+    method public org.w3c.dom.NamedNodeMap getNotations();
+    method public String getPublicId();
+    method public String getSystemId();
+  }
+
+  public interface Element extends org.w3c.dom.Node {
+    method public String getAttribute(String);
+    method public String getAttributeNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr getAttributeNode(String);
+    method public org.w3c.dom.Attr getAttributeNodeNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.NodeList getElementsByTagName(String);
+    method public org.w3c.dom.NodeList getElementsByTagNameNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.TypeInfo getSchemaTypeInfo();
+    method public String getTagName();
+    method public boolean hasAttribute(String);
+    method public boolean hasAttributeNS(String, String) throws org.w3c.dom.DOMException;
+    method public void removeAttribute(String) throws org.w3c.dom.DOMException;
+    method public void removeAttributeNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr removeAttributeNode(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
+    method public void setAttribute(String, String) throws org.w3c.dom.DOMException;
+    method public void setAttributeNS(String, String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr setAttributeNode(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Attr setAttributeNodeNS(org.w3c.dom.Attr) throws org.w3c.dom.DOMException;
+    method public void setIdAttribute(String, boolean) throws org.w3c.dom.DOMException;
+    method public void setIdAttributeNS(String, String, boolean) throws org.w3c.dom.DOMException;
+    method public void setIdAttributeNode(org.w3c.dom.Attr, boolean) throws org.w3c.dom.DOMException;
+  }
+
+  public interface Entity extends org.w3c.dom.Node {
+    method public String getInputEncoding();
+    method public String getNotationName();
+    method public String getPublicId();
+    method public String getSystemId();
+    method public String getXmlEncoding();
+    method public String getXmlVersion();
+  }
+
+  public interface EntityReference extends org.w3c.dom.Node {
+  }
+
+  public interface NameList {
+    method public boolean contains(String);
+    method public boolean containsNS(String, String);
+    method public int getLength();
+    method public String getName(int);
+    method public String getNamespaceURI(int);
+  }
+
+  public interface NamedNodeMap {
+    method public int getLength();
+    method public org.w3c.dom.Node getNamedItem(String);
+    method public org.w3c.dom.Node getNamedItemNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node item(int);
+    method public org.w3c.dom.Node removeNamedItem(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node removeNamedItemNS(String, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node setNamedItem(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node setNamedItemNS(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+  }
+
+  public interface Node {
+    method public org.w3c.dom.Node appendChild(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node cloneNode(boolean);
+    method public short compareDocumentPosition(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.NamedNodeMap getAttributes();
+    method public String getBaseURI();
+    method public org.w3c.dom.NodeList getChildNodes();
+    method public Object getFeature(String, String);
+    method public org.w3c.dom.Node getFirstChild();
+    method public org.w3c.dom.Node getLastChild();
+    method public String getLocalName();
+    method public String getNamespaceURI();
+    method public org.w3c.dom.Node getNextSibling();
+    method public String getNodeName();
+    method public short getNodeType();
+    method public String getNodeValue() throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Document getOwnerDocument();
+    method public org.w3c.dom.Node getParentNode();
+    method public String getPrefix();
+    method public org.w3c.dom.Node getPreviousSibling();
+    method public String getTextContent() throws org.w3c.dom.DOMException;
+    method public Object getUserData(String);
+    method public boolean hasAttributes();
+    method public boolean hasChildNodes();
+    method public org.w3c.dom.Node insertBefore(org.w3c.dom.Node, org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public boolean isDefaultNamespace(String);
+    method public boolean isEqualNode(org.w3c.dom.Node);
+    method public boolean isSameNode(org.w3c.dom.Node);
+    method public boolean isSupported(String, String);
+    method public String lookupNamespaceURI(String);
+    method public String lookupPrefix(String);
+    method public void normalize();
+    method public org.w3c.dom.Node removeChild(org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Node replaceChild(org.w3c.dom.Node, org.w3c.dom.Node) throws org.w3c.dom.DOMException;
+    method public void setNodeValue(String) throws org.w3c.dom.DOMException;
+    method public void setPrefix(String) throws org.w3c.dom.DOMException;
+    method public void setTextContent(String) throws org.w3c.dom.DOMException;
+    method public Object setUserData(String, Object, org.w3c.dom.UserDataHandler);
+    field public static final short ATTRIBUTE_NODE = 2; // 0x2
+    field public static final short CDATA_SECTION_NODE = 4; // 0x4
+    field public static final short COMMENT_NODE = 8; // 0x8
+    field public static final short DOCUMENT_FRAGMENT_NODE = 11; // 0xb
+    field public static final short DOCUMENT_NODE = 9; // 0x9
+    field public static final short DOCUMENT_POSITION_CONTAINED_BY = 16; // 0x10
+    field public static final short DOCUMENT_POSITION_CONTAINS = 8; // 0x8
+    field public static final short DOCUMENT_POSITION_DISCONNECTED = 1; // 0x1
+    field public static final short DOCUMENT_POSITION_FOLLOWING = 4; // 0x4
+    field public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32; // 0x20
+    field public static final short DOCUMENT_POSITION_PRECEDING = 2; // 0x2
+    field public static final short DOCUMENT_TYPE_NODE = 10; // 0xa
+    field public static final short ELEMENT_NODE = 1; // 0x1
+    field public static final short ENTITY_NODE = 6; // 0x6
+    field public static final short ENTITY_REFERENCE_NODE = 5; // 0x5
+    field public static final short NOTATION_NODE = 12; // 0xc
+    field public static final short PROCESSING_INSTRUCTION_NODE = 7; // 0x7
+    field public static final short TEXT_NODE = 3; // 0x3
+  }
+
+  public interface NodeList {
+    method public int getLength();
+    method public org.w3c.dom.Node item(int);
+  }
+
+  public interface Notation extends org.w3c.dom.Node {
+    method public String getPublicId();
+    method public String getSystemId();
+  }
+
+  public interface ProcessingInstruction extends org.w3c.dom.Node {
+    method public String getData();
+    method public String getTarget();
+    method public void setData(String) throws org.w3c.dom.DOMException;
+  }
+
+  public interface Text extends org.w3c.dom.CharacterData {
+    method public String getWholeText();
+    method public boolean isElementContentWhitespace();
+    method public org.w3c.dom.Text replaceWholeText(String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.Text splitText(int) throws org.w3c.dom.DOMException;
+  }
+
+  public interface TypeInfo {
+    method public String getTypeName();
+    method public String getTypeNamespace();
+    method public boolean isDerivedFrom(String, String, int);
+    field public static final int DERIVATION_EXTENSION = 2; // 0x2
+    field public static final int DERIVATION_LIST = 8; // 0x8
+    field public static final int DERIVATION_RESTRICTION = 1; // 0x1
+    field public static final int DERIVATION_UNION = 4; // 0x4
+  }
+
+  public interface UserDataHandler {
+    method public void handle(short, String, Object, org.w3c.dom.Node, org.w3c.dom.Node);
+    field public static final short NODE_ADOPTED = 5; // 0x5
+    field public static final short NODE_CLONED = 1; // 0x1
+    field public static final short NODE_DELETED = 3; // 0x3
+    field public static final short NODE_IMPORTED = 2; // 0x2
+    field public static final short NODE_RENAMED = 4; // 0x4
+  }
+
+}
+
+package org.w3c.dom.ls {
+
+  public interface DOMImplementationLS {
+    method public org.w3c.dom.ls.LSInput createLSInput();
+    method public org.w3c.dom.ls.LSOutput createLSOutput();
+    method public org.w3c.dom.ls.LSParser createLSParser(short, String) throws org.w3c.dom.DOMException;
+    method public org.w3c.dom.ls.LSSerializer createLSSerializer();
+    field public static final short MODE_ASYNCHRONOUS = 2; // 0x2
+    field public static final short MODE_SYNCHRONOUS = 1; // 0x1
+  }
+
+  public class LSException extends java.lang.RuntimeException {
+    ctor public LSException(short, String);
+    field public static final short PARSE_ERR = 81; // 0x51
+    field public static final short SERIALIZE_ERR = 82; // 0x52
+    field public short code;
+  }
+
+  public interface LSInput {
+    method public String getBaseURI();
+    method public java.io.InputStream getByteStream();
+    method public boolean getCertifiedText();
+    method public java.io.Reader getCharacterStream();
+    method public String getEncoding();
+    method public String getPublicId();
+    method public String getStringData();
+    method public String getSystemId();
+    method public void setBaseURI(String);
+    method public void setByteStream(java.io.InputStream);
+    method public void setCertifiedText(boolean);
+    method public void setCharacterStream(java.io.Reader);
+    method public void setEncoding(String);
+    method public void setPublicId(String);
+    method public void setStringData(String);
+    method public void setSystemId(String);
+  }
+
+  public interface LSOutput {
+    method public java.io.OutputStream getByteStream();
+    method public java.io.Writer getCharacterStream();
+    method public String getEncoding();
+    method public String getSystemId();
+    method public void setByteStream(java.io.OutputStream);
+    method public void setCharacterStream(java.io.Writer);
+    method public void setEncoding(String);
+    method public void setSystemId(String);
+  }
+
+  public interface LSParser {
+    method public void abort();
+    method public boolean getAsync();
+    method public boolean getBusy();
+    method public org.w3c.dom.DOMConfiguration getDomConfig();
+    method public org.w3c.dom.ls.LSParserFilter getFilter();
+    method public org.w3c.dom.Document parse(org.w3c.dom.ls.LSInput) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
+    method public org.w3c.dom.Document parseURI(String) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
+    method public org.w3c.dom.Node parseWithContext(org.w3c.dom.ls.LSInput, org.w3c.dom.Node, short) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
+    method public void setFilter(org.w3c.dom.ls.LSParserFilter);
+    field public static final short ACTION_APPEND_AS_CHILDREN = 1; // 0x1
+    field public static final short ACTION_INSERT_AFTER = 4; // 0x4
+    field public static final short ACTION_INSERT_BEFORE = 3; // 0x3
+    field public static final short ACTION_REPLACE = 5; // 0x5
+    field public static final short ACTION_REPLACE_CHILDREN = 2; // 0x2
+  }
+
+  public interface LSParserFilter {
+    method public short acceptNode(org.w3c.dom.Node);
+    method public int getWhatToShow();
+    method public short startElement(org.w3c.dom.Element);
+    field public static final short FILTER_ACCEPT = 1; // 0x1
+    field public static final short FILTER_INTERRUPT = 4; // 0x4
+    field public static final short FILTER_REJECT = 2; // 0x2
+    field public static final short FILTER_SKIP = 3; // 0x3
+  }
+
+  public interface LSResourceResolver {
+    method public org.w3c.dom.ls.LSInput resolveResource(String, String, String, String, String);
+  }
+
+  public interface LSSerializer {
+    method public org.w3c.dom.DOMConfiguration getDomConfig();
+    method public String getNewLine();
+    method public void setNewLine(String);
+    method public boolean write(org.w3c.dom.Node, org.w3c.dom.ls.LSOutput) throws org.w3c.dom.ls.LSException;
+    method public String writeToString(org.w3c.dom.Node) throws org.w3c.dom.DOMException, org.w3c.dom.ls.LSException;
+    method public boolean writeToURI(org.w3c.dom.Node, String) throws org.w3c.dom.ls.LSException;
+  }
+
+}
+
+package org.xml.sax {
+
+  @Deprecated public interface AttributeList {
+    method @Deprecated public int getLength();
+    method @Deprecated public String getName(int);
+    method @Deprecated public String getType(int);
+    method @Deprecated public String getType(String);
+    method @Deprecated public String getValue(int);
+    method @Deprecated public String getValue(String);
+  }
+
+  public interface Attributes {
+    method public int getIndex(String, String);
+    method public int getIndex(String);
+    method public int getLength();
+    method public String getLocalName(int);
+    method public String getQName(int);
+    method public String getType(int);
+    method public String getType(String, String);
+    method public String getType(String);
+    method public String getURI(int);
+    method public String getValue(int);
+    method public String getValue(String, String);
+    method public String getValue(String);
+  }
+
+  public interface ContentHandler {
+    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endDocument() throws org.xml.sax.SAXException;
+    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
+    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
+    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method public void setDocumentLocator(org.xml.sax.Locator);
+    method public void skippedEntity(String) throws org.xml.sax.SAXException;
+    method public void startDocument() throws org.xml.sax.SAXException;
+    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
+    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
+  }
+
+  public interface DTDHandler {
+    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
+    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
+  }
+
+  @Deprecated public interface DocumentHandler {
+    method @Deprecated public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method @Deprecated public void endDocument() throws org.xml.sax.SAXException;
+    method @Deprecated public void endElement(String) throws org.xml.sax.SAXException;
+    method @Deprecated public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method @Deprecated public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method @Deprecated public void setDocumentLocator(org.xml.sax.Locator);
+    method @Deprecated public void startDocument() throws org.xml.sax.SAXException;
+    method @Deprecated public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
+  }
+
+  public interface EntityResolver {
+    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
+  }
+
+  public interface ErrorHandler {
+    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+  }
+
+  @Deprecated public class HandlerBase implements org.xml.sax.DTDHandler org.xml.sax.DocumentHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler {
+    ctor @Deprecated public HandlerBase();
+    method @Deprecated public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method @Deprecated public void endDocument() throws org.xml.sax.SAXException;
+    method @Deprecated public void endElement(String) throws org.xml.sax.SAXException;
+    method @Deprecated public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method @Deprecated public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method @Deprecated public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method @Deprecated public void notationDecl(String, String, String);
+    method @Deprecated public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method @Deprecated public org.xml.sax.InputSource resolveEntity(String, String) throws org.xml.sax.SAXException;
+    method @Deprecated public void setDocumentLocator(org.xml.sax.Locator);
+    method @Deprecated public void startDocument() throws org.xml.sax.SAXException;
+    method @Deprecated public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
+    method @Deprecated public void unparsedEntityDecl(String, String, String, String);
+    method @Deprecated public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+  }
+
+  public class InputSource {
+    ctor public InputSource();
+    ctor public InputSource(String);
+    ctor public InputSource(java.io.InputStream);
+    ctor public InputSource(java.io.Reader);
+    method public java.io.InputStream getByteStream();
+    method public java.io.Reader getCharacterStream();
+    method public String getEncoding();
+    method public String getPublicId();
+    method public String getSystemId();
+    method public void setByteStream(java.io.InputStream);
+    method public void setCharacterStream(java.io.Reader);
+    method public void setEncoding(String);
+    method public void setPublicId(String);
+    method public void setSystemId(String);
+  }
+
+  public interface Locator {
+    method public int getColumnNumber();
+    method public int getLineNumber();
+    method public String getPublicId();
+    method public String getSystemId();
+  }
+
+  @Deprecated public interface Parser {
+    method @Deprecated public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method @Deprecated public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method @Deprecated public void setDTDHandler(org.xml.sax.DTDHandler);
+    method @Deprecated public void setDocumentHandler(org.xml.sax.DocumentHandler);
+    method @Deprecated public void setEntityResolver(org.xml.sax.EntityResolver);
+    method @Deprecated public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method @Deprecated public void setLocale(java.util.Locale) throws org.xml.sax.SAXException;
+  }
+
+  public class SAXException extends java.lang.Exception {
+    ctor public SAXException();
+    ctor public SAXException(String);
+    ctor public SAXException(Exception);
+    ctor public SAXException(String, Exception);
+    method public Exception getException();
+  }
+
+  public class SAXNotRecognizedException extends org.xml.sax.SAXException {
+    ctor public SAXNotRecognizedException();
+    ctor public SAXNotRecognizedException(String);
+  }
+
+  public class SAXNotSupportedException extends org.xml.sax.SAXException {
+    ctor public SAXNotSupportedException();
+    ctor public SAXNotSupportedException(String);
+  }
+
+  public class SAXParseException extends org.xml.sax.SAXException {
+    ctor public SAXParseException(String, org.xml.sax.Locator);
+    ctor public SAXParseException(String, org.xml.sax.Locator, Exception);
+    ctor public SAXParseException(String, String, String, int, int);
+    ctor public SAXParseException(String, String, String, int, int, Exception);
+    method public int getColumnNumber();
+    method public int getLineNumber();
+    method public String getPublicId();
+    method public String getSystemId();
+  }
+
+  public interface XMLFilter extends org.xml.sax.XMLReader {
+    method public org.xml.sax.XMLReader getParent();
+    method public void setParent(org.xml.sax.XMLReader);
+  }
+
+  public interface XMLReader {
+    method public org.xml.sax.ContentHandler getContentHandler();
+    method public org.xml.sax.DTDHandler getDTDHandler();
+    method public org.xml.sax.EntityResolver getEntityResolver();
+    method public org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void setContentHandler(org.xml.sax.ContentHandler);
+    method public void setDTDHandler(org.xml.sax.DTDHandler);
+    method public void setEntityResolver(org.xml.sax.EntityResolver);
+    method public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+  }
+
+}
+
+package org.xml.sax.ext {
+
+  public interface Attributes2 extends org.xml.sax.Attributes {
+    method public boolean isDeclared(int);
+    method public boolean isDeclared(String);
+    method public boolean isDeclared(String, String);
+    method public boolean isSpecified(int);
+    method public boolean isSpecified(String, String);
+    method public boolean isSpecified(String);
+  }
+
+  public class Attributes2Impl extends org.xml.sax.helpers.AttributesImpl implements org.xml.sax.ext.Attributes2 {
+    ctor public Attributes2Impl();
+    ctor public Attributes2Impl(org.xml.sax.Attributes);
+    method public boolean isDeclared(int);
+    method public boolean isDeclared(String, String);
+    method public boolean isDeclared(String);
+    method public boolean isSpecified(int);
+    method public boolean isSpecified(String, String);
+    method public boolean isSpecified(String);
+    method public void setDeclared(int, boolean);
+    method public void setSpecified(int, boolean);
+  }
+
+  public interface DeclHandler {
+    method public void attributeDecl(String, String, String, String, String) throws org.xml.sax.SAXException;
+    method public void elementDecl(String, String) throws org.xml.sax.SAXException;
+    method public void externalEntityDecl(String, String, String) throws org.xml.sax.SAXException;
+    method public void internalEntityDecl(String, String) throws org.xml.sax.SAXException;
+  }
+
+  public class DefaultHandler2 extends org.xml.sax.helpers.DefaultHandler implements org.xml.sax.ext.DeclHandler org.xml.sax.ext.EntityResolver2 org.xml.sax.ext.LexicalHandler {
+    ctor public DefaultHandler2();
+    method public void attributeDecl(String, String, String, String, String) throws org.xml.sax.SAXException;
+    method public void comment(char[], int, int) throws org.xml.sax.SAXException;
+    method public void elementDecl(String, String) throws org.xml.sax.SAXException;
+    method public void endCDATA() throws org.xml.sax.SAXException;
+    method public void endDTD() throws org.xml.sax.SAXException;
+    method public void endEntity(String) throws org.xml.sax.SAXException;
+    method public void externalEntityDecl(String, String, String) throws org.xml.sax.SAXException;
+    method public org.xml.sax.InputSource getExternalSubset(String, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void internalEntityDecl(String, String) throws org.xml.sax.SAXException;
+    method public org.xml.sax.InputSource resolveEntity(String, String, String, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void startCDATA() throws org.xml.sax.SAXException;
+    method public void startDTD(String, String, String) throws org.xml.sax.SAXException;
+    method public void startEntity(String) throws org.xml.sax.SAXException;
+  }
+
+  public interface EntityResolver2 extends org.xml.sax.EntityResolver {
+    method public org.xml.sax.InputSource getExternalSubset(String, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public org.xml.sax.InputSource resolveEntity(String, String, String, String) throws java.io.IOException, org.xml.sax.SAXException;
+  }
+
+  public interface LexicalHandler {
+    method public void comment(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endCDATA() throws org.xml.sax.SAXException;
+    method public void endDTD() throws org.xml.sax.SAXException;
+    method public void endEntity(String) throws org.xml.sax.SAXException;
+    method public void startCDATA() throws org.xml.sax.SAXException;
+    method public void startDTD(String, String, String) throws org.xml.sax.SAXException;
+    method public void startEntity(String) throws org.xml.sax.SAXException;
+  }
+
+  public interface Locator2 extends org.xml.sax.Locator {
+    method public String getEncoding();
+    method public String getXMLVersion();
+  }
+
+  public class Locator2Impl extends org.xml.sax.helpers.LocatorImpl implements org.xml.sax.ext.Locator2 {
+    ctor public Locator2Impl();
+    ctor public Locator2Impl(org.xml.sax.Locator);
+    method public String getEncoding();
+    method public String getXMLVersion();
+    method public void setEncoding(String);
+    method public void setXMLVersion(String);
+  }
+
+}
+
+package org.xml.sax.helpers {
+
+  @Deprecated public class AttributeListImpl implements org.xml.sax.AttributeList {
+    ctor @Deprecated public AttributeListImpl();
+    ctor @Deprecated public AttributeListImpl(org.xml.sax.AttributeList);
+    method @Deprecated public void addAttribute(String, String, String);
+    method @Deprecated public void clear();
+    method @Deprecated public int getLength();
+    method @Deprecated public String getName(int);
+    method @Deprecated public String getType(int);
+    method @Deprecated public String getType(String);
+    method @Deprecated public String getValue(int);
+    method @Deprecated public String getValue(String);
+    method @Deprecated public void removeAttribute(String);
+    method @Deprecated public void setAttributeList(org.xml.sax.AttributeList);
+  }
+
+  public class AttributesImpl implements org.xml.sax.Attributes {
+    ctor public AttributesImpl();
+    ctor public AttributesImpl(org.xml.sax.Attributes);
+    method public void addAttribute(String, String, String, String, String);
+    method public void clear();
+    method public int getIndex(String, String);
+    method public int getIndex(String);
+    method public int getLength();
+    method public String getLocalName(int);
+    method public String getQName(int);
+    method public String getType(int);
+    method public String getType(String, String);
+    method public String getType(String);
+    method public String getURI(int);
+    method public String getValue(int);
+    method public String getValue(String, String);
+    method public String getValue(String);
+    method public void removeAttribute(int);
+    method public void setAttribute(int, String, String, String, String, String);
+    method public void setAttributes(org.xml.sax.Attributes);
+    method public void setLocalName(int, String);
+    method public void setQName(int, String);
+    method public void setType(int, String);
+    method public void setURI(int, String);
+    method public void setValue(int, String);
+  }
+
+  public class DefaultHandler implements org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler {
+    ctor public DefaultHandler();
+    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endDocument() throws org.xml.sax.SAXException;
+    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
+    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
+    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
+    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void setDocumentLocator(org.xml.sax.Locator);
+    method public void skippedEntity(String) throws org.xml.sax.SAXException;
+    method public void startDocument() throws org.xml.sax.SAXException;
+    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
+    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
+    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
+    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+  }
+
+  public class LocatorImpl implements org.xml.sax.Locator {
+    ctor public LocatorImpl();
+    ctor public LocatorImpl(org.xml.sax.Locator);
+    method public int getColumnNumber();
+    method public int getLineNumber();
+    method public String getPublicId();
+    method public String getSystemId();
+    method public void setColumnNumber(int);
+    method public void setLineNumber(int);
+    method public void setPublicId(String);
+    method public void setSystemId(String);
+  }
+
+  public class NamespaceSupport {
+    ctor public NamespaceSupport();
+    method public boolean declarePrefix(String, String);
+    method public java.util.Enumeration getDeclaredPrefixes();
+    method public String getPrefix(String);
+    method public java.util.Enumeration getPrefixes();
+    method public java.util.Enumeration getPrefixes(String);
+    method public String getURI(String);
+    method public boolean isNamespaceDeclUris();
+    method public void popContext();
+    method public String[] processName(String, String[], boolean);
+    method public void pushContext();
+    method public void reset();
+    method public void setNamespaceDeclUris(boolean);
+    field public static final String NSDECL = "http://www.w3.org/xmlns/2000/";
+    field public static final String XMLNS = "http://www.w3.org/XML/1998/namespace";
+  }
+
+  public class ParserAdapter implements org.xml.sax.DocumentHandler org.xml.sax.XMLReader {
+    ctor public ParserAdapter() throws org.xml.sax.SAXException;
+    ctor public ParserAdapter(org.xml.sax.Parser);
+    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endDocument() throws org.xml.sax.SAXException;
+    method public void endElement(String) throws org.xml.sax.SAXException;
+    method public org.xml.sax.ContentHandler getContentHandler();
+    method public org.xml.sax.DTDHandler getDTDHandler();
+    method public org.xml.sax.EntityResolver getEntityResolver();
+    method public org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method public void setContentHandler(org.xml.sax.ContentHandler);
+    method public void setDTDHandler(org.xml.sax.DTDHandler);
+    method public void setDocumentLocator(org.xml.sax.Locator);
+    method public void setEntityResolver(org.xml.sax.EntityResolver);
+    method public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void startDocument() throws org.xml.sax.SAXException;
+    method public void startElement(String, org.xml.sax.AttributeList) throws org.xml.sax.SAXException;
+  }
+
+  @Deprecated public class ParserFactory {
+    method @Deprecated public static org.xml.sax.Parser makeParser() throws java.lang.ClassCastException, java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException, java.lang.NullPointerException;
+    method @Deprecated public static org.xml.sax.Parser makeParser(String) throws java.lang.ClassCastException, java.lang.ClassNotFoundException, java.lang.IllegalAccessException, java.lang.InstantiationException;
+  }
+
+  public class XMLFilterImpl implements org.xml.sax.ContentHandler org.xml.sax.DTDHandler org.xml.sax.EntityResolver org.xml.sax.ErrorHandler org.xml.sax.XMLFilter {
+    ctor public XMLFilterImpl();
+    ctor public XMLFilterImpl(org.xml.sax.XMLReader);
+    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endDocument() throws org.xml.sax.SAXException;
+    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
+    method public void endPrefixMapping(String) throws org.xml.sax.SAXException;
+    method public void error(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public void fatalError(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+    method public org.xml.sax.ContentHandler getContentHandler();
+    method public org.xml.sax.DTDHandler getDTDHandler();
+    method public org.xml.sax.EntityResolver getEntityResolver();
+    method public org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public org.xml.sax.XMLReader getParent();
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method public void notationDecl(String, String, String) throws org.xml.sax.SAXException;
+    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method public org.xml.sax.InputSource resolveEntity(String, String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void setContentHandler(org.xml.sax.ContentHandler);
+    method public void setDTDHandler(org.xml.sax.DTDHandler);
+    method public void setDocumentLocator(org.xml.sax.Locator);
+    method public void setEntityResolver(org.xml.sax.EntityResolver);
+    method public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setParent(org.xml.sax.XMLReader);
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void skippedEntity(String) throws org.xml.sax.SAXException;
+    method public void startDocument() throws org.xml.sax.SAXException;
+    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
+    method public void startPrefixMapping(String, String) throws org.xml.sax.SAXException;
+    method public void unparsedEntityDecl(String, String, String, String) throws org.xml.sax.SAXException;
+    method public void warning(org.xml.sax.SAXParseException) throws org.xml.sax.SAXException;
+  }
+
+  public class XMLReaderAdapter implements org.xml.sax.ContentHandler org.xml.sax.Parser {
+    ctor public XMLReaderAdapter() throws org.xml.sax.SAXException;
+    ctor public XMLReaderAdapter(org.xml.sax.XMLReader);
+    method public void characters(char[], int, int) throws org.xml.sax.SAXException;
+    method public void endDocument() throws org.xml.sax.SAXException;
+    method public void endElement(String, String, String) throws org.xml.sax.SAXException;
+    method public void endPrefixMapping(String);
+    method public void ignorableWhitespace(char[], int, int) throws org.xml.sax.SAXException;
+    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void processingInstruction(String, String) throws org.xml.sax.SAXException;
+    method public void setDTDHandler(org.xml.sax.DTDHandler);
+    method public void setDocumentHandler(org.xml.sax.DocumentHandler);
+    method public void setDocumentLocator(org.xml.sax.Locator);
+    method public void setEntityResolver(org.xml.sax.EntityResolver);
+    method public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setLocale(java.util.Locale) throws org.xml.sax.SAXException;
+    method public void skippedEntity(String) throws org.xml.sax.SAXException;
+    method public void startDocument() throws org.xml.sax.SAXException;
+    method public void startElement(String, String, String, org.xml.sax.Attributes) throws org.xml.sax.SAXException;
+    method public void startPrefixMapping(String, String);
+  }
+
+  public final class XMLReaderFactory {
+    method public static org.xml.sax.XMLReader createXMLReader() throws org.xml.sax.SAXException;
+    method public static org.xml.sax.XMLReader createXMLReader(String) throws org.xml.sax.SAXException;
+  }
+
+}
+
+package org.xmlpull.v1 {
+
+  public interface XmlPullParser {
+    method public void defineEntityReplacementText(String, String) throws org.xmlpull.v1.XmlPullParserException;
+    method public int getAttributeCount();
+    method public String getAttributeName(int);
+    method public String getAttributeNamespace(int);
+    method public String getAttributePrefix(int);
+    method public String getAttributeType(int);
+    method public String getAttributeValue(int);
+    method public String getAttributeValue(String, String);
+    method public int getColumnNumber();
+    method public int getDepth();
+    method public int getEventType() throws org.xmlpull.v1.XmlPullParserException;
+    method public boolean getFeature(String);
+    method public String getInputEncoding();
+    method public int getLineNumber();
+    method public String getName();
+    method public String getNamespace(String);
+    method public String getNamespace();
+    method public int getNamespaceCount(int) throws org.xmlpull.v1.XmlPullParserException;
+    method public String getNamespacePrefix(int) throws org.xmlpull.v1.XmlPullParserException;
+    method public String getNamespaceUri(int) throws org.xmlpull.v1.XmlPullParserException;
+    method public String getPositionDescription();
+    method public String getPrefix();
+    method public Object getProperty(String);
+    method public String getText();
+    method public char[] getTextCharacters(int[]);
+    method public boolean isAttributeDefault(int);
+    method public boolean isEmptyElementTag() throws org.xmlpull.v1.XmlPullParserException;
+    method public boolean isWhitespace() throws org.xmlpull.v1.XmlPullParserException;
+    method public int next() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public int nextTag() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public String nextText() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public int nextToken() throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void require(int, String, String) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+    method public void setFeature(String, boolean) throws org.xmlpull.v1.XmlPullParserException;
+    method public void setInput(java.io.Reader) throws org.xmlpull.v1.XmlPullParserException;
+    method public void setInput(java.io.InputStream, String) throws org.xmlpull.v1.XmlPullParserException;
+    method public void setProperty(String, Object) throws org.xmlpull.v1.XmlPullParserException;
+    field public static final int CDSECT = 5; // 0x5
+    field public static final int COMMENT = 9; // 0x9
+    field public static final int DOCDECL = 10; // 0xa
+    field public static final int END_DOCUMENT = 1; // 0x1
+    field public static final int END_TAG = 3; // 0x3
+    field public static final int ENTITY_REF = 6; // 0x6
+    field public static final String FEATURE_PROCESS_DOCDECL = "http://xmlpull.org/v1/doc/features.html#process-docdecl";
+    field public static final String FEATURE_PROCESS_NAMESPACES = "http://xmlpull.org/v1/doc/features.html#process-namespaces";
+    field public static final String FEATURE_REPORT_NAMESPACE_ATTRIBUTES = "http://xmlpull.org/v1/doc/features.html#report-namespace-prefixes";
+    field public static final String FEATURE_VALIDATION = "http://xmlpull.org/v1/doc/features.html#validation";
+    field public static final int IGNORABLE_WHITESPACE = 7; // 0x7
+    field public static final String NO_NAMESPACE = "";
+    field public static final int PROCESSING_INSTRUCTION = 8; // 0x8
+    field public static final int START_DOCUMENT = 0; // 0x0
+    field public static final int START_TAG = 2; // 0x2
+    field public static final int TEXT = 4; // 0x4
+    field public static final String[] TYPES;
+  }
+
+  public class XmlPullParserException extends java.lang.Exception {
+    ctor public XmlPullParserException(String);
+    ctor public XmlPullParserException(String, org.xmlpull.v1.XmlPullParser, Throwable);
+    method public int getColumnNumber();
+    method public Throwable getDetail();
+    method public int getLineNumber();
+    field protected int column;
+    field protected Throwable detail;
+    field protected int row;
+  }
+
+  public class XmlPullParserFactory {
+    ctor protected XmlPullParserFactory();
+    method public boolean getFeature(String);
+    method public boolean isNamespaceAware();
+    method public boolean isValidating();
+    method public static org.xmlpull.v1.XmlPullParserFactory newInstance() throws org.xmlpull.v1.XmlPullParserException;
+    method public static org.xmlpull.v1.XmlPullParserFactory newInstance(String, Class) throws org.xmlpull.v1.XmlPullParserException;
+    method public org.xmlpull.v1.XmlPullParser newPullParser() throws org.xmlpull.v1.XmlPullParserException;
+    method public org.xmlpull.v1.XmlSerializer newSerializer() throws org.xmlpull.v1.XmlPullParserException;
+    method public void setFeature(String, boolean) throws org.xmlpull.v1.XmlPullParserException;
+    method public void setNamespaceAware(boolean);
+    method public void setValidating(boolean);
+    field public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
+    field protected String classNamesLocation;
+    field protected java.util.HashMap<java.lang.String,java.lang.Boolean> features;
+    field protected java.util.ArrayList parserClasses;
+    field protected java.util.ArrayList serializerClasses;
+  }
+
+  public interface XmlSerializer {
+    method public org.xmlpull.v1.XmlSerializer attribute(String, String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void cdsect(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void comment(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void docdecl(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void endDocument() throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public org.xmlpull.v1.XmlSerializer endTag(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void entityRef(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void flush() throws java.io.IOException;
+    method public int getDepth();
+    method public boolean getFeature(String);
+    method public String getName();
+    method public String getNamespace();
+    method public String getPrefix(String, boolean) throws java.lang.IllegalArgumentException;
+    method public Object getProperty(String);
+    method public void ignorableWhitespace(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void processingInstruction(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setFeature(String, boolean) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setOutput(java.io.OutputStream, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setOutput(java.io.Writer) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setPrefix(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void setProperty(String, Object) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public void startDocument(String, Boolean) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public org.xmlpull.v1.XmlSerializer startTag(String, String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public org.xmlpull.v1.XmlSerializer text(String) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+    method public org.xmlpull.v1.XmlSerializer text(char[], int, int) throws java.io.IOException, java.lang.IllegalArgumentException, java.lang.IllegalStateException;
+  }
+
+}
+
+package org.xmlpull.v1.sax2 {
+
+  public class Driver implements org.xml.sax.Attributes org.xml.sax.Locator org.xml.sax.XMLReader {
+    ctor public Driver() throws org.xmlpull.v1.XmlPullParserException;
+    ctor public Driver(org.xmlpull.v1.XmlPullParser) throws org.xmlpull.v1.XmlPullParserException;
+    method public int getColumnNumber();
+    method public org.xml.sax.ContentHandler getContentHandler();
+    method public org.xml.sax.DTDHandler getDTDHandler();
+    method public org.xml.sax.EntityResolver getEntityResolver();
+    method public org.xml.sax.ErrorHandler getErrorHandler();
+    method public boolean getFeature(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public int getIndex(String, String);
+    method public int getIndex(String);
+    method public int getLength();
+    method public int getLineNumber();
+    method public String getLocalName(int);
+    method public Object getProperty(String) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public String getPublicId();
+    method public String getQName(int);
+    method public String getSystemId();
+    method public String getType(int);
+    method public String getType(String, String);
+    method public String getType(String);
+    method public String getURI(int);
+    method public String getValue(int);
+    method public String getValue(String, String);
+    method public String getValue(String);
+    method public void parse(org.xml.sax.InputSource) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parse(String) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void parseSubTree(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xml.sax.SAXException;
+    method public void setContentHandler(org.xml.sax.ContentHandler);
+    method public void setDTDHandler(org.xml.sax.DTDHandler);
+    method public void setEntityResolver(org.xml.sax.EntityResolver);
+    method public void setErrorHandler(org.xml.sax.ErrorHandler);
+    method public void setFeature(String, boolean) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method public void setProperty(String, Object) throws org.xml.sax.SAXNotRecognizedException, org.xml.sax.SAXNotSupportedException;
+    method protected void startElement(String, String, String) throws org.xml.sax.SAXException;
+    field protected static final String APACHE_DYNAMIC_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/dynamic";
+    field protected static final String APACHE_SCHEMA_VALIDATION_FEATURE = "http://apache.org/xml/features/validation/schema";
+    field protected static final String DECLARATION_HANDLER_PROPERTY = "http://xml.org/sax/properties/declaration-handler";
+    field protected static final String LEXICAL_HANDLER_PROPERTY = "http://xml.org/sax/properties/lexical-handler";
+    field protected static final String NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces";
+    field protected static final String NAMESPACE_PREFIXES_FEATURE = "http://xml.org/sax/features/namespace-prefixes";
+    field protected static final String VALIDATION_FEATURE = "http://xml.org/sax/features/validation";
+    field protected org.xml.sax.ContentHandler contentHandler;
+    field protected org.xml.sax.ErrorHandler errorHandler;
+    field protected org.xmlpull.v1.XmlPullParser pp;
+    field protected String systemId;
+  }
+
+}
+
diff --git a/api/module-lib-current.txt b/api/module-lib-current.txt
new file mode 100644
index 0000000..195abb7
--- /dev/null
+++ b/api/module-lib-current.txt
@@ -0,0 +1,14 @@
+// Signature format: 2.0
+package libcore.io {
+
+  public final class Memory {
+    method public static void memmove(@NonNull Object, int, @NonNull Object, int, long);
+    method public static int peekInt(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static short peekShort(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static void pokeInt(@NonNull byte[], int, int, @NonNull java.nio.ByteOrder);
+    method public static void pokeLong(@NonNull byte[], int, long, @NonNull java.nio.ByteOrder);
+    method public static void pokeShort(@NonNull byte[], int, short, @NonNull java.nio.ByteOrder);
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/api/module-lib-removed.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/current-removed.txt
copy to api/module-lib-removed.txt
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/api/removed.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/current-removed.txt
copy to api/removed.txt
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/api/system-current.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/current-removed.txt
copy to api/system-current.txt
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/api/system-removed.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/current-removed.txt
copy to api/system-removed.txt
diff --git a/benchmarks/Android.bp b/benchmarks/Android.bp
index 4f2f157..8548176 100644
--- a/benchmarks/Android.bp
+++ b/benchmarks/Android.bp
@@ -12,6 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_license"],
+}
+
 java_test {
     name: "benchmarks",
     srcs: ["src/**/*.java"],
diff --git a/benchmarks/src/benchmarks/BigIntegerBenchmark.java b/benchmarks/src/benchmarks/BigIntegerBenchmark.java
new file mode 100644
index 0000000..2b78c0a
--- /dev/null
+++ b/benchmarks/src/benchmarks/BigIntegerBenchmark.java
@@ -0,0 +1,235 @@
+/*
+ * 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 benchmarks;
+
+import java.math.BigInteger;
+
+/**
+ * Tries to measure important BigInteger operations across a variety of BigInteger sizes.
+ * Note that BigInteger implementations commonly need to use wildly different algorithms
+ * for different sizes, so relative performance may change substantially depending on the
+ * size of the integer.
+ * This is not structured as a proper benchmark; just run main(), e.g. with
+ * vogar libcore/benchmarks/src/benchmarks/BigIntegerBenchmark.java.
+ */
+public class BigIntegerBenchmark {
+  private static final boolean PRINT_TIMES = true;
+
+  private static long getStartTime() {
+    if (PRINT_TIMES) {
+      return System.nanoTime();
+    } else {
+      return 0;
+    }
+  }
+
+  private static void printTime(String s, long startTime, int reps) {
+    if (PRINT_TIMES) {
+      System.out.println(s
+          + (double)(System.nanoTime() - startTime) / 1000.0 / reps + " usecs / iter");
+    }
+  }
+
+  // A simple sum of products computation, mostly so we can check timing in the
+  // absence of any division. Computes the sum from 1 to n of ((10^prec) << 30) + 1)^2,
+  // repeating the multiplication, but not addition of 1, each time through the loop.
+  // Check the last few bits of the result as we go. Assumes n < 2^30.
+  // Note that we're actually squaring values in computing the product.
+  // That affects the algorithm used by some implementations.
+  private static void inner(int n, int prec) {
+    BigInteger big = BigInteger.TEN.pow(prec).shiftLeft(30).add(BigInteger.ONE);
+    BigInteger sum = BigInteger.ZERO;
+    for (int i = 0; i < n; ++i) {
+      sum = sum.add(big.multiply(big));
+    }
+    if (sum.and(BigInteger.valueOf(0x3fffffff)).intValue() != n) {
+      System.out.println("inner() got " + sum.and(BigInteger.valueOf(0x3fffffff))
+          + " instead of " + n);
+    }
+  }
+
+  // Execute the above rep times, optionally timing it.
+  private static void repeatInner(int n, int prec, int rep) {
+    long startTime = getStartTime();
+    for (int i = 0; i < rep; ++i) {
+      inner(n, prec);
+    }
+    printTime("inner(" + n + "," + prec + ") took ", startTime, rep);
+  }
+
+  // Approximate the sum of the first 1000 terms of the harmonic series (sum of 1/m as m
+  // goes from 1 to n) to about prec digits. The result has an implicit decimal point
+  // prec digits from the right.
+  private static BigInteger harmonic1000(int prec) {
+    BigInteger scaledOne = BigInteger.TEN.pow(prec);
+    BigInteger sum = BigInteger.ZERO;
+    for (int i = 1; i <= 1000; ++i) {
+      sum = sum.add(scaledOne.divide(BigInteger.valueOf(i)));
+    }
+    return sum;
+  }
+
+  // Execute the above rep times, optionally timing it.
+  // Check results for equality, and print one, to compaare against reference.
+  private static void repeatHarmonic1000(int prec, int rep) {
+    long startTime = getStartTime();
+    BigInteger refRes = harmonic1000(prec);
+    for (int i = 1; i < rep; ++i) {
+      BigInteger newRes = harmonic1000(prec);
+      if (!newRes.equals(refRes)) {
+        throw new AssertionError(newRes + " != " + refRes);
+      }
+    }
+    printTime("harmonic(1000) to " + prec + " digits took ", startTime, rep);
+    if (prec >= 50 && !refRes.toString()
+        .startsWith("748547086055034491265651820433390017652167916970")) {
+      throw new AssertionError("harmanic(" + prec + ") incorrectly produced " + refRes);
+    }
+  }
+
+  // Repeatedly execute just the base conversion from the last test, allowing
+  // us to time and check it for consistency as well.
+  private static void repeatToString(int prec, int rep) {
+    BigInteger refRes = harmonic1000(prec);
+    long startTime = getStartTime();
+    String refString = refRes.toString();
+    for (int i = 1; i < rep; ++i) {
+      // Disguise refRes to avoid compiler optimization issues.
+      BigInteger newRes = refRes.shiftLeft(30).add(BigInteger.valueOf(i)).shiftRight(30);
+      // The time-consuming part:
+      String newString = newRes.toString();
+      if (!newString.equals(refString)) {
+        System.out.println(newString + " != " + refString);
+      }
+    }
+    printTime("toString(" + prec + ") took ", startTime, rep);
+  }
+
+  // Compute base^exp, where base and result are scaled/multiplied by scaleBy to make them
+  // integers. exp >= 0 .
+  private static BigInteger myPow(BigInteger base, int exp, BigInteger scaleBy) {
+    if (exp == 0) {
+      return scaleBy; // Return one.
+    } else if ((exp & 1) != 0) {
+      BigInteger tmp = myPow(base, exp - 1, scaleBy);
+      return tmp.multiply(base).divide(scaleBy);
+    } else {
+      BigInteger tmp = myPow(base, exp / 2, scaleBy);
+      return tmp.multiply(tmp).divide(scaleBy);
+    }
+  }
+
+  // Approximate e by computing (1 + 1/n)^n to prec decimal digits.
+  // This isn't necessarily a very good approximation to e.
+  // Return the result, scaled by 10^prec.
+  private static BigInteger eApprox(int n, int prec) {
+    BigInteger scaledOne = BigInteger.TEN.pow(prec);
+    BigInteger base = scaledOne.add(scaledOne.divide(BigInteger.valueOf(n)));
+    return myPow(base, n, scaledOne);
+  }
+
+  // Repeatedly execute and check the above, printing one of the results
+  // to compare to reference.
+  private static void repeatEApprox(int n, int prec, int rep) {
+    long startTime = getStartTime();
+    BigInteger refRes = eApprox(n, prec);
+    for (int i = 1; i < rep; ++i) {
+      BigInteger newRes = eApprox(n, prec);
+      if (!newRes.equals(refRes)) {
+        throw new AssertionError(newRes + " != " + refRes);
+      }
+    }
+    printTime("eApprox(" + n + "," + prec + ") took ", startTime, rep);
+    if (n >= 100000 && prec >= 10 && !refRes.toString().startsWith("271826")) {
+      throw new AssertionError("eApprox(" + n + "," + prec + ") incorrectly produced "
+          + refRes);
+    }
+  }
+
+  // Test / time modPow()
+  private static void repeatModPow(int len, int rep) {
+    BigInteger odd1 = BigInteger.TEN.pow(len / 2).add(BigInteger.ONE);
+    BigInteger odd2 = BigInteger.TEN.pow(len / 2).add(BigInteger.valueOf(17));
+    BigInteger product = odd1.multiply(odd2);
+    BigInteger exponent = BigInteger.TEN.pow(len / 2 - 1);
+    BigInteger base = BigInteger.TEN.pow(len / 4);
+    long startTime = getStartTime();
+    BigInteger lastRes = null;
+    for (int i = 0; i < rep; ++i) {
+      BigInteger newRes = base.modPow(exponent, product);
+      if (i != 0 && !newRes.equals(lastRes)) {
+        System.out.println(newRes + " != " + lastRes);
+      }
+      lastRes = newRes;
+    }
+    printTime("ModPow() at decimal length " + len + " took ", startTime, rep);
+    if (!lastRes.mod(odd1).equals(base.modPow(exponent, odd1))) {
+      throw new AssertionError("ModPow() result incorrect mod odd1:" + odd1
+          + "; lastRes.mod(odd1)=" + lastRes.mod(odd1) + " vs. "
+          + "base.modPow(exponent, odd1)=" + base.modPow(exponent, odd1) + " base="
+          + base + " exponent=" + exponent);
+    }
+    if (!lastRes.mod(odd2).equals(base.modPow(exponent, odd2))) {
+      throw new AssertionError("ModPow() result incorrect mod odd2");
+    }
+  }
+
+  // Test / time modInverse()
+  private static void repeatModInverse(int len, int rep) {
+    BigInteger odd1 = BigInteger.TEN.pow(len / 2).add(BigInteger.ONE);
+    BigInteger odd2 = BigInteger.TEN.pow(len / 2).add(BigInteger.valueOf(17));
+    BigInteger product = odd1.multiply(odd2);
+    BigInteger arg = BigInteger.ONE.shiftLeft(len / 4);
+    long startTime = getStartTime();
+    BigInteger lastRes = null;
+    for (int i = 0; i < rep; ++i) {
+      BigInteger newRes = arg.modInverse(product);
+      if (i != 0 && !newRes.equals(lastRes)) {
+        System.out.println(newRes + " != " + lastRes);
+      }
+      lastRes = newRes;
+    }
+    printTime("ModInverse() at decimal length " + len + " took ", startTime, rep);
+    if (!lastRes.mod(odd1).equals(arg.modInverse(odd1))) {
+      throw new AssertionError("ModInverse() result incorrect mod odd1");
+    }
+    if (!lastRes.mod(odd2).equals(arg.modInverse(odd2))) {
+      throw new AssertionError("ModInverse() result incorrect mod odd2");
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    for (int i = 10; i <= 10_000; i *= 10) {
+      repeatInner(1000, i, PRINT_TIMES ? Math.min(20_000 / i, 3_000) : 2);
+    }
+    for (int i = 5; i <= 5_000; i *= 10) {
+      repeatHarmonic1000(i, PRINT_TIMES ? Math.min(20_000 / i, 3_000) : 2);
+    }
+    for (int i = 5; i <= 5_000; i *= 10) {
+      repeatToString(i, PRINT_TIMES ? Math.min(20_000 / i, 3_000) : 2);
+    }
+    for (int i = 10; i <= 10_000; i *= 10) {
+      repeatEApprox(100_000, i, PRINT_TIMES ? 50_000 / i : 2);
+    }
+    for (int i = 5; i <= 5_000; i *= 10) {
+      repeatModPow(i, PRINT_TIMES ? 10_000 / i : 2);
+    }
+    for (int i = 10; i <= 10_000; i *= 10) {
+      repeatModInverse(i, PRINT_TIMES ? 20_000 / i : 2);
+    }
+  }
+}
diff --git a/benchmarks/src/benchmarks/LocaleDataBenchmark.java b/benchmarks/src/benchmarks/LocaleDataBenchmark.java
new file mode 100644
index 0000000..adf6768
--- /dev/null
+++ b/benchmarks/src/benchmarks/LocaleDataBenchmark.java
@@ -0,0 +1,40 @@
+/*
+ * 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 benchmarks;
+
+import com.google.caliper.BeforeExperiment;
+import com.google.caliper.Benchmark;
+import java.util.Locale;
+import libcore.icu.LocaleData;
+
+public final class LocaleDataBenchmark {
+    private static final Locale[] TEST_LOCALES = new Locale[]  {
+        Locale.forLanguageTag("en-US"),
+        Locale.forLanguageTag("jp-JP"),
+        Locale.forLanguageTag("es-419"),
+        Locale.forLanguageTag("ar-EG"),
+        Locale.forLanguageTag("zh-CN"),
+    };
+
+    public void timeInitLocaleData(int reps) {
+        for (int rep = 0; rep < reps; ++rep) {
+            for (Locale locale : TEST_LOCALES) {
+                LocaleData.initLocaleData(locale);
+            }
+        }
+    }
+}
diff --git a/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java b/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
index 81a3ab5..f513bf4 100644
--- a/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
+++ b/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
@@ -20,12 +20,13 @@
 import java.util.Random;
 
 /**
- * This pretends to measure performance of operations on small BigIntegers.
- * Given our current implementation, this is really a way to measure performance of
- * finalization and JNI.
+ * This measures performance of operations on small BigIntegers.
  * We manually determine the number of iterations so that it should cause total memory
  * allocation on the order of a few hundred megabytes.  Due to BigInteger's reliance on
  * finalization, these may unfortunately all be kept around at once.
+ *
+ * This is not structured as a proper benchmark; just run main(), e.g. with
+ * vogar libcore/benchmarks/src/benchmarks/SmallBigIntegerBenchmark.java
  */
 public class SmallBigIntegerBenchmark {
     // We allocate about 2 1/3 BigIntegers per iteration.
diff --git a/benchmarks/src/benchmarks/regression/CharacterBenchmark.java b/benchmarks/src/benchmarks/regression/CharacterBenchmark.java
index bb9a51f..bd907f8 100644
--- a/benchmarks/src/benchmarks/regression/CharacterBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/CharacterBenchmark.java
@@ -56,21 +56,21 @@
 
     // A fake benchmark to give us a baseline.
     public boolean timeIsSpace(int reps) {
-        boolean dummy = false;
+        boolean fake = false;
         if (overload == Overload.CHAR) {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
-                    dummy ^= ((char) ch == ' ');
+                    fake ^= ((char) ch == ' ');
                 }
             }
         } else {
             for (int i = 0; i < reps; ++i) {
                 for (int ch = 0; ch < 65536; ++ch) {
-                    dummy ^= (ch == ' ');
+                    fake ^= (ch == ' ');
                 }
             }
         }
-        return dummy;
+        return fake;
     }
 
     public void timeDigit(int reps) {
diff --git a/benchmarks/src/benchmarks/regression/LoopingBackwardsBenchmark.java b/benchmarks/src/benchmarks/regression/LoopingBackwardsBenchmark.java
index f0a474c..7456af2 100644
--- a/benchmarks/src/benchmarks/regression/LoopingBackwardsBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/LoopingBackwardsBenchmark.java
@@ -27,22 +27,22 @@
   @Param({"2", "20", "2000", "20000000"}) int max;
 
   public int timeForwards(int reps) {
-    int dummy = 0;
+    int fake = 0;
     for (int i = 0; i < reps; i++) {
       for (int j = 0; j < max; j++) {
-        dummy += j;
+        fake += j;
       }
     }
-    return dummy;
+    return fake;
   }
 
   public int timeBackwards(int reps) {
-    int dummy = 0;
+    int fake = 0;
     for (int i = 0; i < reps; i++) {
       for (int j = max - 1; j >= 0; j--) {
-        dummy += j;
+        fake += j;
       }
     }
-    return dummy;
+    return fake;
   }
 }
diff --git a/benchmarks/src/benchmarks/regression/NativeMethodBenchmark.java b/benchmarks/src/benchmarks/regression/NativeMethodBenchmark.java
deleted file mode 100644
index dbb6308..0000000
--- a/benchmarks/src/benchmarks/regression/NativeMethodBenchmark.java
+++ /dev/null
@@ -1,133 +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 org.apache.harmony.dalvik.NativeTestTarget;
-
-public class NativeMethodBenchmark {
-    public void time_emptyJniStaticSynchronizedMethod0(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticSynchronizedMethod0();
-        }
-    }
-
-    public void time_emptyJniSynchronizedMethod0(int reps) throws Exception {
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniSynchronizedMethod0();
-        }
-    }
-
-
-    public void time_emptyJniMethod0(int reps) throws Exception {
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod0();
-        }
-    }
-
-    public void time_emptyJniMethod6(int reps) throws Exception {
-        int a = -1;
-        int b = 0;
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod6(a, b, 1, 2, 3, i);
-        }
-    }
-
-    public void time_emptyJniMethod6L(int reps) throws Exception {
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod6L(null, null, null, null, null, null);
-        }
-    }
-
-    public void time_emptyJniStaticMethod6L(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod6L(null, null, null, null, null, null);
-        }
-    }
-    public void time_emptyJniStaticMethod0(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod0();
-        }
-    }
-
-    public void time_emptyJniStaticMethod6(int reps) throws Exception {
-        int a = -1;
-        int b = 0;
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod6(a, b, 1, 2, 3, i);
-        }
-    }
-
-    public void time_emptyJniMethod0_Fast(int reps) throws Exception {
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod0_Fast();
-        }
-    }
-
-    public void time_emptyJniMethod6_Fast(int reps) throws Exception {
-        int a = -1;
-        int b = 0;
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod6_Fast(a, b, 1, 2, 3, i);
-        }
-    }
-
-    public void time_emptyJniMethod6L_Fast(int reps) throws Exception {
-        NativeTestTarget n = new NativeTestTarget();
-        for (int i = 0; i < reps; ++i) {
-            n.emptyJniMethod6L_Fast(null, null, null, null, null, null);
-        }
-    }
-
-    public void time_emptyJniStaticMethod6L_Fast(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod6L_Fast(null, null, null, null, null, null);
-        }
-    }
-    public void time_emptyJniStaticMethod0_Fast(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod0_Fast();
-        }
-    }
-
-    public void time_emptyJniStaticMethod6_Fast(int reps) throws Exception {
-        int a = -1;
-        int b = 0;
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod6_Fast(a, b, 1, 2, 3, i);
-        }
-    }
-
-    public void time_emptyJniStaticMethod0_Critical(int reps) throws Exception {
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod0_Critical();
-        }
-    }
-
-    public void time_emptyJniStaticMethod6_Critical(int reps) throws Exception {
-        int a = -1;
-        int b = 0;
-        for (int i = 0; i < reps; ++i) {
-            NativeTestTarget.emptyJniStaticMethod6_Critical(a, b, 1, 2, 3, i);
-        }
-    }
-}
diff --git a/benchmarks/src/benchmarks/regression/PriorityQueueBenchmark.java b/benchmarks/src/benchmarks/regression/PriorityQueueBenchmark.java
index a5b02b4..5b80785 100644
--- a/benchmarks/src/benchmarks/regression/PriorityQueueBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/PriorityQueueBenchmark.java
@@ -67,7 +67,7 @@
     }
 
     public boolean timeRemove(int reps) {
-        boolean dummy = false;
+        boolean fake = false;
         int elementsSize = seekElements.size();
         // At most allow the queue to empty 10%.
         int resizingThreshold = queueSize / 10;
@@ -78,8 +78,8 @@
             if (i % resizingThreshold == 0) {
                 usepq = new PriorityQueue<Integer>(pq);
             }
-            dummy = usepq.remove(seekElements.get(i % elementsSize));
+            fake = usepq.remove(seekElements.get(i % elementsSize));
         }
-        return dummy;
+        return fake;
     }
 }
diff --git a/benchmarks/src/benchmarks/regression/StringToBytesBenchmark.java b/benchmarks/src/benchmarks/regression/StringToBytesBenchmark.java
index 8b2222472..f43b32e 100644
--- a/benchmarks/src/benchmarks/regression/StringToBytesBenchmark.java
+++ b/benchmarks/src/benchmarks/regression/StringToBytesBenchmark.java
@@ -26,7 +26,11 @@
         L_16(makeString(16)),
         L_64(makeString(64)),
         L_256(makeString(256)),
-        L_512(makeString(512));
+        L_512(makeString(512)),
+        A_16(makeAsciiString(16)),
+        A_64(makeAsciiString(64)),
+        A_256(makeAsciiString(256)),
+        A_512(makeAsciiString(512));
 
         private final String value;
 
@@ -43,6 +47,14 @@
         return new String(chars);
     }
 
+    private static final String makeAsciiString(int length) {
+        char[] chars = new char[length];
+        for (int i = 0; i < length; ++i) {
+            chars[i] = ((i & 0x7f) != 0) ? (char) (i & 0x7f) : '?';
+        }
+        return new String(chars);
+    }
+
     @Param StringLengths string;
 
     public void timeGetBytesUtf8(int nreps) {
diff --git a/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java b/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java
index 8f7bcd2..c05ce06 100644
--- a/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java
+++ b/dalvik/src/main/java/dalvik/annotation/compat/VersionCodes.java
@@ -15,7 +15,6 @@
  */
 package dalvik.annotation.compat;
 
-import libcore.api.CorePlatformApi;
 import libcore.api.IntraCoreApi;
 
 /**
@@ -30,7 +29,6 @@
  *
  * {@hide}
  */
-@CorePlatformApi
 @IntraCoreApi
 public class VersionCodes {
 
@@ -38,23 +36,39 @@
     }
 
     /**
+     * The version code for current development build, which has not yet turned into an official
+     * release.
+     */
+    @IntraCoreApi
+    public static final int CUR_DEVELOPMENT = 10000;
+
+    /**
      * 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;
 
     /**
      * The version code for Android Q (API version 29).
      */
-    @CorePlatformApi
     @IntraCoreApi
     public static final int Q = 29;
+
+    /**
+     * The version code for Android R (API version 30).
+     */
+    @IntraCoreApi
+    public static final int R = 30;
+
+    /**
+     * The version code for Android S (API version TBD).
+     */
+    @IntraCoreApi
+    public static final int S = CUR_DEVELOPMENT;
 }
diff --git a/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java b/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
index f25233c..847e4df 100644
--- a/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
+++ b/dalvik/src/main/java/dalvik/annotation/optimization/FastNative.java
@@ -73,6 +73,7 @@
  * @hide
  */
 @libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
 @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/system/AppSpecializationHooks.java b/dalvik/src/main/java/dalvik/system/AppSpecializationHooks.java
new file mode 100644
index 0000000..28022ab
--- /dev/null
+++ b/dalvik/src/main/java/dalvik/system/AppSpecializationHooks.java
@@ -0,0 +1,45 @@
+/*
+ * 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 dalvik.system;
+
+import libcore.api.CorePlatformApi;
+
+/**
+ * Used by frameworks to specialize libcore in an app process.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public class AppSpecializationHooks {
+
+    /**
+     * Called in {@link android.app.ActivityThread}, but before binding the application. This method
+     * should be called only after {@link android.compat.Compatibility#setCallbacks}
+     * has been invoked to handle the app compat queries from
+     * {@link android.compat.Compatibility#isChangeEnabled(long)}.
+     *
+     * This is a good place to change system properties / clear cache due to an app compat change
+     * before an app starts.
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void handleCompatChangesBeforeBindingApplication() {
+        com.android.i18n.system.AppSpecializationHooks
+                .handleCompatChangesBeforeBindingApplication();
+    }
+}
diff --git a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
index ee20d80..aef8adf 100644
--- a/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java
@@ -29,6 +29,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 import sun.misc.CompoundEnumeration;
 
 /**
@@ -128,6 +130,9 @@
                 : Arrays.copyOf(sharedLibraryLoaders, sharedLibraryLoaders.length);
         this.pathList = new DexPathList(this, dexPath, librarySearchPath, null, isTrusted);
 
+        // Run background verification after having set 'pathList'.
+        this.pathList.maybeRunBackgroundVerification(this);
+
         reportClassLoaderChain();
     }
 
@@ -136,7 +141,7 @@
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public void reportClassLoaderChain() {
         if (reporter == null) {
             return;
@@ -186,6 +191,8 @@
         this.sharedLibraryLoaders = null;
         this.pathList = new DexPathList(this, librarySearchPath);
         this.pathList.initByteBufferDexPath(dexFiles);
+        // Run background verification after having set 'pathList'.
+        this.pathList.maybeRunBackgroundVerification(this);
     }
 
     @Override
@@ -215,11 +222,15 @@
     }
 
     /**
+     * Adds a new dex path to path list.
+     *
+     * @param dexPath dex path to add to path list
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public void addDexPath(String dexPath) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public void addDexPath(@Nullable String dexPath) {
         addDexPath(dexPath, false /*isTrusted*/);
     }
 
@@ -233,11 +244,14 @@
 
     /**
      * Adds additional native paths for consideration in subsequent calls to
-     * {@link #findLibrary(String)}
+     * {@link #findLibrary(String)}.
+     *
+     * @param libPaths collection of paths to be added to path list
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public void addNativePath(Collection<String> libPaths) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public void addNativePath(@NonNull Collection<String> libPaths) {
         pathList.addNativePath(libPaths);
     }
 
@@ -289,7 +303,7 @@
      * provide it, in order to make all those hopeful callers of
      * {@code myClass.getPackage().getName()} happy. Thus we construct
      * a {@code Package} object the first time it is being requested
-     * and fill most of the fields with dummy values. The {@code
+     * and fill most of the fields with fake values. The {@code
      * Package} object is then put into the {@code ClassLoader}'s
      * package cache, so we see the same one next time. We don't
      * create {@code Package} objects for {@code null} arguments or
@@ -324,11 +338,16 @@
     }
 
     /**
+     * Returns colon-separated set of directories where libraries should be
+     * searched for first, before the standard set of directories.
+     *
+     * @return colon-separated set of search directories
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public String getLdLibraryPath() {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public @NonNull String getLdLibraryPath() {
         StringBuilder result = new StringBuilder();
         for (File directory : pathList.getNativeLibraryDirectories()) {
             if (result.length() > 0) {
@@ -349,11 +368,11 @@
      * Once set, all new instances of BaseDexClassLoader will report upon
      * constructions the loaded dex files.
      *
-     * @param newReporter the new Reporter. Setting null will cancel reporting.
+     * @param newReporter the new Reporter. Setting {@code null} will cancel reporting.
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static void setReporter(Reporter newReporter) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void setReporter(@Nullable Reporter newReporter) {
         reporter = newReporter;
     }
 
@@ -365,9 +384,12 @@
     }
 
     /**
+     * Reports the construction of a {@link BaseDexClassLoader} and provides opaque
+     * information about the class loader chain.
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public interface Reporter {
         /**
          * Reports the construction of a BaseDexClassLoader and provides opaque information about
@@ -379,7 +401,7 @@
          * @param contextsMap A map from dex file paths to the class loader context used to load
          *     each dex file.
          */
-        @libcore.api.CorePlatformApi
-        void report(Map<String, String> contextsMap);
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+        void report(@NonNull Map<String, String> contextsMap);
     }
 }
diff --git a/dalvik/src/main/java/dalvik/system/BlockGuard.java b/dalvik/src/main/java/dalvik/system/BlockGuard.java
index 192e450..a4ad9ce 100644
--- a/dalvik/src/main/java/dalvik/system/BlockGuard.java
+++ b/dalvik/src/main/java/dalvik/system/BlockGuard.java
@@ -34,7 +34,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.IntraCoreApi
 public final class BlockGuard {
 
@@ -46,20 +46,20 @@
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public interface Policy {
         /**
          * Called on disk writes.
          */
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         void onWriteToDisk();
 
         /**
          * Called on disk reads.
          */
         @UnsupportedAppUsage
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         void onReadFromDisk();
 
         /**
@@ -72,7 +72,7 @@
         /**
          * Called on unbuffered input/ouput operations.
          */
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         void onUnbufferedIO();
 
         /**
@@ -83,10 +83,12 @@
         /**
          * 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.
+         * there. The bits in the mask are from the {@code DISALLOW_*} and
+         * {@code PENALTY_*} constants declared in {@code StrictMode} class.
+         *
+         * @return policy bitmask
          */
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         int getPolicyMask();
     }
 
@@ -94,7 +96,7 @@
      * Per-process interface used to implement {@code StrictMode.VmPolicy}.
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public interface VmPolicy {
         /**
          * Called by core libraries code when the given path is accessed. This
@@ -115,12 +117,12 @@
          * @param path The path in the local file system that is being accessed
          *            for reading or writing.
          */
-        @libcore.api.CorePlatformApi
-        void onPathAccess(String path);
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+        void onPathAccess(@NonNull String path);
     }
 
     /**
-     * @deprecated no longer actively used, but kept intact for greylist.
+     * @deprecated no longer actively used, but kept intact for hidden API lists.
      */
     @Deprecated
     public static class BlockGuardPolicyException extends RuntimeException {
@@ -168,7 +170,7 @@
      * The default, permissive per-thread policy.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final Policy LAX_POLICY = new Policy() {
         @Override public String toString() { return "LAX_POLICY"; }
         @Override public void onWriteToDisk() {}
@@ -186,7 +188,7 @@
     /**
      * The default, permissive per-process policy.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final VmPolicy LAX_VM_POLICY = new VmPolicy() {
         @Override public String toString() { return "LAX_VM_POLICY"; }
         @Override public void onPathAccess(String path) {}
@@ -208,7 +210,7 @@
      *         instance if nothing else is set.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public static @NonNull Policy getThreadPolicy() {
         return threadPolicy.get();
@@ -224,7 +226,7 @@
      *            want to unset the active policy.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setThreadPolicy(@NonNull Policy policy) {
         threadPolicy.set(Objects.requireNonNull(policy));
     }
@@ -235,7 +237,7 @@
      * @return the current process's policy. Will return the
      *         {@link #LAX_VM_POLICY} instance if nothing else is set.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static @NonNull VmPolicy getVmPolicy() {
         return vmPolicy;
     }
@@ -249,7 +251,7 @@
      * @param policy policy to set. Use the public {@link #LAX_VM_POLICY} if you
      *            want to unset the active policy.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setVmPolicy(@NonNull VmPolicy policy) {
         vmPolicy = Objects.requireNonNull(policy);
     }
diff --git a/dalvik/src/main/java/dalvik/system/CloseGuard.java b/dalvik/src/main/java/dalvik/system/CloseGuard.java
index 99ddf3e..a53efb3 100644
--- a/dalvik/src/main/java/dalvik/system/CloseGuard.java
+++ b/dalvik/src/main/java/dalvik/system/CloseGuard.java
@@ -110,7 +110,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.IntraCoreApi
 public final class CloseGuard {
 
@@ -140,9 +140,11 @@
     /**
      * Returns a CloseGuard instance. {@code #open(String)} can be used to set
      * up the instance to warn on failure to close.
+     *
+     * @return {@link CloseGuard} instance.
      */
     @UnsupportedAppUsage(trackingBug=111170242)
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public static CloseGuard get() {
         return new CloseGuard();
@@ -154,9 +156,11 @@
      * if enabled is true. If a stack trace was captured, the {@link
      * #getReporter() reporter} is informed of unclosed resources; otherwise a
      * one-line warning is logged.
+     *
+     * @param enabled whether stack capture and tracking is enabled.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setEnabled(boolean enabled) {
         CloseGuard.stackAndTrackingEnabled = enabled;
     }
@@ -171,9 +175,11 @@
     /**
      * Used to replace default Reporter used to warn of CloseGuard
      * violations when stack tracking is enabled. Must be non-null.
+     *
+     * @param rep replacement for default Reporter.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setReporter(Reporter rep) {
         if (rep == null) {
             throw new NullPointerException("reporter == null");
@@ -183,8 +189,10 @@
 
     /**
      * Returns non-null CloseGuard.Reporter.
+     *
+     * @return CloseGuard's Reporter.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static Reporter getReporter() {
         return reporter;
     }
@@ -224,7 +232,7 @@
      * @throws NullPointerException if closer is null.
      */
     @UnsupportedAppUsage(trackingBug=111170242)
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public void open(String closer) {
         openWithCallSite(closer, null /* callsite */);
@@ -240,7 +248,7 @@
      * @param closer Non-null name of explicit termination method. Printed by warnIfOpen.
      * @param callsite Non-null string uniquely identifying the callsite.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public void openWithCallSite(String closer, String callsite) {
         // always perform the check for valid API usage...
         if (closer == null) {
@@ -276,7 +284,7 @@
      * finalization.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public void close() {
         Tracker tracker = currentTracker;
@@ -295,7 +303,7 @@
      * directly logs a brief message.
      */
     @UnsupportedAppUsage(trackingBug=111170242)
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public void warnIfOpen() {
         if (closerNameOrAllocationInfo != null) {
@@ -326,13 +334,13 @@
      * Interface to allow customization of reporting behavior.
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public interface Reporter {
         @UnsupportedAppUsage
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         void report(String message, Throwable allocationSite);
 
-        @libcore.api.CorePlatformApi
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         default void report(String message) {}
     }
 
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java b/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
deleted file mode 100644
index 9d5eff1..0000000
--- a/dalvik/src/main/java/dalvik/system/DalvikLogHandler.java
+++ /dev/null
@@ -1,49 +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 dalvik.system;
-
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * An optimized handler for efficient publishing of basic log messages.
- * Implementers should also be subclasses of {@link java.util.logging.Handler}.
- *
- * <p>Unlike the default log handler, this API doesn't require intermediate
- * objects to be allocated for log handling. It also includes a short tag, which
- * may otherwise need to be calculated for each published message.
- *
- * @hide
- */
-@libcore.api.CorePlatformApi
-public interface DalvikLogHandler {
-
-    /**
-     * Publishes a log message. Unlike {@link
-     * java.util.logging.Handler#publish(java.util.logging.LogRecord)}, this
-     * method includes only the raw log message. Log messages that were created
-     * with additional fields (parameters, source methods, etc.) will flow
-     * through the conventional channels instead.
-     *
-     * @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?
-}
diff --git a/dalvik/src/main/java/dalvik/system/DalvikLogging.java b/dalvik/src/main/java/dalvik/system/DalvikLogging.java
deleted file mode 100644
index 5c529a6..0000000
--- a/dalvik/src/main/java/dalvik/system/DalvikLogging.java
+++ /dev/null
@@ -1,50 +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 dalvik.system;
-
-/**
- * Utility methods for logging to {@code DalvikHandlers}.
- *
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class DalvikLogging {
-    private DalvikLogging() {}
-
-    /**
-     * Returns the short logger tag (up to 23 chars) for the given logger name.
-     * 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) {
-            return "null";
-        }
-
-        int length = loggerName.length();
-        if (length <= 23) {
-            return loggerName;
-        }
-
-        int lastPeriod = loggerName.lastIndexOf(".");
-        return length - (lastPeriod + 1) <= 23
-                ? loggerName.substring(lastPeriod + 1)
-                : loggerName.substring(loggerName.length() - 23);
-    }
-}
diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 176fde4..2fb0cdb 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -27,6 +27,8 @@
 import java.util.Enumeration;
 import java.util.List;
 import libcore.io.Libcore;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 
 import dalvik.annotation.optimization.ReachabilitySensitive;
 
@@ -40,7 +42,6 @@
  *     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 {
   /**
@@ -398,15 +399,11 @@
      * 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);
+    /*package*/ void verifyInBackground(ClassLoader classLoader) {
+        verifyInBackgroundNative(mCookie, classLoader);
     }
 
-    private static native void verifyInBackgroundNative(Object mCookie, ClassLoader classLoader,
-            String classLoaderContext);
-
-    /*package*/ static native String getClassLoaderContext(ClassLoader classLoader,
-            DexPathList.Element[] elements);
+    private static native void verifyInBackgroundNative(Object mCookie, ClassLoader classLoader);
 
     /*
      * Returns true if the dex file is backed by a valid oat file.
@@ -464,7 +461,7 @@
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int NO_DEXOPT_NEEDED = 0;
 
     /**
@@ -494,7 +491,7 @@
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int DEX2OAT_FOR_FILTER = 3;
 
 
@@ -519,6 +516,7 @@
      * is used to indicate whether profile information has changed recently.
      *
      * @param fileName the absolute path to the apk/jar file to examine.
+     * @param instructionSet instruction set to examine
      * @param compilerFilter a compiler filter to use for what a caller considers up-to-date.
      * @param classLoaderContext a string encoding the class loader context the dex file
      *        is intended to have at runtime.
@@ -536,13 +534,13 @@
      *         not a file, or not present.
      * @throws java.io.IOException if fileName is not a valid apk/jar file or
      *         if problems occur while parsing it.
-     * @throws java.lang.NullPointerException if fileName is null.
+     * @throws java.lang.NullPointerException if {@code fileName} is {@code null}.
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static native int getDexOptNeeded(String fileName,
-            String instructionSet, String compilerFilter, String classLoaderContext,
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static native int getDexOptNeeded(@NonNull String fileName,
+            @NonNull String instructionSet, @NonNull String compilerFilter, @Nullable String classLoaderContext,
             boolean newProfile, boolean downgrade)
             throws FileNotFoundException, IOException;
 
@@ -565,9 +563,9 @@
      *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final class OptimizationInfo {
-        // The optimization status.
+        // The human readable refined optimization status of the validity of the odex file.
         private final String status;
         // The optimization reason. The reason might be "unknown" if the
         // the compiler artifacts were not annotated during optimizations.
@@ -578,13 +576,23 @@
             this.reason = reason;
         }
 
-        @libcore.api.CorePlatformApi
-        public String getStatus() {
+        /**
+         * Returns the human readable refined status of the validity of the odex file.
+         *
+         * @return optimization status
+         */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+        public @NonNull String getStatus() {
             return status;
         }
 
-        @libcore.api.CorePlatformApi
-        public String getReason() {
+        /**
+         * Returns the reason of a particular optimization used.
+         *
+         * @return optimization reason
+         */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+        public @NonNull String getReason() {
             return reason;
         }
     }
@@ -592,11 +600,16 @@
     /**
      * Retrieves the optimization info for a dex file.
      *
+     * @param fileName       path to dex file
+     * @param instructionSet instruction set to get optimization info for
+     * @return {@link OptimizationInfo} for {@code fileName} dex file
+     * @throws FileNotFoundException if {@code fileName} not found
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static OptimizationInfo getDexFileOptimizationInfo(
-            String fileName, String instructionSet) throws FileNotFoundException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull OptimizationInfo getDexFileOptimizationInfo(
+            @NonNull String fileName, @NonNull String instructionSet) throws FileNotFoundException {
         String[] status = getDexFileOptimizationStatus(fileName, instructionSet);
         return new OptimizationInfo(status[0], status[1]);
     }
@@ -618,34 +631,49 @@
 
     /**
      * Returns the paths of the optimized files generated for {@code fileName}.
-     * If no optimized code exists the method returns null.
+     * If no optimized code exists the method returns {@code null}.
+     *
+     * @param fileName       path to dex file
+     * @param instructionSet instruction set to get optimized files for
+     * @return paths to optimized code, or {@code null} if they do not exist
+     * @throws FileNotFoundException
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static native String[] getDexFileOutputPaths(String fileName, String instructionSet)
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static native @Nullable String[] getDexFileOutputPaths(@NonNull String fileName, @NonNull String instructionSet)
         throws FileNotFoundException;
 
     /**
      * Returns whether the given filter is a valid filter.
      *
+     * @param filter filter string
+     * @return whether given filter string is a valid filter
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public native static boolean isValidCompilerFilter(String filter);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native static boolean isValidCompilerFilter(@NonNull String filter);
 
     /**
      * Returns whether the given filter is based on profiles.
      *
+     * @param filter filter string
+     * @return whether given filter string is based on profiles
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public native static boolean isProfileGuidedCompilerFilter(String filter);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native static boolean isProfileGuidedCompilerFilter(@NonNull String filter);
 
     /**
      * Returns the version of the compiler filter that is not based on profiles.
      * If the input is not a valid filter, or the filter is already not based on
      * profiles, this returns the input.
      *
+     * @param filter filter string
+     * @return version of the compiler filter that is not based on profiles
+     *
      * @hide
      */
     public native static String getNonProfileGuidedCompilerFilter(String filter);
@@ -655,10 +683,13 @@
      * If the input is not a valid filter, or the filter is already suitable for
      * safe mode, this returns the input.
      *
+     * @param filter filter string
+     * @return version of the compiler filter that is suitable for safe mode
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public native static String getSafeModeCompilerFilter(String filter);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native static @NonNull String getSafeModeCompilerFilter(@NonNull String filter);
 
     /**
      * Returns the static file size of the original dex file.
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index 798166c..acf5e66 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -262,23 +262,7 @@
         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);
@@ -291,6 +275,21 @@
         }
     }
 
+    /* package */ void maybeRunBackgroundVerification(ClassLoader loader) {
+        // Spawn background thread to verify all classes and cache verification results.
+        // Must be called *after* `this.dexElements` has been initialized and `loader.pathList`
+        // has been set for ART to find its classes (the fields are hardcoded in ART and dex
+        // files iterated over in the order of the array).
+        // 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.
+        for (Element element : dexElements) {
+            if (element.dexFile != null && !element.dexFile.isBackedByOatFile()) {
+                element.dexFile.verifyInBackground(loader);
+            }
+        }
+    }
+
     /**
      * Splits the given dex path string into elements using the path
      * separator, pruning out any elements that do not refer to existing
diff --git a/dalvik/src/main/java/dalvik/system/NativeStart.java b/dalvik/src/main/java/dalvik/system/NativeStart.java
index 1382823..ba2661e 100644
--- a/dalvik/src/main/java/dalvik/system/NativeStart.java
+++ b/dalvik/src/main/java/dalvik/system/NativeStart.java
@@ -17,7 +17,7 @@
 package dalvik.system;
 
 /**
- * Dummy class used during JNI initialization.  The JNI functions want
+ * Fake class used during JNI initialization.  The JNI functions want
  * to be able to create objects, and the VM needs to discard the references
  * when the function returns.  That gets a little weird when we're
  * calling JNI functions from the C main(), and there's no Java stack frame
@@ -33,7 +33,7 @@
 class NativeStart {
     private NativeStart() {}
 
-    private static native void main(String[] dummy);
+    private static native void main(String[] fake);
 
     private static native void run();
 }
diff --git a/dalvik/src/main/java/dalvik/system/PathClassLoader.java b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
index cbd494f..d5d17f3 100644
--- a/dalvik/src/main/java/dalvik/system/PathClassLoader.java
+++ b/dalvik/src/main/java/dalvik/system/PathClassLoader.java
@@ -16,6 +16,9 @@
 
 package dalvik.system;
 
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
 /**
  * Provides a simple {@link ClassLoader} implementation that operates on a list
  * of files and directories in the local file system, but does not attempt to
@@ -65,12 +68,37 @@
     }
 
     /**
+     * Creates a {@code PathClassLoader} that operates on two given
+     * lists of files and directories. The entries of the first list
+     * should be one of the following:
+     *
+     * <ul>
+     * <li>JAR/ZIP/APK files, possibly containing a "classes.dex" file as
+     * well as arbitrary resources.
+     * <li>Raw ".dex" files (not inside a zip file).
+     * </ul>
+     *
+     * The entries of the second list should be directories containing
+     * native library files.
+     *
+     * @param dexPath the list of jar/apk files containing classes and
+     * resources, delimited by {@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 sharedLibraryLoaders class loaders of Java shared libraries
+     * used by this new class loader. The shared library loaders are always
+     * checked before the {@code dexPath} when looking
+     * up classes and resources.
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public PathClassLoader(
-            String dexPath, String librarySearchPath, ClassLoader parent,
-            ClassLoader[] sharedLibraryLoaders) {
+            @NonNull String dexPath, @Nullable String librarySearchPath, @Nullable ClassLoader parent,
+            @Nullable 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
index f1af867..9f826ea 100644
--- a/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
+++ b/dalvik/src/main/java/dalvik/system/RuntimeHooks.java
@@ -16,12 +16,9 @@
 
 package dalvik.system;
 
-import dalvik.system.ThreadPrioritySetter;
-
 import java.util.Objects;
 import java.util.TimeZone;
 import java.util.function.Supplier;
-
 import libcore.util.NonNull;
 import libcore.util.Nullable;
 
@@ -35,15 +32,11 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class RuntimeHooks {
 
     private static Supplier<String> zoneIdSupplier;
 
-    // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
-    private static volatile ThreadPrioritySetter threadPrioritySetter;
-    // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
-
     private RuntimeHooks() {
         // No need to construct an instance. All methods are static.
     }
@@ -54,12 +47,14 @@
      *
      * <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).
+     * {@link TimeZone#setDefault(TimeZone)} is called with a non-{@code null} value in the interim).
      *
      * <p>Once set the supplier cannot be changed.
+     *
+     * @param zoneIdSupplier new {@link Supplier} of the time zone ID
      */
-    @libcore.api.CorePlatformApi
-    public static void setTimeZoneIdSupplier(Supplier<String> zoneIdSupplier) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void setTimeZoneIdSupplier(@NonNull Supplier<String> zoneIdSupplier) {
         if (RuntimeHooks.zoneIdSupplier != null) {
             throw new UnsupportedOperationException("zoneIdSupplier instance already set");
         }
@@ -80,33 +75,12 @@
      * handlers to run, this handler should never terminate this process. Any
      * throwables thrown by the handler will be ignored by
      * {@link Thread#dispatchUncaughtException(Throwable)}.
+     *
+     * @param uncaughtExceptionHandler handler for uncaught exceptions
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setUncaughtExceptionPreHandler(
-            Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
+            @Nullable Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
         Thread.setUncaughtExceptionPreHandler(uncaughtExceptionHandler);
     }
-
-    // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
-    /**
-     * Sets a {@link ThreadPrioritySetter} that will be invoked instead of
-     * the default implementation during {@link Thread.setPriority(int)}.
-     * @hide
-     */
-    @libcore.api.CorePlatformApi
-    public static void setThreadPrioritySetter(@NonNull ThreadPrioritySetter threadPrioritySetter) {
-        RuntimeHooks.threadPrioritySetter = Objects.requireNonNull(threadPrioritySetter);
-    }
-
-    /**
-     * Returns the last {@code ThreadPrioritySetter} that has been
-     * {@code #setThreadPrioritySetter(ThreadPrioritySetter) set}, or
-     * null if the setter has not yet been called.
-     * @hide
-     */
-    @libcore.api.CorePlatformApi
-    public static @Nullable ThreadPrioritySetter getThreadPrioritySetter() {
-        return threadPrioritySetter;
-    }
-    // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
 }
diff --git a/dalvik/src/main/java/dalvik/system/SocketTagger.java b/dalvik/src/main/java/dalvik/system/SocketTagger.java
index 0493daa..4a8300d 100644
--- a/dalvik/src/main/java/dalvik/system/SocketTagger.java
+++ b/dalvik/src/main/java/dalvik/system/SocketTagger.java
@@ -27,7 +27,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public abstract class SocketTagger {
 
     private static SocketTagger tagger = new SocketTagger() {
@@ -35,16 +35,19 @@
         @Override public void untag(FileDescriptor socketDescriptor) throws SocketException {}
     };
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public SocketTagger() {
     }
 
     /**
-     * Notified when {@code socketDescriptor} is either assigned to the current
+     * Notified when {@code socketDescriptor} is 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.
+     *
+     * @param socketDescriptor to be assigned to the current thread
+     * @throws SocketException when {@link SocketException} occurs
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public abstract void tag(FileDescriptor socketDescriptor) throws SocketException;
 
     /**
@@ -54,34 +57,77 @@
      *
      * <p><strong>Note:</strong> this method will not be invoked when the socket
      * is closed.
+     *
+     * @param socketDescriptor to be released from the current thread to a connection pool
+     * @throws SocketException when {@link SocketException} occurs
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public abstract void untag(FileDescriptor socketDescriptor) throws SocketException;
 
+    /**
+     * Notified when {@code socket} is 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.
+     *
+     * @param socket to be assigned to the current thread
+     * @throws SocketException when {@link SocketException} occurs
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final void tag(Socket socket) throws SocketException {
         if (!socket.isClosed()) {
             tag(socket.getFileDescriptor$());
         }
     }
 
+    /**
+     * Notified when {@code socket} is released from the current
+     * thread to a connection pool. Implementations of this method should be
+     * thread-safe.
+     *
+     * <p><strong>Note:</strong> this method will not be invoked when the socket
+     * is closed.
+     *
+     * @param socket           to be released from the current thread
+     *                         to a connection pool
+     * @throws SocketException when {@link SocketException} occurs
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final void untag(Socket socket) throws SocketException {
         if (!socket.isClosed()) {
             untag(socket.getFileDescriptor$());
         }
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Notified when {@code socket} is 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.
+     *
+     * @param socket           to be assigned to the current thread
+     * @throws SocketException when {@link SocketException} occurs
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final void tag(DatagramSocket socket) throws SocketException {
         if (!socket.isClosed()) {
             tag(socket.getFileDescriptor$());
         }
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Notified when {@code socket} is released from the current
+     * thread to a connection pool. Implementations of this method should be
+     * thread-safe.
+     *
+     * <p><strong>Note:</strong> this method will not be invoked when the socket
+     * is closed.
+     *
+     * @param socket           to be released from the current thread
+     *                         to a connection pool
+     * @throws SocketException when {@link SocketException} occurs
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final void untag(DatagramSocket socket) throws SocketException {
         if (!socket.isClosed()) {
             untag(socket.getFileDescriptor$());
@@ -90,8 +136,10 @@
 
     /**
      * Sets this process' socket tagger to {@code tagger}.
+     *
+     * @param tagger socket tagger to be assigned to this process
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static synchronized void set(SocketTagger tagger) {
         if (tagger == null) {
             throw new NullPointerException("tagger == null");
@@ -101,9 +149,11 @@
 
     /**
      * Returns this process socket tagger.
+     *
+     * @return {@link SocketTagger} assigned to this process
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static synchronized SocketTagger get() {
         return tagger;
     }
diff --git a/dalvik/src/main/java/dalvik/system/ThreadPrioritySetter.java b/dalvik/src/main/java/dalvik/system/ThreadPrioritySetter.java
deleted file mode 100644
index 484784b..0000000
--- a/dalvik/src/main/java/dalvik/system/ThreadPrioritySetter.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 dalvik.system;
-
-/**
- * Interface for hooking to thread priority runtime setting
- * @hide
- */
-@libcore.api.CorePlatformApi
-@FunctionalInterface
-public interface ThreadPrioritySetter {
-    @libcore.api.CorePlatformApi
-    void setPriority(int nativeTid, int priority);
-}
diff --git a/dalvik/src/main/java/dalvik/system/VMDebug.java b/dalvik/src/main/java/dalvik/system/VMDebug.java
index 4436e3f..a705e24 100644
--- a/dalvik/src/main/java/dalvik/system/VMDebug.java
+++ b/dalvik/src/main/java/dalvik/system/VMDebug.java
@@ -34,13 +34,14 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class VMDebug {
     /**
      * flag for startMethodTracing(), which adds the results from
      * startAllocCounting to the trace key file.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    // Must match android.os.Debug.TRACE_COUNT_ALLOCS.
     public static final int TRACE_COUNT_ALLOCS = 1;
 
     /* constants for getAllocCount */
@@ -56,63 +57,90 @@
     private static final int KIND_EXT_FREED_OBJECTS     = 1<<14;
     private static final int KIND_EXT_FREED_BYTES       = 1<<15;
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of all allocated objects.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_ALLOCATED_OBJECTS =
         KIND_ALLOCATED_OBJECTS;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the cumulative size of all objects allocated.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_ALLOCATED_BYTES =
         KIND_ALLOCATED_BYTES;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of freed objects.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_FREED_OBJECTS =
         KIND_FREED_OBJECTS;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the cumulative size of all freed objects.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_FREED_BYTES =
         KIND_FREED_BYTES;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of times an allocation triggered a blocking GC.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_GC_INVOCATIONS =
         KIND_GC_INVOCATIONS;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of initialized classes.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_CLASS_INIT_COUNT =
         KIND_CLASS_INIT_COUNT;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the cumulative time spent in class initialization.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_GLOBAL_CLASS_INIT_TIME =
         KIND_CLASS_INIT_TIME;
-    public static final int KIND_GLOBAL_EXT_ALLOCATED_OBJECTS =
-        KIND_EXT_ALLOCATED_OBJECTS;
-    public static final int KIND_GLOBAL_EXT_ALLOCATED_BYTES =
-        KIND_EXT_ALLOCATED_BYTES;
-    public static final int KIND_GLOBAL_EXT_FREED_OBJECTS =
-        KIND_EXT_FREED_OBJECTS;
-    public static final int KIND_GLOBAL_EXT_FREED_BYTES =
-        KIND_EXT_FREED_BYTES;
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of all allocated objects for current thread.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_THREAD_ALLOCATED_OBJECTS =
         KIND_ALLOCATED_OBJECTS << 16;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the cumulative size of all objects allocated for current thread.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
+
+    /**
+     * Constant for {@link #getAllocCount(int)}
+     * to get the number of times an allocation triggered a blocking GC for current thread.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_THREAD_GC_INVOCATIONS =
         KIND_GC_INVOCATIONS << 16;
-    public static final int KIND_THREAD_CLASS_INIT_COUNT =
-        KIND_CLASS_INIT_COUNT << 16;
-    public static final int KIND_THREAD_CLASS_INIT_TIME =
-        KIND_CLASS_INIT_TIME << 16;
-    public static final int KIND_THREAD_EXT_ALLOCATED_OBJECTS =
-        KIND_EXT_ALLOCATED_OBJECTS << 16;
-    public static final int KIND_THREAD_EXT_ALLOCATED_BYTES =
-        KIND_EXT_ALLOCATED_BYTES << 16;
-    public static final int KIND_THREAD_EXT_FREED_OBJECTS =
-        KIND_EXT_FREED_OBJECTS << 16;
-    public static final int KIND_THREAD_EXT_FREED_BYTES =
-        KIND_EXT_FREED_BYTES << 16;
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Constant for {@link #getAllocCount(int)} to get all possible stats.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int KIND_ALL_COUNTS = 0xffffffff;
 
     /* all methods are static */
@@ -123,7 +151,7 @@
      *
      * @return the time in milliseconds, or -1 if the debugger is not connected
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native long lastDebuggerActivity();
 
@@ -133,7 +161,7 @@
      *
      * @return true if debugging is enabled
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native boolean isDebuggingEnabled();
 
@@ -143,7 +171,7 @@
      * @return true if (and only if) a debugger is connected
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native boolean isDebuggerConnected();
 
@@ -151,20 +179,11 @@
      * Returns an array of strings that identify VM features.  This is
      * used by DDMS to determine what sorts of operations the VM can
      * perform.
-     */
-    @libcore.api.CorePlatformApi
-    public static native String[] getVmFeatureList();
-
-    /**
-     * Start method tracing with default name, size, and with <code>0</code>
-     * flags.
      *
-     * @deprecated Not used, not needed.
+     * @return array of strings identifying VM features
      */
-    @Deprecated
-    public static void startMethodTracing() {
-        throw new UnsupportedOperationException();
-    }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static native String[] getVmFeatureList();
 
     /**
      * Start method tracing, specifying a file name as well as a default
@@ -178,39 +197,41 @@
      * be created under the /sdcard/ directory. If a name is not given,
      * the default is /sdcard/dmtrace.trace.</p>
      *
-     * @param traceFileName name to give the trace file
-     * @param bufferSize the maximum size of both files combined. If passed
-     * as <code>0</code>, it defaults to 8MB.
-     * @param flags flags to control method tracing. The only one that
-     * is currently defined is {@link #TRACE_COUNT_ALLOCS}.
+     * @param traceFileName   name to give the trace file
+     * @param bufferSize      the maximum size of both files combined. If passed
+     *                        as {@code 0}, it defaults to 8MB.
+     * @param flags           flags to control method tracing. The only one that
+     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
      * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
-     * method instrumentation is used.
-     * @param intervalUs the time between samples in microseconds when
-     * sampling is enabled.
+     *                        method instrumentation is used.
+     * @param intervalUs      the time between samples in microseconds when
+     *                        sampling is enabled.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void startMethodTracing(String traceFileName, int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
         startMethodTracingFilename(traceFileName, checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
     }
 
     /**
-     * Like startMethodTracing(String, int, int), but taking an already-opened
-     * FileDescriptor in which the trace is written.  The file name is also
-     * supplied simply for logging.  Makes a dup of the file descriptor.
-     */
-    public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize,
-                                          int flags, boolean samplingEnabled, int intervalUs) {
-        startMethodTracing(traceFileName, fd, bufferSize, flags, samplingEnabled, intervalUs,
-                           false);
-    }
-
-    /**
-     * Like startMethodTracing(String, int, int), but taking an already-opened
-     * FileDescriptor in which the trace is written.  The file name is also
+     * Like {@link #startMethodTracing(String, int, int)}, but taking an already-opened
+     * {@code FileDescriptor} in which the trace is written.  The file name is also
      * supplied simply for logging.  Makes a dup of the file descriptor.
      * Streams tracing data to the file if streamingOutput is true.
+     *
+     * @param traceFileName   name to give the trace file
+     * @param fd              already opened {@code FileDescriptor} in which trace is written
+     * @param bufferSize      the maximum size of both files combined. If passed
+     *                        as {@code 0}, it defaults to 8MB.
+     * @param flags           flags to control method tracing. The only one that
+     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
+     * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
+     *                        method instrumentation is used.
+     * @param intervalUs      the time between samples in microseconds when
+     *                        sampling is enabled.
+     * @param streamingOutput streams tracing data to the duped {@code fd} file descriptor
+     *                        if {@code streamingOutput} is {@code true}.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void startMethodTracing(String traceFileName, FileDescriptor fd, int bufferSize,
                                           int flags, boolean samplingEnabled, int intervalUs,
                                           boolean streamingOutput) {
@@ -222,11 +243,20 @@
     }
 
     /**
-     * Starts method tracing without a backing file.  When stopMethodTracing
+     * Starts method tracing without a backing file.  When {@link #stopMethodTracing()}
      * is called, the result is sent directly to DDMS.  (If DDMS is not
      * attached when tracing ends, the profiling data will be discarded.)
+     *
+     * @param bufferSize      the maximum size of both files combined. If passed
+     *                        as {@code 0}, it defaults to 8MB.
+     * @param flags           flags to control method tracing. The only one that
+     *                        is currently defined is {@link #TRACE_COUNT_ALLOCS}.
+     * @param samplingEnabled if true, sample profiling is enabled. Otherwise,
+     *                        method instrumentation is used.
+     * @param intervalUs      the time between samples in microseconds when
+     *                        sampling is enabled.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void startMethodTracingDdms(int bufferSize, int flags, boolean samplingEnabled, int intervalUs) {
         startMethodTracingDdmsImpl(checkBufferSize(bufferSize), flags, samplingEnabled, intervalUs);
     }
@@ -251,28 +281,16 @@
      * Determine whether method tracing is currently active and what type is
      * active.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native int getMethodTracingMode();
 
     /**
      * Stops method tracing.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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();
-
-    /**
      * Get an indication of thread CPU usage. The value returned indicates the
      * amount of time that the current thread has spent executing code or
      * waiting for certain types of I/O.
@@ -284,21 +302,37 @@
      * @return the CPU usage. A value of -1 means the system does not support
      *         this feature.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native long threadCpuTimeNanos();
 
     /**
-     * Count the number and aggregate size of memory allocations between
-     * two points.
+     * Starts counting the number and aggregate size of memory allocations.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void startAllocCounting();
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Stops counting the number and aggregate size of memory allocations.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void stopAllocCounting();
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Returns information on the number of objects allocated by the runtime between a
+     * {@link #startAllocCounting() start} and {@link #stopAllocCounting() stop}.
+     *
+     * @param kind either {@code KIND_GLOBAL_*} or {@code KIND_THREAD_*}.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native int getAllocCount(int kind);
-    @libcore.api.CorePlatformApi
+
+    /**
+     * Resets counting the number and aggregate size of memory allocations for the given kinds.
+     *
+     * @param kinds a union of {@code KIND_GLOBAL_*} and {@code KIND_THREAD_*}.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void resetAllocCount(int kinds);
 
     /**
@@ -322,15 +356,22 @@
     /**
      * Count the number of instructions executed between two points.
      */
-    public static native void startInstructionCounting();
-    public static native void stopInstructionCounting();
-    public static native void getInstructionCount(int[] counts);
-    public static native void resetInstructionCount();
+    @Deprecated
+    public static void startInstructionCounting() {}
+    @Deprecated
+    public static void stopInstructionCounting() {}
+    @Deprecated
+    public static void getInstructionCount(int[] counts) {}
+    @Deprecated
+    public static void resetInstructionCount() {}
 
     /**
      * Dumps a list of loaded class to the log file.
+     *
+     * @param flags a union of {@link android.os.Debug.SHOW_FULL_DETAIL},
+     *    {@link android.os.Debug.SHOW_CLASSLOADER}, and {@link android.os.Debug.SHOW_INITIALIZED}.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native void printLoadedClasses(int flags);
 
@@ -339,7 +380,7 @@
      *
      * @return the number of loaded classes
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public static native int getLoadedClassCount();
 
@@ -353,7 +394,7 @@
      *         HPROF support.
      * @throws IOException if an error occurs while opening or writing files.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void dumpHprofData(String filename) throws IOException {
         if (filename == null) {
             throw new NullPointerException("filename == null");
@@ -367,7 +408,7 @@
      * @throws UnsupportedOperationException if the VM was built without
      *         HPROF support.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void dumpHprofDataDdms();
 
     /**
@@ -377,8 +418,9 @@
      *        file name is only used in log messages (and may be null).
      * @param fd Descriptor of open file that will receive the output.
      *        If this is null, the fileName is used instead.
+     * @throws {@link IOException} if an error occurs while opening or writing files.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void dumpHprofData(String fileName, FileDescriptor fd)
             throws IOException {
        dumpHprofData(fileName, fd != null ? fd.getInt$() : -1);
@@ -388,59 +430,26 @@
             throws IOException;
 
     /**
-     * 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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void dumpReferenceTables();
 
     /**
-     * Crashes the VM.  Seriously.  Dumps the interpreter stack trace for
-     * the current thread and then aborts the VM so you can see the native
-     * stack trace.  Useful for figuring out how you got somewhere when
-     * lots of native code is involved.
-     */
-    public static native void crash();
-
-    /**
-     * Together with gdb, provide a handy way to stop the VM at user-tagged
-     * locations.
-     */
-    public static native void infopoint(int id);
-
-    /*
-     * Fake method, inserted into dmtrace output when the garbage collector
-     * runs.  Not actually called.
-     */
-    private static void startGC() {}
-
-    /*
-     * Fake method, inserted into dmtrace output during class preparation
-     * (loading and linking, but not verification or initialization).  Not
-     * actually called.
-     */
-    private static void startClassPrep() {}
-
-    /**
      * Counts the instances of a class.
      * It is the caller's responsibility to do GC if they don't want unreachable
      * objects to get counted.
      *
      * @param klass the class to be counted.
      * @param assignable if true, any instance whose class is assignable to
-     *                   <code>klass</code>, as defined by {@link Class#isAssignableFrom},
+     *                   {@code klass}, as defined by {@link Class#isAssignableFrom},
      *                   is counted. If false, only instances whose class is
-     *                   equal to <code>klass</code> are counted.
+     *                   equal to {@code klass} are counted.
      * @return the number of matching instances.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native long countInstancesOfClass(Class klass, boolean assignable);
 
     /**
@@ -450,14 +459,14 @@
      *
      * @param classes the classes to be counted.
      * @param assignable if true, any instance whose class is assignable to
-     *                   <code>classes[i]</code>, as defined by {@link Class#isAssignableFrom},
+     *                   {@code classes[i]}, as defined by {@link Class#isAssignableFrom},
      *                   is counted. If false, only instances whose class is
-     *                   equal to <code>classes[i]</code> are counted.
+     *                   equal to {@code classes[i]} are counted.
      * @return an array containing the number of matching instances. The value
-     *         for index <code>i</code> is the number of instances of
-     *         the class <code>classes[i]</code>
+     *         for index {@code i} is the number of instances of
+     *         the class {@code classes[i]}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native long[] countInstancesOfClasses(Class[] classes, boolean assignable);
 
     /**
@@ -467,36 +476,15 @@
      *
      * @param classes the classes to get instances of.
      * @param assignable if true, any instance whose class is assignable to
-     *                   <code>classes[i]</code>, as defined by {@link Class#isAssignableFrom},
+     *                   {@code classes[i]}, as defined by {@link Class#isAssignableFrom},
      *                   is included. If false, only instances whose class is
-     *                   equal to <code>classes[i]</code> are included.
+     *                   equal to {@code classes[i]} are included.
      * @return an array containing the list of matching instances. The value
-     *         for index <code>i</code> is an array containing the instances
-     *         of the class <code>classes[i]</code>
+     *         for index {@code i} is an array containing the instances
+     *         of the class {@code classes[i]}
      */
     public static native Object[][] getInstancesOfClasses(Class[] classes, boolean assignable);
 
-    /**
-     * Export the heap per-space stats for dumpsys meminfo.
-     *
-     * The content of the array is:
-     *
-     * <pre>
-     *   data[0] : the application heap space size
-     *   data[1] : the application heap space allocated bytes
-     *   data[2] : the application heap space free bytes
-     *   data[3] : the zygote heap space size
-     *   data[4] : the zygote heap space allocated size
-     *   data[5] : the zygote heap space free size
-     *   data[6] : the large object space size
-     *   data[7] : the large object space allocated bytes
-     *   data[8] : the large object space free bytes
-     * </pre>
-     *
-     * @param data the array into which the stats are written.
-     */
-    public static native void getHeapSpaceStats(long[] data);
-
     /* Map from the names of the runtime stats supported by getRuntimeStat() to their IDs */
     private static final HashMap<String, Integer> runtimeStatsMap = new HashMap<>();
 
@@ -509,17 +497,19 @@
         runtimeStatsMap.put("art.gc.blocking-gc-time", 5);
         runtimeStatsMap.put("art.gc.gc-count-rate-histogram", 6);
         runtimeStatsMap.put("art.gc.blocking-gc-count-rate-histogram", 7);
+        runtimeStatsMap.put("art.gc.objects-allocated", 8);
+        runtimeStatsMap.put("art.gc.total-time-waiting-for-gc", 9);
     }
 
     /**
      * Returns the value of a particular runtime statistic or {@code null} if no
      * such runtime statistic exists.
      *
-     * @param statName
-     *            the name of the runtime statistic to look up.
+     * @param statName the name of the runtime statistic to look up.
+     *
      * @return the value of the runtime statistic.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String getRuntimeStat(String statName) {
         if (statName == null) {
             throw new NullPointerException("statName == null");
@@ -537,7 +527,7 @@
      *
      * @return a map of the names/values of the supported runtime statistics.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static Map<String, String> getRuntimeStats() {
         HashMap<String, String> map = new HashMap<>();
         String[] values = getRuntimeStatsInternal();
@@ -555,19 +545,12 @@
     /**
      * Attaches an agent to the VM.
      *
-     * @param agent The path to the agent .so file plus optional agent arguments.
-     */
-    public static void attachAgent(String agent) throws IOException {
-        attachAgent(agent, null);
-    }
-
-    /**
-     * Attaches an agent to the VM.
-     *
-     * @param agent The path to the agent .so file plus optional agent arguments.
+     * @param agent       The path to the agent .so file plus optional agent arguments.
      * @param classLoader The classloader to use as a loading context.
+     *
+     * @throws IOException if an error occurs while opening {@code agent} file.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void attachAgent(String agent, ClassLoader classLoader) throws IOException {
         nativeAttachAgent(agent, classLoader);
     }
@@ -593,6 +576,6 @@
      *
      * @param stackDepth The number of frames captured for each stack trace.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void setAllocTrackerStackDepth(int stackDepth);
 }
diff --git a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
index 7e8fe36..9f6ca69 100644
--- a/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
+++ b/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
@@ -16,12 +16,14 @@
 
 package dalvik.system;
 
-import android.icu.impl.CacheValue;
-import android.icu.text.DecimalFormatSymbols;
-import android.icu.util.ULocale;
+import libcore.icu.ICU;
 
 import java.io.File;
 import java.io.FileDescriptor;
+import java.lang.reflect.Method;
+import java.lang.ClassNotFoundException;
+import java.lang.NoSuchMethodException;
+import java.lang.ReflectiveOperationException;
 
 /**
  * Provides hooks for the zygote to call back into the runtime to perform
@@ -29,9 +31,10 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class ZygoteHooks {
     private static long token;
+    private static Method enableMemoryMappedDataMethod;
 
     /** All methods are static, no need to instantiate. */
     private ZygoteHooks() {
@@ -41,39 +44,38 @@
      * 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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void startZygoteNoThreadCreation();
 
     /**
      * Called when the zygote begins preloading classes and data.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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);
+        com.android.i18n.system.ZygoteHooks.onBeginPreload();
 
-        // 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);
+        ICU.initializeCacheInZygote();
+
+        // Look up JaCoCo on the boot classpath, if it exists. This will be used later for enabling
+        // memory-mapped Java coverage.
+        try {
+          Class<?> jacocoOfflineClass = Class.forName("org.jacoco.agent.rt.internal.Offline");
+          enableMemoryMappedDataMethod = jacocoOfflineClass.getMethod("enableMemoryMappedData");
+        } catch (ClassNotFoundException e) {
+          // JaCoCo was not on the boot classpath, so this is not a coverage build.
+        } catch (NoSuchMethodException e) {
+          // Method was not found in the JaCoCo Offline class. The version of JaCoCo is not
+          // compatible with memory-mapped coverage.
+          throw new RuntimeException(e);
         }
-
-        // Framework's LocalLog is used during app start-up. It indirectly uses the current ICU time
-        // zone. Pre-loading the current time zone in ICU improves app startup time. b/150605074
-        // We're being explicit about the fully qualified name of the TimeZone class to avoid
-        // confusion with java.util.TimeZome.getDefault().
-        android.icu.util.TimeZone.getDefault();
     }
 
     /**
      * Called when the zygote has completed preloading classes and data.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void onEndPreload() {
-        // All cache references created by ICU from this point will be soft.
-        CacheValue.setStrength(CacheValue.Strength.SOFT);
+        com.android.i18n.system.ZygoteHooks.onEndPreload();
 
         // Clone standard descriptors as originals closed / rebound during zygote post fork.
         FileDescriptor.in.cloneForFork();
@@ -86,7 +88,7 @@
      * softly- and final-reachable objects, along with any other garbage.
      * This is only useful just before a fork().
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void gcAndFinalize() {
         final VMRuntime runtime = VMRuntime.getRuntime();
 
@@ -102,7 +104,7 @@
      * 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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void stopZygoteNoThreadCreation();
 
     /**
@@ -112,7 +114,7 @@
      * process. {@code postForkCommon} is called after {@code postForkChild} in
      * the child process.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void preFork() {
         Daemons.stop();
         token = nativePreFork();
@@ -122,23 +124,39 @@
     /**
      * Called by the zygote in the system server process after forking. This method is is called
      * before {@code postForkChild} for system server.
+     *
+     * @param runtimeFlags The flags listed in com.android.internal.os.Zygote passed to the runtime.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void postForkSystemServer(int runtimeFlags) {
         nativePostForkSystemServer(runtimeFlags);
     }
 
     /**
-     * Called by the zygote in the child process after every fork. The runtime
-     * flags from {@code runtimeFlags} are applied to the child process. The string
-     * {@code instructionSet} determines whether to use a native bridge.
+     * Called by the zygote in the child process after every fork.
+     *
+     * @param runtimeFlags The runtime flags to apply to the child process.
+     * @param isSystemServer Whether the child process is system server.
+     * @param isChildZygote Whether the child process is a child zygote.
+     * @param instructionSet The instruction set of the child, used to determine
+     *                       whether to use a native bridge.
      */
-    @libcore.api.CorePlatformApi
-    public static void postForkChild(int runtimeFlags, boolean isSystemServer, boolean isZygote,
-            String instructionSet) {
-        nativePostForkChild(token, runtimeFlags, isSystemServer, isZygote, instructionSet);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void postForkChild(int runtimeFlags, boolean isSystemServer,
+            boolean isChildZygote, String instructionSet) {
+        nativePostForkChild(token, runtimeFlags, isSystemServer, isChildZygote, instructionSet);
 
         Math.setRandomSeedInternal(System.currentTimeMillis());
+
+        // Enable memory-mapped coverage if JaCoCo is in the boot classpath. system_server is
+        // skipped due to being persistent and having its own coverage writing mechanism.
+        if (!isSystemServer && enableMemoryMappedDataMethod != null) {
+          try {
+            enableMemoryMappedDataMethod.invoke(null);
+          } catch (ReflectiveOperationException e) {
+            throw new RuntimeException(e);
+          }
+        }
     }
 
     /**
@@ -146,13 +164,30 @@
      * every fork. In the child process, this method is called after
      * {@code postForkChild}.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void postForkCommon() {
         // Notify the runtime before creating new threads.
         nativePostZygoteFork();
         Daemons.startPostZygoteFork();
     }
 
+    /**
+     * Is it safe to keep all ART daemon threads stopped indefinitely in the zygote?
+     * The answer may change from false to true dynamically, but not in the other
+     * direction.
+     *
+     * @return {@code true} if it's safe to keep all ART daemon threads stopped
+     *         indefinitely in the zygote; and {@code false} otherwise
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static boolean isIndefiniteThreadSuspensionSafe() {
+        // TODO: Make this return true if we're done with JIT compilation.
+        //
+        // We only care about JIT compilation that affects other processes.
+        // The zygote itself doesn't run appreciable amounts of Java code when
+        // running single-threaded.
+        return !nativeZygoteJitEnabled();
+    }
 
     // Hook for SystemServer specific early initialization post-forking.
     private static native void nativePostForkSystemServer(int runtimeFlags);
@@ -165,6 +200,8 @@
                                                    boolean isSystemServer, boolean isZygote,
                                                    String instructionSet);
 
+    private static native boolean nativeZygoteJitEnabled();
+
     /**
      * We must not fork until we're single-threaded again. Wait until /proc shows we're
      * down to just one thread.
diff --git a/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java b/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java
deleted file mode 100644
index 271a985..0000000
--- a/dalvik/src/main/java/org/apache/harmony/dalvik/NativeTestTarget.java
+++ /dev/null
@@ -1,122 +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 org.apache.harmony.dalvik;
-
-import dalvik.annotation.optimization.CriticalNative;
-import dalvik.annotation.optimization.FastNative;
-
-/**
- * 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);
-
-    /**
-     * This is an empty native static method with six args, hooked up
-     * using JNI. These have more complex args to show the cost of
-     * parsing the signature. All six values should be null
-     * 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);
-
-    /**
-     * This is an empty native static method with six args, hooked up
-     * using JNI. These have more complex args to show the cost of
-     * 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 292e967..76b6927 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
@@ -28,13 +28,13 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class Chunk {
 
     /*
      * Public members.  Do not rename without updating the VM.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public int type;                // chunk type
     public byte[] data;             // chunk data
     public int offset, length;      // position within "data"
@@ -46,8 +46,13 @@
 
     /**
      * Constructor with all fields.
+     *
+     * @param type   chunk type
+     * @param data   chunk data
+     * @param offset offset in {@code data} where actual data starts from
+     * @param length length of the {@code data}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public Chunk(int type, byte[] data, int offset, int length) {
         this.type = type;
         this.data = data;
@@ -56,11 +61,14 @@
     }
 
     /**
-     * Construct from a ByteBuffer.  The chunk is assumed to start at
+     * Construct from a {@link ByteBuffer}.  The chunk is assumed to start at
      * offset 0 and continue to the current position.
+     *
+     * @param type chunk type
+     * @param buf  {@link ByteBuffer} containing chunk data
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public Chunk(int type, ByteBuffer buf) {
         this.type = type;
 
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 0fb74f8..d6ce94d 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
@@ -23,52 +23,64 @@
 /**
  * Handle a chunk of data sent from a DDM server.
  *
- * To handle a chunk type, sub-class ChunkHandler and register your class
- * with DdmServer.
+ * To handle a chunk type, sub-class {@link ChunkHandler} and register your class
+ * with {@link DdmServer}.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public abstract class ChunkHandler {
 
+    /**
+     * Byte order of the data in the chunk.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final ByteOrder CHUNK_ORDER = ByteOrder.BIG_ENDIAN;
 
     public static final int CHUNK_FAIL = type("FAIL");
 
-
-    @libcore.api.CorePlatformApi
+    /**
+     * Constructs chunk handler.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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();
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public abstract void onConnected();
 
     /**
      * 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();
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public abstract void onDisconnected();
 
     /**
-     * Handle a single chunk of data.  "request" includes the type and
+     * Handle a single chunk of data.  {@code request} includes the type and
      * the chunk payload.
      *
-     * Returns a response in a Chunk.
+     * Returns a response in a {@link Chunk}.
+     *
+     * @param request chunk type and payload
+     * @return        {@link Chunk} with response
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public abstract Chunk handleChunk(Chunk request);
 
     /**
-     * Create a FAIL chunk.  The "handleChunk" methods can use this to
+     * Create a FAIL chunk.  The {@link #handleChunk(Chunk)} methods can use this to
      * return an error message when they are not able to process a chunk.
+     *
+     * @param errorCode arbitrary number to distinguish error
+     * @param msg       error message
+     * @return          {@link Chunk} with response
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static Chunk createFailChunk(int errorCode, String msg) {
         if (msg == null)
             msg = "";
@@ -77,15 +89,21 @@
         out.order(ChunkHandler.CHUNK_ORDER);
         out.putInt(errorCode);
         out.putInt(msg.length());
-        putString(out, msg);
+        final int len = msg.length();
+        for (int i = 0; i < len; i++) {
+            out.putChar(msg.charAt(i));
+        }
 
         return new Chunk(CHUNK_FAIL, out);
     }
 
     /**
-     * Utility function to wrap a ByteBuffer around a Chunk.
+     * Utility function to wrap a {@link ByteBuffer} around a {@link Chunk}.
+     *
+     * @param request chunk to be wrapped
+     * @return        {@link ByteBuffer} wrapping data from the given chunk
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static ByteBuffer wrapChunk(Chunk request) {
         ByteBuffer in;
 
@@ -94,35 +112,10 @@
         return in;
     }
 
-
-    /**
-     * Utility function to copy a String out of a ByteBuffer.
-     *
-     * 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++)
-            data[i] = buf.getChar();
-        return new String(data);
-    }
-
-    /**
-     * 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++)
-            buf.putChar(str.charAt(i));
-    }
-
     /**
      * Convert a 4-character string to a 32-bit type.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int type(String typeName) {
         if (typeName.length() != 4) {
             throw new IllegalArgumentException("Bad type name: " + typeName);
@@ -137,7 +130,7 @@
     /**
      * Convert an integer type to a 4-character string.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String name(int type)
     {
         char[] ascii = new char[4];
@@ -149,5 +142,4 @@
 
         return new String(ascii);
     }
-
 }
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 f1f58b6..44f7658 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
@@ -30,8 +30,8 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
-public class DdmServer {
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public final class DdmServer {
 
     private static HashMap<Integer,ChunkHandler> mHandlerMap =
         new HashMap<Integer,ChunkHandler>();
@@ -49,12 +49,16 @@
     private DdmServer() {}
 
     /**
-     * Register an instance of the ChunkHandler class to handle a specific
+     * Register an instance of the {@link ChunkHandler} class to handle a specific
      * chunk type.
      *
      * Throws an exception if the type already has a handler registered.
+     *
+     * @param type    int describing registered handler
+     * @param handler handler to be registered
+     * @throws NullPointerException if {@code handler} is {@code null}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void registerHandler(int type, ChunkHandler handler) {
         if (handler == null) {
             throw new NullPointerException("handler == null");
@@ -73,6 +77,7 @@
      *
      * Returns the old handler.
      */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static ChunkHandler unregisterHandler(int type) {
         synchronized (mHandlerMap) {
             return mHandlerMap.remove(type);
@@ -83,7 +88,7 @@
      * The application must call here after it finishes registering
      * handlers.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void registrationComplete() {
         // sync on mHandlerMap because it's convenient and makes a kind of
         // sense
@@ -98,9 +103,11 @@
      * JDWP "event", which does not elicit a response from the server.
      *
      * Use this for "unsolicited" chunks.
+     *
+     * @param chunk to send
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void sendChunk(Chunk chunk) {
         nativeSendChunk(chunk.type, chunk.data, chunk.offset, chunk.length);
     }
@@ -124,10 +131,10 @@
                 ChunkHandler handler = (ChunkHandler) iter.next();
                 switch (event) {
                     case CONNECTED:
-                        handler.connected();
+                        handler.onConnected();
                         break;
                     case DISCONNECTED:
-                        handler.disconnected();
+                        handler.onDisconnected();
                         break;
                     default:
                         throw new UnsupportedOperationException();
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 2c961da..cfa8725 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
@@ -24,8 +24,8 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
-public class DdmVmInternal {
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public final class DdmVmInternal {
 
     /* do not instantiate */
     private DdmVmInternal() {}
@@ -34,69 +34,37 @@
      * Enable thread notification.
      *
      * This is built into the VM, since that's where threads get managed.
-     */
-    @libcore.api.CorePlatformApi
-    native public static void threadNotify(boolean enable);
-
-    /**
-     * Enable heap info updates.
      *
-     * This is built into the VM, since that's where the heap is managed.
-     *
-     * @param when when to send the next HPIF chunk
-     * @return true on success.  false if 'when' is bad or if there was
-     *         an internal error.
+     * @param enabled {@code true} to enable thread notification; {@code false} to disable
      */
-    @libcore.api.CorePlatformApi
-    @FastNative
-    native public static boolean heapInfoNotify(int when);
-
-    /**
-     * Enable heap segment updates for the java (isNative == false) or
-     * native (isNative == true) heap.
-     *
-     * 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);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    native public static void setThreadNotifyEnabled(boolean enabled);
 
     /**
      * Get status info for all threads.  This is for the THST chunk.
      *
      * Returns a byte array with the THST data, or null if something
      * went wrong.
+     *
+     * @hide
      */
     @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.
+     * *
+     * @hide
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
     native public static StackTraceElement[] getStackTraceById(int threadId);
 
     /**
      * Enable or disable "recent allocation" tracking.
+     *
+     * @param enabled {@code true} to enable recent allocation tracking; {@code false} to disable
      */
-    @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();
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    native public static void setRecentAllocationsTrackingEnabled(boolean enabled);
 }
diff --git a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp b/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp
deleted file mode 100644
index 9f2b429..0000000
--- a/dalvik/src/main/native/org_apache_harmony_dalvik_NativeTestTarget.cpp
+++ /dev/null
@@ -1,82 +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.
- */
-
-#define LOG_TAG "NativeTestTarget"
-
-#include <nativehelper/JNIHelp.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) { }
-
-static JNINativeMethod gMethods_NormalOnly[] = {
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticSynchronizedMethod0, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniSynchronizedMethod0, "()V"),
-};
-
-
-static void NativeTestTarget_emptyJniMethod0(JNIEnv*, jobject) { }
-static void NativeTestTarget_emptyJniMethod6(JNIEnv*, jobject, int, int, int, int, int, int) { }
-static void NativeTestTarget_emptyJniMethod6L(JNIEnv*, jobject, jobject, jarray, jarray, jobject, jarray, jarray) { }
-static void NativeTestTarget_emptyJniStaticMethod6L(JNIEnv*, jclass, jobject, jarray, jarray, jobject, jarray, jarray) { }
-
-static void NativeTestTarget_emptyJniStaticMethod0(JNIEnv*, jclass) { }
-static void NativeTestTarget_emptyJniStaticMethod6(JNIEnv*, jclass, int, int, int, int, int, int) { }
-
-static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod0, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod6, "(IIIIII)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod6L, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod0, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod6, "(IIIIII)V"),
-};
-
-static void NativeTestTarget_emptyJniMethod0_Fast(JNIEnv*, jobject) { }
-static void NativeTestTarget_emptyJniMethod6_Fast(JNIEnv*, jobject, int, int, int, int, int, int) { }
-static void NativeTestTarget_emptyJniMethod6L_Fast(JNIEnv*, jobject, jobject, jarray, jarray, jobject, jarray, jarray) { }
-static void NativeTestTarget_emptyJniStaticMethod6L_Fast(JNIEnv*, jclass, jobject, jarray, jarray, jobject, jarray, jarray) { }
-
-static void NativeTestTarget_emptyJniStaticMethod0_Fast(JNIEnv*, jclass) { }
-static void NativeTestTarget_emptyJniStaticMethod6_Fast(JNIEnv*, jclass, int, int, int, int, int, int) { }
-
-static JNINativeMethod gMethods_Fast[] = {
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod0_Fast, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod6_Fast, "(IIIIII)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod6L_Fast, "(Ljava/lang/String;[Ljava/lang/String;[[ILjava/lang/Object;[Ljava/lang/Object;[[[[Ljava/lang/Object;)V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod0_Fast, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod6_Fast, "(IIIIII)V"),
-};
-
-
-static void NativeTestTarget_emptyJniStaticMethod0_Critical() { }
-static void NativeTestTarget_emptyJniStaticMethod6_Critical( int, int, int, int, int, int) { }
-
-static JNINativeMethod gMethods_Critical[] = {
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod0_Critical, "()V"),
-    NATIVE_METHOD(NativeTestTarget, emptyJniStaticMethod6_Critical, "(IIIIII)V"),
-};
-int register_org_apache_harmony_dalvik_NativeTestTarget(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "org/apache/harmony/dalvik/NativeTestTarget", gMethods_NormalOnly, NELEM(gMethods_NormalOnly));
-    jniRegisterNativeMethods(env, "org/apache/harmony/dalvik/NativeTestTarget", gMethods, NELEM(gMethods));
-    jniRegisterNativeMethods(env, "org/apache/harmony/dalvik/NativeTestTarget", gMethods_Fast, NELEM(gMethods_Fast));
-    jniRegisterNativeMethods(env, "org/apache/harmony/dalvik/NativeTestTarget", gMethods_Critical, NELEM(gMethods_Critical));
-
-    return 0;
-}
diff --git a/dom/src/test/java/org/w3c/domts/level1/core/hc_nodegetownerdocumentnull.java b/dom/src/test/java/org/w3c/domts/level1/core/hc_nodegetownerdocumentnull.java
index df1f508..12708ec 100644
--- a/dom/src/test/java/org/w3c/domts/level1/core/hc_nodegetownerdocumentnull.java
+++ b/dom/src/test/java/org/w3c/domts/level1/core/hc_nodegetownerdocumentnull.java
@@ -31,7 +31,7 @@
  *     The "getOwnerDocument()" method returns null if the target
  *     node itself is a document.
  *     
- *     Invoke the "getOwnerDocument()" method on the master 
+ *     Invoke the "getOwnerDocument()" method on the root
  *     document.   The Document returned should be null.
 * @author Curt Arnold
 * @see <a href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#node-ownerDoc">http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#node-ownerDoc</a>
diff --git a/dom/src/test/java/org/w3c/domts/level2/core/ownerDocument01.java b/dom/src/test/java/org/w3c/domts/level2/core/ownerDocument01.java
index f77f32a..92e519a 100644
--- a/dom/src/test/java/org/w3c/domts/level2/core/ownerDocument01.java
+++ b/dom/src/test/java/org/w3c/domts/level2/core/ownerDocument01.java
@@ -34,7 +34,7 @@
  *     The "getOwnerDocument()" method returns null if the target
  *     node itself is a DocumentType which is not used with any document yet.
  *     
- *     Invoke the "getOwnerDocument()" method on the master 
+ *     Invoke the "getOwnerDocument()" method on the root
  *     document.   The DocumentType returned should be null.
 * @author NIST
 * @author Mary Brady
diff --git a/expectations/Android.bp b/expectations/Android.bp
index c2667d3..2aadab9 100644
--- a/expectations/Android.bp
+++ b/expectations/Android.bp
@@ -12,18 +12,34 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-GPL
+    //   SPDX-license-identifier-GPL-2.0
+    //   SPDX-license-identifier-LGPL
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-W3C
+    default_applicable_licenses: ["libcore_license"],
+}
+
 expectations_visibility = [
+    "//art/build/sdk",
     "//cts/tests/libcore:__subpackages__",
 ]
 
-filegroup {
-    name: "libcore-expectations-knownfailures",
+java_library {
+    name: "libcore-expectations-knownfailures-jar",
     visibility: expectations_visibility,
-    srcs: ["knownfailures.txt"],
+    java_resources: ["knownfailures.txt"],
+    sdk_version: "core_current",
 }
 
-filegroup {
-    name: "libcore-expectations-virtualdeviceknownfailures",
+java_library {
+    name: "libcore-expectations-virtualdeviceknownfailures-jar",
     visibility: expectations_visibility,
-    srcs: ["virtualdeviceknownfailures.txt"],
+    java_resources: ["virtualdeviceknownfailures.txt"],
+    sdk_version: "core_current",
 }
diff --git a/expectations/knownfailures.txt b/expectations/knownfailures.txt
index 80e1c97..b128717 100644
--- a/expectations/knownfailures.txt
+++ b/expectations/knownfailures.txt
@@ -100,11 +100,6 @@
   name: "org.apache.harmony.security.tests.java.security.SignatureTest#testUpdatebyteArrayintint2"
 },
 {
-  description: "Android doesn't allow null parent.",
-  result: EXEC_FAILED,
-  name: "tests.java.security.SecureClassLoaderTest#testSecureClassLoaderClassLoader"
-},
-{
   description: "not supported",
   result: EXEC_FAILED,
   names: [
@@ -1272,7 +1267,7 @@
   description: "Android's XPath fails 29 of 250 Jaxen XPath tests",
   bug: 3270761,
   names: [
-    "libcore.xml.JaxenXPathTestSuite$3#xml/defaultNamespace.xml / /dummy:a/dummy:b/dummy:c",
+    "libcore.xml.JaxenXPathTestSuite$3#xml/defaultNamespace.xml / /fake:a/fake:b/fake:c",
     "libcore.xml.JaxenXPathTestSuite$3#xml/evaluate.xml / //metatest[ evaluate(@select) = . ]",
     "libcore.xml.JaxenXPathTestSuite$3#xml/evaluate.xml / evaluate('//jumps/*')",
     "libcore.xml.JaxenXPathTestSuite$3#xml/evaluate.xml / evaluate('//jumps/*')/dog",
@@ -1743,9 +1738,9 @@
   names: [
       "libcore.java.security.OldDHTest#testDHGen",
       "libcore.java.security.OldKeyPairGeneratorTestDH#testKeyPairGenerator",
-      "libcore.javax.crypto.spec.KeyPairGeneratorTestDH#testKeyPairGenerator",
-      "libcore.javax.crypto.spec.AlgorithmParametersTestDH#testAlgorithmParameters",
-      "libcore.javax.crypto.spec.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
+      "com.android.org.conscrypt.java.security.KeyPairGeneratorTestDH#testKeyPairGenerator",
+      "com.android.org.conscrypt.java.security.AlgorithmParametersTestDH#testAlgorithmParameters",
+      "com.android.org.conscrypt.java.security.AlgorithmParameterGeneratorTestDH#testAlgorithmParameterGenerator"
   ]
 },
 {
@@ -1791,5 +1786,37 @@
   result: EXEC_FAILED,
   bug: 62408076,
   name: "libcore.java.lang.reflect.annotations.AnnotatedElementParameterTest#testImplicitConstructorParameters_singleAnnotation"
+},
+{
+  description: "Android has different implementation in classes, e.g. SecurityManager.",
+  result: EXEC_FAILED,
+  bug: 181171596,
+  names: [
+    "test.java.util.concurrent.tck.AbstractExecutorServiceTest#testSubmitFailedPrivilegedExceptionAction",
+    "test.java.util.concurrent.tck.AbstractExecutorServiceTest#testSubmitPrivilegedAction",
+    "test.java.util.concurrent.tck.AbstractExecutorServiceTest#testSubmitPrivilegedExceptionAction",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testMinimalCompletionStage_toCompletableFuture_join",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testMinimalCompletionStage_toCompletableFuture_mutable",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testMinimalCompletionStage_toCompletableFuture_normalCompletion",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testMinimalCompletionStage_toCompletableFuture_oneWayPropagation",
+    "test.java.util.concurrent.tck.CompletableFutureTest#testToCompletableFutureGarbageRetention",
+    "test.java.util.concurrent.tck.ExecutorsTest#testCreatePrivilegedCallableUsingCCLWithNoPrivs",
+    "test.java.util.concurrent.tck.ExecutorsTest#testPrivilegedCallableUsingCCLWithPrivs",
+    "test.java.util.concurrent.tck.ExecutorsTest#testPrivilegedCallableWithNoPrivs",
+    "test.java.util.concurrent.tck.ExecutorsTest#testPrivilegedCallableWithPrivs",
+    "test.java.util.concurrent.tck.ExecutorsTest#testPrivilegedThreadFactory",
+    "test.java.util.concurrent.tck.ForkJoinPoolTest#testSubmitFailedPrivilegedExceptionAction",
+    "test.java.util.concurrent.tck.ForkJoinPoolTest#testSubmitPrivilegedAction",
+    "test.java.util.concurrent.tck.ForkJoinPoolTest#testSubmitPrivilegedExceptionAction",
+    "test.java.util.concurrent.tck.PriorityQueueTest#testOfferNonComparable",
+    "test.java.util.concurrent.tck.StampedLockTest#testDeeplyNestedReadLocks",
+    "test.java.util.concurrent.tck.StampedLockTest#testReadLock_lockUnlock",
+    "test.java.util.concurrent.tck.StampedLockTest#testTryConvertToOptimisticRead",
+    "test.java.util.concurrent.tck.StampedLockTest#testTryConvertToReadLock",
+    "test.java.util.concurrent.tck.StampedLockTest#testTryConvertToWriteLock",
+    "test.java.util.concurrent.tck.ThreadPoolExecutorTest#testPoolSizeInvariants",
+    "test.java.util.concurrent.tck.ThreadTest#testGetAndSetDefaultUncaughtExceptionHandler"
+ ]
 }
 ]
diff --git a/expectations/virtualdeviceknownfailures.txt b/expectations/virtualdeviceknownfailures.txt
index b689133..4ab4074 100644
--- a/expectations/virtualdeviceknownfailures.txt
+++ b/expectations/virtualdeviceknownfailures.txt
@@ -27,7 +27,8 @@
   names: ["org.apache.harmony.tests.java.net.MulticastSocketTest",
           "libcore.java.net.MulticastSocketTest#testGroupReceiveIPv6",
           "libcore.java.nio.channels.DatagramChannelMulticastTest#test_joinAnySource_IPv4",
-          "libcore.java.nio.channels.DatagramChannelMulticastTest#test_joinAnySource_multicastLoopOption_IPv4"
+          "libcore.java.nio.channels.DatagramChannelMulticastTest#test_joinAnySource_multicastLoopOption_IPv4",
+	  "libcore.java.nio.channels.DatagramChannelMulticastTest#test_joinSourceSpecific_anyBind_ipv6"
           ],
   bug: 35922755
 },
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
index 9f397f4..2bf5660 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/FileTest.java
@@ -410,17 +410,22 @@
 
         // Test create an illegal file
         String sep = File.separator;
-        f1 = new File(sep + "..");
+        f1 = new File(sep + "a" + sep + ".." + sep + ".." + sep);
         try {
             f1.createNewFile();
             fail("should throw IOE");
         } catch (IOException e) {
             // expected;
         }
-        f1 = new File(sep + "a" + sep + ".." + sep + ".." + sep);
+
+        // Prior to kernel version 5.7, creating "/.." returns EISDIR, and in 5.7 or later,
+        // such syscall returns EEXIST. In the first case, IOException is thrown. In the second
+        // case, false is returned. The below test is modified to accept both of them.
+        // See http://b/176057454 for details.
+        f1 = new File(sep + "..");
         try {
-            f1.createNewFile();
-            fail("should throw IOE");
+            boolean result = f1.createNewFile();
+            assertFalse(result);
         } catch (IOException e) {
             // expected;
         }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java
index b95adc9..0b9339d 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOErrorTest.java
@@ -36,7 +36,7 @@
         String errorMsg = "java.io.IOError"; //$NON-NLS-1$
         assertTrue(e.toString().contains(errorMsg));
 
-        errorMsg = "A dummy error"; //$NON-NLS-1$
+        errorMsg = "A fake error"; //$NON-NLS-1$
         e = new IOError(new Throwable(errorMsg));
         assertTrue(e.toString().contains(errorMsg));
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java
index d0b26db..3853e39 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/IOExceptionTest.java
@@ -60,12 +60,12 @@
         // Test for constructor java.io.IOException(java.lang.String, java.lang.Throwable)
 
         IOException ioException = new IOException(
-                "A dummy IOException", new Throwable("A dummy Throwable")); //$NON-NLS-1$//$NON-NLS-2$
-        assertEquals("A dummy IOException", ioException.getMessage()); //$NON-NLS-1$
+                "A fake IOException", new Throwable("A fake Throwable")); //$NON-NLS-1$//$NON-NLS-2$
+        assertEquals("A fake IOException", ioException.getMessage()); //$NON-NLS-1$
 
         try {
             throw new IOException(
-                    "A dummy error", new Throwable("Some error message")); //$NON-NLS-1$ //$NON-NLS-2$
+                    "A fake error", new Throwable("Some error message")); //$NON-NLS-1$ //$NON-NLS-2$
         } catch (IOException e) {
             return;
         } catch (Exception e) {
@@ -80,7 +80,7 @@
      */
     public void test_Constructor_LThrowable() {
         // Test for constructor java.io.IOException(java.lang.Throwable)
-        Throwable cause = new Throwable("A dummy Throwable"); //$NON-NLS-1$
+        Throwable cause = new Throwable("A fake Throwable"); //$NON-NLS-1$
         IOException ioException = new IOException(cause);
         assertEquals(cause.toString(), ioException.getMessage());
 
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 16a7415..637ad9d 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
@@ -43,7 +43,7 @@
     @Rule
     public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
-    static class DummyClass implements Serializable {
+    static class FakeClass implements Serializable {
         private static final long serialVersionUID = 999999999999999L;
 
         long bam = 999L;
@@ -61,16 +61,16 @@
     public void test_forClass() {
         // Need to test during serialization to be sure an instance is
         // returned
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         assertEquals("forClass returned an object: " + osc.forClass(),
-                DummyClass.class, osc.forClass());
+                FakeClass.class, osc.forClass());
     }
 
     /**
      * java.io.ObjectStreamClass#getField(java.lang.String)
      */
     public void test_getFieldLjava_lang_String() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         assertEquals("getField did not return correct field", 'J', osc
                 .getField("bam").getTypeCode());
         assertNull("getField did not null for non-existent field", osc
@@ -81,7 +81,7 @@
      * java.io.ObjectStreamClass#getFields()
      */
     public void test_getFields() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         ObjectStreamField[] osfArray = osc.getFields();
         assertTrue(
                 "Array of fields should be of length 2 but is instead of length: "
@@ -92,10 +92,10 @@
      * java.io.ObjectStreamClass#getName()
      */
     public void test_getName() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         assertEquals(
                 "getName returned incorrect name: " + osc.getName(),
-                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass",
+                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$FakeClass",
                 osc.getName());
     }
 
@@ -103,10 +103,10 @@
      * java.io.ObjectStreamClass#getSerialVersionUID()
      */
     public void test_getSerialVersionUID() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         assertTrue("getSerialversionUID returned incorrect uid: "
                 + osc.getSerialVersionUID() + " instead of "
-                + DummyClass.getUID(), osc.getSerialVersionUID() == DummyClass
+                + FakeClass.getUID(), osc.getSerialVersionUID() == FakeClass
                 .getUID());
     }
 
@@ -128,10 +128,10 @@
      * java.io.ObjectStreamClass#lookup(java.lang.Class)
      */
     public void test_lookupLjava_lang_Class() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         assertEquals(
                 "lookup returned wrong class: " + osc.getName(),
-                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass",
+                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$FakeClass",
                 osc.getName());
     }
 
@@ -139,7 +139,7 @@
      * java.io.ObjectStreamClass#toString()
      */
     public void test_toString() {
-        ObjectStreamClass osc = ObjectStreamClass.lookup(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookup(FakeClass.class);
         String oscString = osc.toString();
 
         // The previous test was more specific than the spec so it was replaced
@@ -213,9 +213,9 @@
     public void test_lookupAnyLjava_lang_Class() {
         // Test for method java.io.ObjectStreamClass
         // java.io.ObjectStreamClass.lookupAny(java.lang.Class)
-        ObjectStreamClass osc = ObjectStreamClass.lookupAny(DummyClass.class);
+        ObjectStreamClass osc = ObjectStreamClass.lookupAny(FakeClass.class);
         assertEquals("lookup returned wrong class: " + osc.getName(),
-                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$DummyClass", osc
+                "org.apache.harmony.tests.java.io.ObjectStreamClassTest$FakeClass", osc
                 .getName());
 
         osc = ObjectStreamClass.lookupAny(NonSerialzableClass.class);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java
index 8dd12a4..a5feed1 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/io/ObjectStreamFieldTest.java
@@ -33,7 +33,7 @@
 
 public class ObjectStreamFieldTest extends junit.framework.TestCase {
 
-    static class DummyClass implements Serializable {
+    static class FakeClass implements Serializable {
         private static final long serialVersionUID = 999999999999998L;
 
         long bam = 999L;
@@ -245,7 +245,7 @@
      * is called before a test is executed.
      */
     protected void setUp() {
-        osc = ObjectStreamClass.lookup(DummyClass.class);
+        osc = ObjectStreamClass.lookup(FakeClass.class);
         bamField = osc.getField("bam");
         samField = osc.getField("sam");
         hamField = osc.getField("ham");
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java
index 9dca8e9..f8cff0d 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ObjectTest.java
@@ -16,34 +16,52 @@
  */
 package org.apache.harmony.tests.java.lang;
 
+import java.util.ArrayList;
+import java.util.List;
+
 public class ObjectTest extends junit.framework.TestCase {
 
-    /**
-     * Test objects.
-     */
-    Object obj1 = new Object();
+    final Object lock = new Object();
 
-    Object obj2 = new Object();
-
-    /**
-     * Generic state indicator.
-     */
-    int status = 0;
-
+    // Helpers for test_notify() and test_notifyAll(). Access is guarded by {@code lock}'s monitor.
     int ready = 0;
+    int finished = 0;
+    int outstandingNotifications = 0;
+    int spuriousNotifications = 0;
+    Throwable backgroundException;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        synchronized (lock) {
+            backgroundException = null;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        synchronized (lock) {
+            if (backgroundException != null) {
+                fail("Encountered " + backgroundException);
+            }
+        }
+        super.tearDown();
+    }
 
     /**
      * java.lang.Object#Object()
      */
-    public void test_Constructor() {
+    public void test_constructor() {
         // Test for method java.lang.Object()
-        assertNotNull("Constructor failed !!!", new Object());
+        assertNotNull("Constructor failed", new Object());
     }
 
     /**
      * java.lang.Object#equals(java.lang.Object)
      */
     public void test_equalsLjava_lang_Object() {
+        Object obj1 = new Object();
+        Object obj2 = new Object();
         // Test for method boolean java.lang.Object.equals(java.lang.Object)
         assertTrue("Same object should be equal", obj1.equals(obj1));
         assertTrue("Different objects should not be equal", !obj1.equals(obj2));
@@ -54,20 +72,15 @@
      */
     public void test_getClass() throws Exception {
         // Test for method java.lang.Class java.lang.Object.getClass()
-        String classNames[] = { "java.lang.Object", "java.lang.Throwable",
+        String[] classNames = { "java.lang.Object", "java.lang.Throwable",
                 "java.lang.StringBuffer" };
-        Class<?> classToTest = null;
-        Object instanceToTest = null;
-
-        status = 0;
-        for (int i = 0; i < classNames.length; ++i) {
-            classToTest = Class.forName(classNames[i]);
-            instanceToTest = classToTest.newInstance();
-            assertTrue("Instance didn't match creator class.",
-                    instanceToTest.getClass() == classToTest);
-            assertTrue("Instance didn't match class with matching name.",
-                    instanceToTest.getClass() == Class
-                            .forName(classNames[i]));
+        for (String className : classNames) {
+            final Class<?> classToTest = Class.forName(className);
+            final Object instanceToTest = classToTest.newInstance();
+            assertSame("Instance didn't match creator class.", instanceToTest.getClass(),
+                    classToTest);
+            assertSame("Instance didn't match class with matching name.", instanceToTest.getClass(),
+                    Class.forName(className));
         }
     }
 
@@ -76,10 +89,19 @@
      */
     public void test_hashCode() {
         // Test for method int java.lang.Object.hashCode()
-        assertTrue("Same object should have same hash.",
-                obj1.hashCode() == obj1.hashCode());
-        assertTrue("Same object should have same hash.",
-                obj2.hashCode() == obj2.hashCode());
+        Object obj1 = new Object();
+        Object obj2;
+        int origHashCodeForObj1 = obj1.hashCode();
+        // Force obj1 lock inflation.
+        synchronized (obj1) {
+            obj2 = new Object();
+        }
+        assertEquals("Same object should have same hash.", obj1.hashCode(), obj1.hashCode());
+        assertEquals("Lock inflation shouldn't change hash code.",
+                obj1.hashCode(), origHashCodeForObj1);
+        assertEquals("Same object should have same hash.", obj2.hashCode(), obj2.hashCode());
+        Runtime.getRuntime().gc();
+        assertEquals("Gc shouldn't change hash code.", obj1.hashCode(), origHashCodeForObj1);
     }
 
     /**
@@ -87,67 +109,72 @@
      */
     public void test_notify() {
         // Test for method void java.lang.Object.notify()
+        class TestThread extends Thread {
+            public TestThread(String name) {
+                super(name);
+            }
 
-        // Inner class to run test thread.
-        class TestThread implements Runnable {
+            @Override
             public void run() {
-                synchronized (obj1) {
+                synchronized (lock) {
                     try {
-                        ready += 1;
-                        obj1.wait();// Wait for ever.
-                        status += 1;
+                        ready++;
+                        lock.wait(); // Wait to be notified.
+                        while (outstandingNotifications <= 0) {
+                            spuriousNotifications++;
+                            lock.wait();
+                        }
+                        outstandingNotifications--;
                     } catch (InterruptedException ex) {
-                        status = -1000;
+                        backgroundException = ex;
                     }
                 }
             }
         }
-        ;
-
-        // Start of test code.
 
         // Warning:
         // This code relies on each thread getting serviced within
-        // 200 mSec of when it is notified. Although this
+        // 400 msec of when it is notified. Although this
         // seems reasonable, it could lead to false-failures.
 
         ready = 0;
-        status = 0;
+        outstandingNotifications = 0;
+        spuriousNotifications = 0;
         final int readyWaitSecs = 3;
 
         final int threadCount = 20;
+        List<TestThread> threads = new ArrayList<>();
         for (int i = 0; i < threadCount; ++i) {
-            new Thread(new TestThread()).start();
+            TestThread thread = new TestThread("TestThread " + i);
+            threads.add(thread);
+            thread.start();
         }
-        synchronized (obj1) {
+        synchronized (lock) {
             try {
-
                 // Wait up to readyWaitSeconds for all threads to be waiting on
                 // monitor
-                for (int i = 0; i < readyWaitSecs; i++) {
-                    obj1.wait(1000, 0);
+                for (int i = 0; i < 10 * readyWaitSecs; i++) {
+                    lock.wait(100, 0);
                     if (ready == threadCount) {
                         break;
                     }
                 }
-
-                // Check pre-conditions of testing notifyAll
-                assertTrue("Not all launched threads are waiting. (ready = "
-                        + ready + ")", ready == threadCount);
-                assertTrue("Thread woke too early. (status = " + status + ")",
-                        status == 0);
-
+                assertEquals("Not all launched threads are waiting. (ready=" + ready + ")",
+                        ready, threadCount);
                 for (int i = 1; i <= threadCount; ++i) {
-                    obj1.notify();
-                    obj1.wait(200, 0);
-                    assertTrue("Out of sync. (expected " + i + " but got "
-                            + status + ")", status == i);
+                    outstandingNotifications++;
+                    lock.notify();
+                    for (int j = 0; j < 10 && outstandingNotifications > 0; ++j) {
+                        lock.wait(100);  // Sleep for 100 msecs, releasing lock.
+                    }
+                    assertEquals("Notification #" + i + "  took too long to wake a thread.",
+                            0, outstandingNotifications);
+                    // Spurious notifications are allowed, but should be very rare.
+                    assertTrue("Too many spurious notifications: " + spuriousNotifications,
+                            spuriousNotifications <= 1);
                 }
-
             } catch (InterruptedException ex) {
-                fail(
-                        "Unexpectedly got an InterruptedException. (status = "
-                                + status + ")");
+                fail("Unexpectedly got an InterruptedException.");
             }
         }
     }
@@ -161,13 +188,13 @@
         // Inner class to run test thread.
         class TestThread implements Runnable {
             public void run() {
-                synchronized (obj1) {
+                synchronized (lock) {
                     try {
                         ready += 1;
-                        obj1.wait();// Wait for ever.
-                        status += 1;
+                        lock.wait();// Wait forever.
+                        finished += 1;
                     } catch (InterruptedException ex) {
-                        status = -1000;
+                        backgroundException = ex;
                     }
                 }
             }
@@ -181,45 +208,43 @@
         // 5 seconds of when they are notified. Although this
         // seems reasonable, it could lead to false-failures.
 
-        status = 0;
         ready = 0;
+        finished = 0;
         final int readyWaitSecs = 3;
+        final int finishedWaitSecs = 5;
         final int threadCount = 20;
         for (int i = 0; i < threadCount; ++i) {
             new Thread(new TestThread()).start();
         }
 
-        synchronized (obj1) {
+        synchronized (lock) {
 
             try {
-
                 // Wait up to readyWaitSeconds for all threads to be waiting on
                 // monitor
                 for (int i = 0; i < readyWaitSecs; i++) {
-                    obj1.wait(1000, 0);
+                    lock.wait(1000, 0);
                     if (ready == threadCount) {
                         break;
                     }
                 }
 
                 // Check pre-conditions of testing notifyAll
-                assertTrue("Not all launched threads are waiting. (ready = "
-                        + ready + ")", ready == threadCount);
-                assertTrue("At least one thread woke too early. (status = "
-                        + status + ")", status == 0);
+                assertEquals("Not all launched threads are waiting.", threadCount, ready);
+                // This assumes no spurious wakeups. If we ever see any, we might check for at
+                // most one finished thread instead.
+                assertEquals("At least one thread woke too early.", 0, finished);
 
-                obj1.notifyAll();
+                lock.notifyAll();
 
-                obj1.wait(5000, 0);
+                for (int i = 0; finished < threadCount && i < finishedWaitSecs; ++i) {
+                  lock.wait(1000, 0);
+                }
 
-                assertTrue(
-                        "At least one thread did not get notified. (status = "
-                                + status + ")", status == threadCount);
+                assertEquals("At least one thread did not get notified.", threadCount, finished);
 
             } catch (InterruptedException ex) {
-                fail(
-                        "Unexpectedly got an InterruptedException. (status = "
-                                + status + ")");
+                fail("Unexpectedly got an InterruptedException. (finished = " + finished + ")");
             }
 
         }
@@ -230,7 +255,7 @@
      */
     public void test_toString() {
         // Test for method java.lang.String java.lang.Object.toString()
-        assertNotNull("Object toString returned null.", obj1.toString());
+        assertNotNull("Object toString returned null.", lock.toString());
     }
 
     /**
@@ -240,19 +265,23 @@
         // Test for method void java.lang.Object.wait()
 
         // Inner class to run test thread.
-        class TestThread implements Runnable {
+        class TestThread extends Thread {
+            int status;
+
             public void run() {
-                synchronized (obj1) {
+                synchronized (lock) {
                     try {
-                        obj1.wait();// Wait for ever.
+                        do {
+                            lock.wait(); // Wait to be notified.
+                        } while (outstandingNotifications <= 0);
+                        outstandingNotifications--;
                         status = 1;
                     } catch (InterruptedException ex) {
-                        status = -1;
+                        backgroundException = ex;
                     }
                 }
             }
         }
-        ;
 
         // Start of test code.
 
@@ -261,21 +290,23 @@
         // 1 second of when they are notified. Although this
         // seems reasonable, it could lead to false-failures.
 
-        status = 0;
-        new Thread(new TestThread()).start();
-        synchronized (obj1) {
+        TestThread thread = new TestThread();
+        synchronized (lock) {
+            thread.status = 0;
+        }
+        thread.start();
+        synchronized (lock) {
             try {
-                obj1.wait(1000, 0);
-                assertTrue("Thread woke too early. (status = " + status + ")",
-                        status == 0);
-                obj1.notifyAll();
-                obj1.wait(1000, 0);
-                assertTrue("Thread did not get notified. (status = " + status
-                        + ")", status == 1);
+                lock.wait(1000, 0);
+                assertEquals("Thread woke too early. (status=" + thread.status + ")",
+                        0, thread.status);
+                outstandingNotifications = 1;
+                lock.notifyAll();
+                lock.wait(1000, 0);
+                assertEquals("Thread did not get notified. (status=" + thread.status + ")",
+                        1, thread.status);
             } catch (InterruptedException ex) {
-                fail(
-                        "Unexpectedly got an InterruptedException. (status = "
-                                + status + ")");
+                fail("Unexpectedly got an InterruptedException. (status=" + thread.status + ")");
             }
         }
     }
@@ -289,15 +320,15 @@
         // Start of test code.
 
         final int loopCount = 20;
-        final int allowableError = 100; // millesconds
+        final int allowableError = 100; // milliseconds
         final int delay = 200; // milliseconds
-        synchronized (obj1) {
+        synchronized (lock) {
             try {
                 int count = 0;
                 long[][] toLong = new long[3][3];
                 for (int i = 0; i < loopCount; ++i) {
                     long before = System.currentTimeMillis();
-                    obj1.wait(delay, 0);
+                    lock.wait(delay, 0);
                     long after = System.currentTimeMillis();
                     long error = (after - before - delay);
                     if (error < 0)
@@ -311,10 +342,9 @@
                             count++;
                         }
                         if (error > (1000 + delay) || count == toLong.length) {
-                            StringBuffer sb = new StringBuffer();
+                            StringBuilder sb = new StringBuilder();
                             for (int j = 0; j < count; j++) {
-                                sb
-                                        .append("wakeup time too inaccurate, iteration ");
+                                sb.append("wakeup time too inaccurate, iteration ");
                                 sb.append(toLong[j][0]);
                                 sb.append(", before: ");
                                 sb.append(toLong[j][1]);
@@ -329,9 +359,7 @@
                     }
                 }
             } catch (InterruptedException ex) {
-                fail(
-                        "Unexpectedly got an InterruptedException. (status = "
-                                + status + ")");
+                fail("Unexpectedly got an InterruptedException.");
             }
         }
     }
@@ -343,21 +371,26 @@
         // Test for method void java.lang.Object.wait(long, int)
 
         // Inner class to run test thread.
-        class TestThread implements Runnable {
+        class TestThread extends Thread {
+            int status;
+
+            @Override
             public void run() {
-                synchronized (obj1) {
+                synchronized (lock) {
                     try {
-                        obj1.wait(0, 1); // Don't wait very long.
+                        lock.wait(0, 1); // Don't wait very long.
                         status = 1;
-                        obj1.wait(0, 0); // Wait for ever.
+                        do {
+                            lock.wait(0, 0); // Wait to be notified.
+                        } while (outstandingNotifications <= 0);
+                        outstandingNotifications--;
                         status = 2;
                     } catch (InterruptedException ex) {
-                        status = -1;
+                        backgroundException = ex;
                     }
                 }
             }
         }
-        ;
 
         // Start of test code.
 
@@ -366,23 +399,25 @@
         // 1 second of when they are notified. Although this
         // seems reasonable, it could lead to false-failures.
 
-        status = 0;
-        new Thread(new TestThread()).start();
-        synchronized (obj1) {
+        TestThread thread = new TestThread();
+        synchronized (lock) {
+            thread.status = 0;
+        }
+        thread.start();
+        synchronized (lock) {
             try {
-                obj1.wait(1000, 0);
-                assertTrue("Thread did not wake after 1 ms. (status = "
-                        + status + ")", status == 1);
-                obj1.notifyAll();
-                obj1.wait(1000, 0);
-                assertTrue("Thread did not get notified. (status = " + status
-                        + ")", status == 2);
+                lock.wait(1000, 0);
+                assertEquals("Thread did not wake after 1sec. (status=" + thread.status + ")",
+                        1, thread.status);
+                outstandingNotifications++;
+                lock.notifyAll();
+                lock.wait(1000, 0);
+                assertEquals("Thread did not get notified. (status=" +
+                        thread.status + ")", 2, thread.status);
             } catch (InterruptedException ex) {
-                fail(
-                        "Unexpectedly got an InterruptedException. (status = "
-                                + status + ")");
+                fail("Unexpectedly got an InterruptedException. (status = " +
+                        thread.status + ")");
             }
         }
-
     }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java
index 5819dd3..2fc03c5 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ThreadTest.java
@@ -707,7 +707,7 @@
         long secondRead = System.currentTimeMillis();
         assertTrue("Did not join by appropriate time: " + secondRead + "-"
                 + firstRead + "=" + (secondRead - firstRead), secondRead
-                - firstRead <= 300);
+                - firstRead <= 400);
         assertTrue("Joined thread is not alive", st.isAlive());
         st.interrupt();
 
@@ -818,8 +818,6 @@
      */
     public void test_sleepJ() {
         // Test for method void java.lang.Thread.sleep(long)
-
-        // TODO : Test needs enhancing.
         long stime = 0, ftime = 0;
         try {
             stime = System.currentTimeMillis();
@@ -828,7 +826,12 @@
         } catch (InterruptedException e) {
             fail("Unexpected interrupt received");
         }
-        assertTrue("Failed to sleep long enough", (ftime - stime) >= 800);
+        long elapsedMillis = ftime - stime;
+        // We shouldn't ever wake up early, but there might be some rounding:
+        assertTrue("Failed to sleep long enough: " + elapsedMillis,
+            elapsedMillis >= 998);
+        // Scheduling delays can make us appear to sleep quite a bit longer:
+        assertTrue("Overslept: " + elapsedMillis, elapsedMillis <= 1300);
     }
 
     /**
@@ -836,8 +839,6 @@
      */
     public void test_sleepJI() {
         // Test for method void java.lang.Thread.sleep(long, int)
-
-        // TODO : Test needs revisiting.
         long stime = 0, ftime = 0;
         try {
             stime = System.currentTimeMillis();
@@ -846,9 +847,10 @@
         } catch (InterruptedException e) {
             fail("Unexpected interrupt received");
         }
-        long result = ftime - stime;
-        assertTrue("Failed to sleep long enough: " + result, result >= 900
-                && result <= 1100);
+        long elapsedMillis = ftime - stime;
+        assertTrue("Failed to sleep long enough: " + elapsedMillis,
+            elapsedMillis >= 999);
+        assertTrue("Overslept: " + elapsedMillis, elapsedMillis <= 1300);
     }
 
     /**
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java
index 7a3496e..19ccf03 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/lang/ref/ReferenceTest.java
@@ -83,6 +83,63 @@
     }
 
     /**
+     * java.lang.ref.Reference#refersTo()
+     */
+    public void test_refersTo() {
+        tmpA = new Object();
+        tmpB = new Object();
+        tmpC = new Object();
+        final SoftReference sr = new SoftReference(tmpA, new ReferenceQueue());
+        final WeakReference wr = new WeakReference(tmpB, new ReferenceQueue());
+        final PhantomReference pr = new PhantomReference(tmpC, new ReferenceQueue());
+        assertTrue("soft refersTo(referent)", sr.refersTo(tmpA));
+        assertTrue("weak refersTo(referent)", wr.refersTo(tmpB));
+        assertTrue("phantom refersTo(referent)", pr.refersTo(tmpC));
+        assertFalse("soft refersTo(other)", sr.refersTo(tmpC));
+        assertFalse("weak refersTo(other)", wr.refersTo(tmpA));
+        assertFalse("phantom refersTo(other)", pr.refersTo(tmpB));
+        sr.clear();
+        wr.clear();
+        pr.clear();
+        assertTrue("soft refersTo(null)", sr.refersTo(null));
+        assertTrue("weak refersTo(null)", wr.refersTo(null));
+        assertTrue("phantom refersTo(null)", pr.refersTo(null));
+        assertFalse("soft refersTo(nonnull)", sr.refersTo(tmpA));
+        assertFalse("weak refersTo(nonnull)", wr.refersTo(tmpB));
+        assertFalse("phantom refersTo(nonnull)", pr.refersTo(tmpC));
+
+        // Check that refersTo remains consistent during GC.
+        final WeakReference wr2 = new WeakReference(tmpB, new ReferenceQueue());
+        Thread checker = new Thread(() -> {
+            while (wr2.get() == tmpB && wr2.refersTo(tmpB)
+                    && !wr2.refersTo(null) && !wr2.refersTo(tmpA)) {}
+            disappeared = true;
+        });
+        checker.start();
+        for (int i = 0; i < 5; ++i) {
+            Runtime.getRuntime().gc();
+            System.runFinalization();
+            assertFalse("WeakReference prematurely inaccessible", disappeared);
+        }
+        wr2.clear();
+        for (int i = 0; i < 5; ++i) {
+            Runtime.getRuntime().gc();
+            if (disappeared) {
+                break;
+            }
+            try {
+                Thread.sleep(10);
+            } catch (InterruptedException e) {
+                fail("InterruptedException : " + e.getMessage());
+            }
+        }
+        assertTrue("WeakReference remained accessible", disappeared);
+        assertTrue("refersTo(null) failed", wr2.refersTo(null) && !wr2.refersTo(tmpB));
+    }
+
+    private volatile boolean disappeared = false;
+
+    /**
      * java.lang.ref.Reference#enqueue()
      */
     public void test_enqueue() {
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 b9ee1c6..cc64946 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
@@ -81,13 +81,8 @@
 	 * @tests java.math.BigInteger#BigInteger(int, java.util.Random)
 	 */
 	public void test_ConstructorILjava_util_Random() {
-        // regression test for HARMONY-1047
-		try {
-			new BigInteger(Integer.MAX_VALUE, (Random)null);
-			fail("NegativeArraySizeException expected");
-		} catch (NegativeArraySizeException e) {
-            // PASSED
-		}
+        // regression test for HARMONY-1047 removed. We were failing this supposed test for RI
+        // behavior in spite of running their code.
 		
 		bi = new BigInteger(70, rand);
 		bi2 = new BigInteger(70, rand);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
index a24a67b..dab784a 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/MulticastSocketTest.java
@@ -17,6 +17,13 @@
 
 package org.apache.harmony.tests.java.net;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.io.IOException;
 import java.net.BindException;
 import java.net.DatagramPacket;
@@ -32,12 +39,16 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
-import libcore.junit.junit3.TestCaseWithRules;
+
 import libcore.junit.util.ResourceLeakageDetector;
+
+import org.junit.Assume;
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
+import org.junit.Test;
 
-public class MulticastSocketTest extends TestCaseWithRules {
+public class MulticastSocketTest {
     @Rule
     public TestRule guardRule = ResourceLeakageDetector.getRule();
 
@@ -63,10 +74,10 @@
     private NetworkInterface ipv6NetworkInterface;
     private boolean supportsMulticast;
 
-    @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         // The loopback interface isn't actually useful for sending/receiving multicast messages
-        // but it can be used as a dummy for tests where that does not matter.
+        // but it can be used as a fake for tests where that does not matter.
         loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
         assertNotNull(loopbackInterface);
         assertTrue(loopbackInterface.isLoopback());
@@ -79,9 +90,7 @@
         // set we assume the device has an interface capable of supporting multicast.
         supportsMulticast = Boolean.parseBoolean(
                 System.getProperty("android.cts.device.multicast", "true"));
-        if (!supportsMulticast) {
-            return;
-        }
+        Assume.assumeTrue(supportsMulticast);
 
         while (interfaces.hasMoreElements()
                 && (ipv4NetworkInterface == null || ipv6NetworkInterface == null)) {
@@ -104,10 +113,9 @@
                 ipv4NetworkInterface != null && ipv6NetworkInterface != null);
     }
 
-    public void test_Constructor() throws IOException {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void constructor() throws IOException {
+        Assume.assumeTrue(supportsMulticast);
         // Regression test for 497.
         MulticastSocket s = new MulticastSocket();
         // Regression test for Harmony-1162.
@@ -116,10 +124,9 @@
         s.close();
     }
 
-    public void test_ConstructorI() throws IOException {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void constructorI() throws IOException {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket orig = new MulticastSocket();
         int port = orig.getLocalPort();
         orig.close();
@@ -130,10 +137,9 @@
         dup.close();
     }
 
-    public void test_getInterface() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void getInterface() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         // Validate that we get the expected response when one was not set.
         MulticastSocket mss = new MulticastSocket(0);
         // We expect an ANY address in this case.
@@ -157,10 +163,9 @@
         mss.close();
     }
 
-    public void test_getNetworkInterface() throws IOException {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void getNetworkInterface() throws IOException {
+        Assume.assumeTrue(supportsMulticast);
         // Validate that we get the expected response when one was not set.
         MulticastSocket mss = new MulticastSocket(0);
         NetworkInterface theInterface = mss.getNetworkInterface();
@@ -202,10 +207,9 @@
         mss.close();
     }
 
-    public void test_getTimeToLive() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void getTimeToLive() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket();
         mss.setTimeToLive(120);
         assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
@@ -214,27 +218,24 @@
         mss.close();
     }
 
-    public void test_getTTL() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void getTTL() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket();
         mss.setTTL((byte) 120);
         assertEquals("Returned incorrect TTL", 120, mss.getTTL());
         mss.close();
     }
 
-    public void test_joinGroupLjava_net_InetAddress_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroupLjava_net_InetAddress_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         test_joinGroupLjava_net_InetAddress(GOOD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_InetAddress_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroupLjava_net_InetAddress_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         test_joinGroupLjava_net_InetAddress(GOOD_IPv6);
     }
 
@@ -258,10 +259,9 @@
         receivingSocket.close();
     }
 
-    public void test_joinGroup_null_null() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroup_null_null() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.joinGroup(null, null);
@@ -271,10 +271,9 @@
         mss.close();
     }
 
-    public void test_joinGroup_non_multicast_address_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroup_non_multicast_address_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.joinGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
@@ -284,10 +283,9 @@
         mss.close();
     }
 
-    public void test_joinGroup_non_multicast_address_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroup_non_multicast_address_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.joinGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
@@ -297,35 +295,35 @@
         mss.close();
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+        Assume.assumeTrue(supportsMulticast);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
                 ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+        Assume.assumeTrue(supportsMulticast);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
                 ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4_nullInterface()
             throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv4, BAD_IPv4);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv4, BAD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6_nullInterface()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6_nullInterface()
             throws Exception {
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv6, BAD_IPv6);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(null, GOOD_IPv6, BAD_IPv6);
     }
 
-    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+    private void check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
             NetworkInterface networkInterface, InetAddress group, InetAddress group2)
             throws Exception {
         // Create the sending socket and specify the interface to use as needed (otherwise use the
@@ -383,10 +381,9 @@
         sendingSocket.close();
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         // Check that we can join on specific interfaces and that we only receive if data is
         // received on that interface. This test is only really useful on devices with multiple
         // non-loopback interfaces.
@@ -453,25 +450,23 @@
         }
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv4()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+        Assume.assumeTrue(supportsMulticast);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
                 ipv4NetworkInterface, GOOD_IPv4);
     }
 
-    public void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6()
+    @Test
+    public void joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins_IPv6()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+        Assume.assumeTrue(supportsMulticast);
+        check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
                 ipv6NetworkInterface, GOOD_IPv6);
     }
 
-    private void test_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
+    private void check_joinGroupLjava_net_SocketAddressLjava_net_NetworkInterface_multiple_joins(
             NetworkInterface networkInterface, InetAddress group) throws Exception {
         // Validate that we can join the same address on two different interfaces but not on the
         // same interface.
@@ -487,21 +482,19 @@
         mss.close();
     }
 
-    public void test_leaveGroupLjava_net_InetAddress_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_leaveGroupLjava_net_InetAddress(GOOD_IPv4);
+    @Test
+    public void leaveGroupLjava_net_InetAddress_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_leaveGroupLjava_net_InetAddress(GOOD_IPv4);
     }
 
-    public void test_leaveGroupLjava_net_InetAddress_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_leaveGroupLjava_net_InetAddress(GOOD_IPv6);
+    @Test
+    public void leaveGroupLjava_net_InetAddress_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_leaveGroupLjava_net_InetAddress(GOOD_IPv6);
     }
 
-    private void test_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception {
+    private void check_leaveGroupLjava_net_InetAddress(InetAddress group) throws Exception {
         String msg = "Hello World";
         MulticastSocket mss = new MulticastSocket(0);
         InetSocketAddress groupAddress = new InetSocketAddress(group, mss.getLocalPort());
@@ -516,10 +509,9 @@
         mss.close();
     }
 
-    public void test_leaveGroup_null_null() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void leaveGroup_null_null() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.leaveGroup(null, null);
@@ -529,10 +521,9 @@
         mss.close();
     }
 
-    public void test_leaveGroup_non_multicast_address_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void leaveGroup_non_multicast_address_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0), null);
@@ -542,10 +533,9 @@
         mss.close();
     }
 
-    public void test_leaveGroup_non_multicast_address_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void leaveGroup_non_multicast_address_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket(0);
         try {
             mss.leaveGroup(new InetSocketAddress(InetAddress.getByName("::1"), 0), null);
@@ -555,25 +545,23 @@
         mss.close();
     }
 
-    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
+    @Test
+    public void leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv4()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+        Assume.assumeTrue(supportsMulticast);
+        check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
                 ipv4NetworkInterface, GOOD_IPv4, BAD_IPv4);
     }
 
-    public void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
+    @Test
+    public void leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface_IPv6()
             throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+        Assume.assumeTrue(supportsMulticast);
+        check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
                 ipv6NetworkInterface, GOOD_IPv6, BAD_IPv6);
     }
 
-    private void test_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
+    private void check_leaveGroupLjava_net_SocketAddressLjava_net_NetworkInterface(
             NetworkInterface networkInterface, InetAddress group, InetAddress group2)
             throws Exception {
         SocketAddress groupSockAddr = null;
@@ -609,21 +597,19 @@
         }
     }
 
-    public void test_sendLjava_net_DatagramPacketB_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_sendLjava_net_DatagramPacketB(GOOD_IPv4);
+    @Test
+    public void sendLjava_net_DatagramPacketB_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_sendLjava_net_DatagramPacketB(GOOD_IPv4);
     }
 
-    public void test_sendLjava_net_DatagramPacketB_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_sendLjava_net_DatagramPacketB(GOOD_IPv6);
+    @Test
+    public void sendLjava_net_DatagramPacketB_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_sendLjava_net_DatagramPacketB(GOOD_IPv6);
     }
 
-    private void test_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception {
+    private void check_sendLjava_net_DatagramPacketB(InetAddress group) throws Exception {
         String msg = "Hello World";
         MulticastSocket sendingSocket = new MulticastSocket(0);
         MulticastSocket receivingSocket = createReceivingSocket(sendingSocket.getLocalPort());
@@ -641,10 +627,9 @@
         receivingSocket.close();
     }
 
-    public void test_setInterfaceLjava_net_InetAddress() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setInterfaceLjava_net_InetAddress() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket();
         mss.setInterface(InetAddress.getLocalHost());
         InetAddress theInterface = mss.getInterface();
@@ -662,17 +647,15 @@
         mss.close();
     }
 
-    public void test_setInterface_unbound_address_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setInterface_unbound_address_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         test_setInterface_unbound_address(GOOD_IPv4);
     }
 
-    public void test_setInterface_unbound_address_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setInterface_unbound_address_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         test_setInterface_unbound_address(GOOD_IPv6);
     }
 
@@ -687,10 +670,9 @@
         mss.close();
     }
 
-    public void test_setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setNetworkInterfaceLjava_net_NetworkInterface_null() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         // Validate that null interface is handled ok.
         MulticastSocket mss = new MulticastSocket();
         try {
@@ -701,10 +683,9 @@
         mss.close();
     }
 
-    public void test_setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setNetworkInterfaceLjava_net_NetworkInterface_round_trip() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         // Validate that we can get and set the interface.
         MulticastSocket mss = new MulticastSocket();
         mss.setNetworkInterface(ipv4NetworkInterface);
@@ -713,21 +694,19 @@
         mss.close();
     }
 
-    public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4);
+    @Test
+    public void setNetworkInterfaceLjava_net_NetworkInterface_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv4);
     }
 
-    public void test_setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6);
+    @Test
+    public void setNetworkInterfaceLjava_net_NetworkInterface_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_setNetworkInterfaceLjava_net_NetworkInterface(GOOD_IPv6);
     }
 
-    private void test_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group)
+    private void check_setNetworkInterfaceLjava_net_NetworkInterface(InetAddress group)
             throws IOException, InterruptedException {
         // Set up the receiving socket and join the group.
         Enumeration theInterfaces = NetworkInterface.getNetworkInterfaces();
@@ -761,10 +740,9 @@
         }
     }
 
-    public void test_setTimeToLiveI() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setTimeToLiveI() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket();
         mss.setTimeToLive(120);
         assertEquals("Returned incorrect 1st TTL", 120, mss.getTimeToLive());
@@ -773,20 +751,18 @@
         mss.close();
     }
 
-    public void test_setTTLB() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setTTLB() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket mss = new MulticastSocket();
         mss.setTTL((byte) 120);
         assertEquals("Failed to set TTL", 120, mss.getTTL());
         mss.close();
     }
 
-    public void test_ConstructorLjava_net_SocketAddress() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void constructorLjava_net_SocketAddress() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket ms = new MulticastSocket((SocketAddress) null);
         assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
         ms.bind(null);
@@ -817,10 +793,9 @@
         s.close();
     }
 
-    public void test_getLoopbackMode() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void getLoopbackMode() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket ms = new MulticastSocket(null);
         assertTrue("should not be bound", !ms.isBound() && !ms.isClosed() && !ms.isConnected());
         ms.getLoopbackMode();
@@ -829,10 +804,9 @@
         assertTrue("should be closed", ms.isClosed());
     }
 
-    public void test_setLoopbackModeZ() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setLoopbackModeZ() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         MulticastSocket ms = new MulticastSocket();
         ms.setLoopbackMode(true);
         assertTrue("loopback should be true", ms.getLoopbackMode());
@@ -842,21 +816,19 @@
         assertTrue("should be closed", ms.isClosed());
     }
 
-    public void test_setLoopbackModeSendReceive_IPv4() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_setLoopbackModeSendReceive(GOOD_IPv4);
+    @Test
+    public void setLoopbackModeSendReceive_IPv4() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_setLoopbackModeSendReceive(GOOD_IPv4);
     }
 
-    public void test_setLoopbackModeSendReceive_IPv6() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
-        test_setLoopbackModeSendReceive(GOOD_IPv6);
+    @Test
+    public void setLoopbackModeSendReceive_IPv6() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
+        check_setLoopbackModeSendReceive(GOOD_IPv6);
     }
 
-    private void test_setLoopbackModeSendReceive(InetAddress group) throws IOException {
+    private void check_setLoopbackModeSendReceive(InetAddress group) throws IOException {
         // Test send receive.
         final String message = "Hello, world!";
 
@@ -878,10 +850,9 @@
         socket.close();
     }
 
-    public void test_setReuseAddressZ() throws Exception {
-        if (!supportsMulticast) {
-            return;
-        }
+    @Test
+    public void setReuseAddressZ() throws Exception {
+        Assume.assumeTrue(supportsMulticast);
         // Test case were we to set ReuseAddress to false.
         MulticastSocket theSocket1 = new MulticastSocket(null);
         theSocket1.setReuseAddress(false);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java
index 68122b2..a7a70d1 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/SocketTest.java
@@ -1196,7 +1196,7 @@
          * that do not support urgent data
          */
         String platform = System.getProperty("os.name");
-        if (platform.equals("Dummy")) {
+        if (platform.equals("Fake")) {
             return;
         }
 
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 6ae5eb4..dafcff8 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
@@ -57,7 +57,7 @@
             long longBitsIn = nans[i];
             double dbl = Double.longBitsToDouble(longBitsIn);
             long longBitsOut = Double.doubleToRawLongBits(dbl);
-            // Sanity check
+            // Confidence check
             assertTrue(longBitsIn == longBitsOut);
 
             // Store the double and retrieve it
@@ -213,7 +213,7 @@
         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
+        assertTrue(Double.compare(negativeZero, positiveZero) < 0); // confidence check
 
         // Unlike Double.compare(), DoubleBuffer.compareTo() considers -0 == +0
         assertEquals(0, negativeZeroBuffer.compareTo(positiveZeroBuffer));
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java
index 884185a..6a26c55 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DateFormatTest.java
@@ -21,9 +21,12 @@
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.Locale;
+import java.util.Set;
 
 public class DateFormatTest extends junit.framework.TestCase {
 
@@ -42,18 +45,21 @@
 	 * @tests java.text.DateFormat#getAvailableLocales()
 	 */
 	public void test_getAvailableLocales() {
+		// Locale.getAvailableLocales() and DateFormat.getAvailableLocales() should have
+		// the same set of locales.
+		Set<Locale> expectedLocales = new HashSet<>(Arrays.asList(
+				Locale.getAvailableLocales()));
 		Locale[] locales = DateFormat.getAvailableLocales();
 		assertTrue("No locales", locales.length > 0);
+		assertEquals(expectedLocales.size(), locales.length);
 		boolean english = false, german = false;
-		for (int i = locales.length; --i >= 0;) {
-			if (locales[i].equals(Locale.ENGLISH))
+		for (Locale locale : locales) {
+			assertTrue("Locale.getAvailableLocales() doesn't have the locale " + locale,
+					expectedLocales.contains(locale));
+			if (locale.equals(Locale.ENGLISH))
 				english = true;
-			if (locales[i].equals(Locale.GERMAN))
+			if (locale.equals(Locale.GERMAN))
 				german = true;
-			DateFormat f1 = DateFormat.getDateTimeInstance(DateFormat.SHORT,
-					DateFormat.SHORT, locales[i]);
-			assertTrue("Doesn't work",
-					f1.format(new Date()).getClass() == String.class);
 		}
 		assertTrue("Missing locales", english && german);
 	}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
index 8b36163..15ce7cb 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/DecimalFormatTest.java
@@ -1664,11 +1664,11 @@
         // digits. This shows the value actually being tested.
         String testId = "decimalValue: " + new BigDecimal(d);
 
-        // As a sanity check we try out parseDouble() with the string generated by
+        // As a confidence check we try out parseDouble() with the string generated by
         // Double.toString(). Strictly speaking Double.toString() is probably not guaranteed to be
         // lossless, but in reality it probably is, or at least is close enough.
         assertDoubleEqual(
-                testId + " failed parseDouble(toString()) sanity check",
+                testId + " failed parseDouble(toString()) confidence check",
                 d, Double.parseDouble(Double.toString(d)));
 
         // Format the number: If this is lossy it is a problem. We are trying to check that it
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
index ec065a9..2629c06 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/CurrencyTest.java
@@ -235,7 +235,8 @@
         String[] dollar  = new String[] {"USD", "$", "US$", "$US", "$ US"};
         // BEGIN Android-changed
         // Starting CLDR 1.7 release, currency symbol for CAD changed to CA$ in some locales such as ja.
-        String[] cDollar = new String[] {"CA$", "CAD", "$", "Can$", "$CA"};
+        // Starting CLDR 38 release, currency symbol for CAD changed to $ CA in some locales such as ja-JP.
+        String[] cDollar = new String[] {"CA$", "CAD", "$", "Can$", "$CA", "$ CA"};
         // END Android-changed
 
         Currency currE   = Currency.getInstance("EUR");
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java
index 33b17c4..46365e1 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TimerTest.java
@@ -711,22 +711,22 @@
             testTask = new TimerTestTask();
             testTask.incrementCount(true);
             d = new Date(System.currentTimeMillis() + 100);
-            t.schedule(testTask, d, 100); // at least 9 times
-            testTask = new TimerTestTask();
-            testTask.incrementCount(true);
-            d = new Date(System.currentTimeMillis() + 200);
-            t.schedule(testTask, d, 100); // at least 7 times
+            t.schedule(testTask, d, 200); // at least 4 times
             testTask = new TimerTestTask();
             testTask.incrementCount(true);
             d = new Date(System.currentTimeMillis() + 300);
             t.schedule(testTask, d, 200); // at least 4 times
             testTask = new TimerTestTask();
             testTask.incrementCount(true);
+            d = new Date(System.currentTimeMillis() + 500);
+            t.schedule(testTask, d, 400); // at least 2 times
+            testTask = new TimerTestTask();
+            testTask.incrementCount(true);
             d = new Date(System.currentTimeMillis() + 100);
-            t.schedule(testTask, d, 200); // at least 4 times
+            t.schedule(testTask, d, 400); // at least 2 times
             Thread.sleep(3000);
-            assertTrue("Multiple tasks should have incremented counter 24 times not "
-                    + timerCounter, timerCounter >= 24);
+            assertTrue("Multiple tasks should have incremented counter 12 times not "
+                    + timerCounter, timerCounter >= 12);
             t.cancel();
         } finally {
             if (t != null)
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java
index 14506fb..f1df0c8 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/TreeMapTest.java
@@ -1902,26 +1902,26 @@
      * Regression test for HARMONY-5788.
      */
     public void test_entrySet_contains() throws Exception {
-        TreeMap master = new TreeMap<String, String>();
+        TreeMap main = new TreeMap<String, String>();
         TreeMap test_map = new TreeMap<String, String>();
 
-        master.put("null", null);
-        Object[] entry = master.entrySet().toArray();
+        main.put("null", null);
+        Object[] entry = main.entrySet().toArray();
         assertFalse("Empty map should not contain the null-valued entry",
                 test_map.entrySet().contains(entry[0]));
 
         Map<String, String> submap = test_map.subMap("a", "z");
-        entry = master.entrySet().toArray();
+        entry = main.entrySet().toArray();
         assertFalse("Empty submap should not contain the null-valued entry",
                 submap.entrySet().contains(entry[0]));
 
         test_map.put("null", null);
         assertTrue("entrySet().containsAll(...) should work with null values",
-                test_map.entrySet().containsAll(master.entrySet()));
+                test_map.entrySet().containsAll(main.entrySet()));
 
-        master.clear();
-        master.put("null", '0');
-        entry = master.entrySet().toArray();
+        main.clear();
+        main.put("null", '0');
+        entry = main.entrySet().toArray();
         assertFalse("Null-valued entry should not equal non-null-valued entry",
                 test_map.entrySet().contains(entry[0]));
     }
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 c8c5da9..a6e6577 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
@@ -495,7 +495,7 @@
             JarEntry entry = new JarEntry(entryName3);
             InputStream in = jar.getInputStream(entry);
             // BEGIN Android-added
-            byte[] dummy = getAllBytesFromStream(in);
+            byte[] fake = getAllBytesFromStream(in);
             // END Android-added
             assertNull("found certificates", entry.getCertificates());
         } catch (Exception e) {
@@ -507,7 +507,7 @@
             entry.setSize(1076);
             InputStream in = jar.getInputStream(entry);
             // BEGIN Android-added
-            byte[] dummy = getAllBytesFromStream(in);
+            byte[] fake = getAllBytesFromStream(in);
             // END Android-added
             fail("SecurityException should be thrown.");
         } catch (SecurityException e) {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java
index 09e4f66..5db1fcc 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/zip/ZipOutputStreamTest.java
@@ -338,7 +338,7 @@
 
         ZipEntry zipEntry;
 
-        // There's no sane way to access ONLY mtime
+        // There's no practical way to access ONLY mtime
         Field mtimeField = ZipEntry.class.getDeclaredField("mtime");
         mtimeField.setAccessible(true);
 
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
index d820689..305404e 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HandshakeCompletedEventTest.java
@@ -548,7 +548,7 @@
 
 
     /**
-     * Implements basically a dummy TrustManager. It stores the certificate
+     * Implements basically a fake TrustManager. It stores the certificate
      * chain it sees, so it can later be queried.
      */
     public static class TestTrustManager implements X509TrustManager {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java
index 44572ab..96384ad 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/javax/net/ssl/HostnameVerifierTest.java
@@ -40,6 +40,104 @@
         assertFalse(hv.verify("localhost", session));
     }
 
+    // copied and modified from apache http client test suite.
+    public void testVerify() throws Exception {
+        HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        InputStream in;
+        X509Certificate x509;
+        // CN=foo.com, no subjectAlt
+        in = new ByteArrayInputStream(X509_FOO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        mySSLSession session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("a.foo.com", session));
+        assertFalse(verifier.verify("bar.com", session));
+
+        // CN=花子.co.jp, no subjectAlt
+        in = new ByteArrayInputStream(X509_HANAKO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
+        assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
+
+        // CN=foo.com, subjectAlt=bar.com
+        in = new ByteArrayInputStream(X509_FOO_BAR);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("a.foo.com", session));
+        assertTrue(verifier.verify("bar.com", session));
+        assertFalse(verifier.verify("a.bar.com", session));
+
+        // CN=foo.com, subjectAlt=bar.com, subjectAlt=花子.co.jp
+        in = new ByteArrayInputStream(X509_FOO_BAR_HANAKO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("a.foo.com", session));
+        assertTrue(verifier.verify("bar.com", session));
+        assertFalse(verifier.verify("a.bar.com", session));
+        // The certificate has this name in the altnames section, but OkHostnameVerifier drops
+        // any altnames that are improperly encoded according to RFC 5280, which requires
+        // non-ASCII characters to be encoded in ASCII via Punycode.
+        assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
+        assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
+
+        // no CN, subjectAlt=foo.com
+        in = new ByteArrayInputStream(X509_NO_CNS_FOO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertTrue(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("a.foo.com", session));
+
+        // CN=foo.com, CN=bar.com, CN=花子.co.jp, no subjectAlt
+        in = new ByteArrayInputStream(X509_THREE_CNS_FOO_BAR_HANAKO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("a.foo.com", session));
+        assertFalse(verifier.verify("bar.com", session));
+        assertFalse(verifier.verify("a.bar.com", session));
+        assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
+        assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
+
+        // CN=*.foo.com, no subjectAlt
+        in = new ByteArrayInputStream(X509_WILD_FOO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("www.foo.com", session));
+        assertFalse(verifier.verify("\u82b1\u5b50.foo.com", session));
+        assertFalse(verifier.verify("a.b.foo.com", session));
+
+        // CN=*.co.jp, no subjectAlt
+        in = new ByteArrayInputStream(X509_WILD_CO_JP);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        assertFalse(verifier.verify("foo.co.jp", session));
+        assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
+
+        // CN=*.foo.com, subjectAlt=*.bar.com, subjectAlt=花子.co.jp
+        in = new ByteArrayInputStream(X509_WILD_FOO_BAR_HANAKO);
+        x509 = (X509Certificate) cf.generateCertificate(in);
+        session = new mySSLSession(new X509Certificate[] {x509});
+        // try the foo.com variations
+        assertFalse(verifier.verify("foo.com", session));
+        assertFalse(verifier.verify("www.foo.com", session));
+        assertFalse(verifier.verify("\u82b1\u5b50.foo.com", session));
+        assertFalse(verifier.verify("a.b.foo.com", session));
+        assertFalse(verifier.verify("bar.com", session));
+        assertTrue(verifier.verify("www.bar.com", session));
+        assertFalse(verifier.verify("a.b.bar.com", session));
+        // The certificate has this name in the altnames section, but OkHostnameVerifier drops
+        // any altnames that are improperly encoded according to RFC 5280, which requires
+        // non-ASCII characters to be encoded in ASCII via Punycode.
+        assertFalse(verifier.verify("\u82b1\u5b50.bar.com", session));
+        assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
+        assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
+    }
+
     public void testSubjectAlt() throws Exception {
         CertificateFactory cf = CertificateFactory.getInstance("X.509");
         InputStream in = new ByteArrayInputStream(X509_MULTIPLE_SUBJECT_ALT);
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java
index 37c6086..e8f1bc5 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/apache/harmony/kernel/dalvik/ThreadsTest.java
@@ -81,6 +81,7 @@
     public void test_parkFor_3() throws Exception {
         CyclicBarrier barrier = new CyclicBarrier(1);
         Parker parker = new Parker(barrier, false, 1000);
+        parker.disableRetry();
         Thread parkerThread = new Thread(parker);
 
         UNSAFE.unpark(parkerThread);
@@ -123,6 +124,7 @@
     public void test_parkUntil_3() throws Exception {
         CyclicBarrier barrier = new CyclicBarrier(1);
         Parker parker = new Parker(barrier, true, 1000);
+        parker.disableRetry();
         Thread parkerThread = new Thread(parker);
 
         UNSAFE.unpark(parkerThread);
@@ -139,6 +141,8 @@
      */
     private static class Parker implements Runnable {
 
+        private static final long NANOS_PER_MILLI = 1_000_000L;
+
         private final CyclicBarrier barrier;
 
         /** whether {@link #amount} is milliseconds to wait in an
@@ -146,6 +150,8 @@
          * in a relative fashion (<code>false</code>) */
         private final boolean absolute;
 
+        private boolean retryDisabled;
+
         /** amount to wait (see above) */
         private final long amount;
 
@@ -153,10 +159,10 @@
         private boolean completed;
 
         /** recorded start time */
-        private long startMillis;
+        private long startNanos;
 
         /** recorded end time */
-        private long endMillis;
+        private long endNanos;
 
         /**
          * Construct an instance.
@@ -168,9 +174,17 @@
         public Parker(CyclicBarrier barrier, boolean absolute, long parkMillis) {
             this.barrier = barrier;
             this.absolute = absolute;
-
+            // this.retryDisabled = false;
+            if (parkMillis < 10) {
+              // Doesn't work well with our retry logic, and likely to be flakey.
+              throw new AssertionError("Unexpectedly short park timeout.");
+            }
             // Multiply by 1000000 because parkFor() takes nanoseconds.
-            this.amount = absolute ? parkMillis : parkMillis * 1000000;
+            this.amount = absolute ? parkMillis : parkMillis * NANOS_PER_MILLI;
+        }
+
+        public void disableRetry() {
+          retryDisabled = true;
         }
 
         public void run() {
@@ -181,20 +195,29 @@
             }
             boolean absolute = this.absolute;
             long amount = this.amount;
-            long startNanos = System.nanoTime();
+            long startNs = System.nanoTime();
             long start = System.currentTimeMillis();
 
-            if (absolute) {
-                UNSAFE.park(true, start + amount);
-            } else {
-                UNSAFE.park(false, amount);
+            for (int i = 0; i < 2; ++i) {
+                if (absolute) {
+                    UNSAFE.park(true, start + amount);
+                } else {
+                    UNSAFE.park(false, amount);
+                }
+                // park() may wake up spuriously. For our implementation, this
+                // should be unlikely, except there are cases in which the
+                // initial attempt returns immediately. Try a second time, but
+                // only in that case.
+                if (retryDisabled || System.currentTimeMillis() - start > 1L) {
+                  break;
+                }
             }
 
-            long endNanos = System.nanoTime();
+            long endNs = System.nanoTime();
 
             synchronized (this) {
-                startMillis = startNanos / 1000000;
-                endMillis = endNanos / 1000000;
+                startNanos = startNs;
+                endNanos = endNs;
                 completed = true;
                 notifyAll();
             }
@@ -219,25 +242,23 @@
                     }
                 }
 
-                return endMillis - startMillis;
+                return (endNanos - startNanos) / NANOS_PER_MILLI;
             }
         }
 
         /**
-         * Asserts that the actual duration is within 10% of the
+         * Asserts that the actual duration is within 150-200 msecs of the
          * given expected time.
+         * Observe that small errors in either direction are normal here; for a
+         * number of tests the value will be too small if the Parker thread
+         * starts late, e.g. because it doesn't get a time slice soon enough.
          *
          * @param expectedMillis the expected duration, in milliseconds
          */
         public void assertDurationIsInRange(long expectedMillis) {
-            /*
-             * Allow a bit more slop for the maximum on "expected
-             * instantaneous" results.
-             */
-            long minimum = (long) ((double) expectedMillis * 0.80);
-            long maximum =
-                Math.max((long) ((double) expectedMillis * 1.20), 10);
-            long waitMillis = Math.max(expectedMillis * 10, 1000);
+            long minimum = Math.max(expectedMillis - 150L, 0L);
+            long maximum = expectedMillis + 200L;
+            long waitMillis = Math.max(expectedMillis * 10L, 1000L);
             long duration = getDurationMillis(waitMillis);
 
             if (duration < minimum) {
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java
index 2c93189..d09e3a7 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/org/xml/sax/support/MockFilter.java
@@ -29,7 +29,7 @@
 import org.xml.sax.helpers.XMLFilterImpl;
 
 /**
- * A helper class that extends XMLFilterImpl, provides dummy feature/property
+ * A helper class that extends XMLFilterImpl, provides fake feature/property
  * management, and logs some method calls.
  */
 public class MockFilter extends XMLFilterImpl {
diff --git a/json/src/main/java/org/json/JSONObject.java b/json/src/main/java/org/json/JSONObject.java
index 40d15bb..2a2df62 100644
--- a/json/src/main/java/org/json/JSONObject.java
+++ b/json/src/main/java/org/json/JSONObject.java
@@ -674,11 +674,13 @@
      *
      * See {@link #keys()}.
      *
+     * @return set of keys in this object
+     *
      * @hide.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public Set<String> keySet() {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @NonNull public Set<@NonNull String> keySet() {
         return nameValuePairs.keySet();
     }
 
diff --git a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
index 44d12b3..71be06c 100644
--- a/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
+++ b/jsr166-tests/src/test/java/jsr166/FutureTaskTest.java
@@ -467,8 +467,8 @@
             shouldThrow();
         } catch (SecurityException expected) {}
 
-        // We failed to deliver the interrupt, but the world retains
-        // its sanity, as if we had done task.cancel(false)
+        // We failed to deliver the interrupt, but the world remains
+        // consistent, as if we had done task.cancel(false)
         assertTrue(task.isCancelled());
         assertTrue(task.isDone());
         assertEquals(1, task.runCount());
diff --git a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
index ea6e576..c073f1d 100644
--- a/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
+++ b/jsr166-tests/src/test/java/jsr166/JSR166TestCase.java
@@ -956,7 +956,7 @@
      * Uninteresting threads are filtered out.
      */
     static void dumpTestThreads() {
-        // Android-change no ThreadMXBean
+        // Android-removed: no ThreadMXBean.
         // ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
         // System.err.println("------ stacktrace dump start ------");
         // for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
@@ -1089,7 +1089,7 @@
      * getPolicy/setPolicy.
      */
     public void runWithPermissions(Runnable r, Permission... permissions) {
-        // Android-changed: no SecurityManager
+        // Android-removed: no SecurityManager.
         // SecurityManager sm = System.getSecurityManager();
         // if (sm == null) {
         //     r.run();
@@ -1107,7 +1107,7 @@
      */
     public void runWithSecurityManagerWithPermissions(Runnable r,
                                                       Permission... permissions) {
-        // Android-changed: no SecurityManager
+        // Android-removed: no SecurityManager.
         // SecurityManager sm = System.getSecurityManager();
         // if (sm == null) {
         //     Policy savedPolicy = Policy.getPolicy();
diff --git a/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java b/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
index 0318c83..450f2ff 100644
--- a/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
+++ b/libart/src/main/java/dalvik/system/AnnotatedStackTraceElement.java
@@ -16,6 +16,9 @@
 
 package dalvik.system;
 
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
 /**
  * A class encapsulating a StackTraceElement and lock state. This adds
  * critical thread state to the standard stack trace information, which
@@ -23,8 +26,8 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
-public class AnnotatedStackTraceElement {
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public final class AnnotatedStackTraceElement {
     /**
      * The traditional StackTraceElement describing the Java stack frame.
      */
@@ -36,7 +39,7 @@
     private Object[] heldLocks;
 
     /**
-     * If this frame denotes the top of stack, <code>blockedOn<code> will hold
+     * If this frame denotes the top of stack, {@code blockedOn} will hold
      * the object this thread is waiting to lock, or waiting on, if any. May be
      * null.
      */
@@ -46,18 +49,36 @@
     private AnnotatedStackTraceElement() {
     }
 
-    @libcore.api.CorePlatformApi
-    public StackTraceElement getStackTraceElement() {
+    /**
+     * Returns the {@link StackTraceElement} describing the Java stack frame.
+     *
+     * @return {@link StackTraceElement} describing the Java stack frame.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @NonNull public StackTraceElement getStackTraceElement() {
         return stackTraceElement;
     }
 
-    @libcore.api.CorePlatformApi
-    public Object[] getHeldLocks() {
+    /**
+     * Returns the objects this stack frame is synchronized on.
+     * May be {@code null}.
+     *
+     * @return array of objects current frame is syncronized on.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @Nullable public Object[] getHeldLocks() {
         return heldLocks;
     }
 
-    @libcore.api.CorePlatformApi
-    public Object getBlockedOn() {
+    /**
+     * Returns the object this stack frame is waiting on for synchronization.
+     * May be {@code null}.
+     *
+     * @return object this thread is waiting to lock, or waiting on, if any,
+     *         or {@code null}, if none.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @Nullable public Object getBlockedOn() {
         return blockedOn;
     }
 }
diff --git a/libart/src/main/java/dalvik/system/VMRuntime.java b/libart/src/main/java/dalvik/system/VMRuntime.java
index 321f4e3..0c8b375 100644
--- a/libart/src/main/java/dalvik/system/VMRuntime.java
+++ b/libart/src/main/java/dalvik/system/VMRuntime.java
@@ -17,10 +17,15 @@
 package dalvik.system;
 
 import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledAfter;
+import android.compat.annotation.EnabledSince;
+import android.compat.annotation.Disabled;
 import android.compat.annotation.UnsupportedAppUsage;
 
 import dalvik.annotation.compat.VersionCodes;
+import dalvik.annotation.optimization.CriticalNative;
+import dalvik.annotation.optimization.FastNative;
+
+import libcore.api.CorePlatformApi;
 
 import java.lang.ref.FinalizerReference;
 import java.util.HashMap;
@@ -28,9 +33,6 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
-import dalvik.annotation.optimization.CriticalNative;
-import dalvik.annotation.optimization.FastNative;
-
 /**
  * Provides an interface to VM-global, Dalvik-specific features.
  * An application cannot create its own Runtime instance, and must obtain
@@ -38,7 +40,8 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+@libcore.api.IntraCoreApi
 public final class VMRuntime {
 
     /**
@@ -65,32 +68,41 @@
 
     /**
      * Remove meta-reflection workaround for hidden api usage for apps targeting R+. This allowed
-     * apps to obtain references to blacklisted fields and methods through an extra layer of
+     * apps to obtain references to blocklist fields and methods through an extra layer of
      * reflection.
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
+    @EnabledSince(targetSdkVersion = VersionCodes.R)
     private static final long
-        PREVENT_META_REFLECTION_BLACKLIST_ACCESS = 142365358; // This is a bug id.
+        PREVENT_META_REFLECTION_BLOCKLIST_ACCESS = 142365358; // This is a bug id.
 
     /**
      * Gating access to greylist-max-p APIs.
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = VersionCodes.P)
+    @EnabledSince(targetSdkVersion = VersionCodes.Q)
     private static final long HIDE_MAXTARGETSDK_P_HIDDEN_APIS = 149997251; // This is a bug id.
 
     /**
      * Gating access to greylist-max-q APIs.
      */
     @ChangeId
-    @EnabledAfter(targetSdkVersion = VersionCodes.Q)
+    @EnabledSince(targetSdkVersion = VersionCodes.R)
     private static final long HIDE_MAXTARGETSDK_Q_HIDDEN_APIS = 149994052; // This is a bug id.
 
     /**
+     * Allow apps accessing @TestApi APIs.
+     *
+     * <p>This will always be disabled by default and should only be used by platform test code.
+     */
+    @ChangeId
+    @Disabled
+    private static final long ALLOW_TEST_API_ACCESS = 166236554; // This is a bug id.
+
+    /**
      * Interface for logging hidden API usage events.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public interface HiddenApiUsageLogger {
 
         // The following ACCESS_METHOD_ constants must match the values in
@@ -99,22 +111,26 @@
          * Internal test value that does not correspond to an actual access by the
          * application. Never logged, added for completeness.
          */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         public static final int ACCESS_METHOD_NONE = 0;
 
         /**
          *  Used when a method has been accessed via reflection.
          */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         public static final int ACCESS_METHOD_REFLECTION = 1;
 
         /**
          *  Used when a method has been accessed via JNI.
          */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         public static final int ACCESS_METHOD_JNI = 2;
 
         /**
          * Used when a method is accessed at link time. Never logged, added only
          * for completeness.
          */
+        @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
         public static final int ACCESS_METHOD_LINKING = 3;
 
         /**
@@ -141,8 +157,11 @@
      * Sets the hidden API usage logger {@link #hiddenApiUsageLogger}.
      * It should only be called if {@link #setHiddenApiAccessLogSamplingRate(int)}
      * is called with a value > 0
+     *
+     * @param hiddenApiUsageLogger an object implement {@code HiddenApiUsageLogger} that the runtime
+     *          will call for logging hidden API checks.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setHiddenApiUsageLogger(HiddenApiUsageLogger hiddenApiUsageLogger) {
         VMRuntime.hiddenApiUsageLogger = hiddenApiUsageLogger;
     }
@@ -166,7 +185,8 @@
      * any released version in {@code android.os.Build.VERSION_CODES}.
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    // Must match android.os.Build.VERSION_CODES.CUR_DEVELOPMENT.
     public static final int SDK_VERSION_CUR_DEVELOPMENT = 10000;
 
     private static Consumer<String> nonSdkApiUsageConsumer = null;
@@ -189,13 +209,12 @@
     }
 
     /**
-     * Returns the object that represents the VM instance's Dalvik-specific
-     * runtime environment.
-     *
+     * Returns the object that represents the current runtime.
      * @return the runtime object
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @libcore.api.IntraCoreApi
     public static VMRuntime getRuntime() {
         return THE_ONE;
     }
@@ -223,30 +242,39 @@
 
     /**
      * Returns the name of the shared library providing the VM implementation.
+     *
+     * @return the name of the shared library providing the VM implementation.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native String vmLibrary();
 
     /**
      * Returns the VM's instruction set.
+     *
+     * @return the VM's instruction set.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native String vmInstructionSet();
 
     /**
      * Returns whether the VM is running in 64-bit mode.
+     *
+     * @return true if VM is running in 64-bit mode, false otherwise.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     @FastNative
     public native boolean is64Bit();
 
     /**
      * Returns whether the VM is running with JNI checking enabled.
+     *
+     * @return true if the VM is running with JNI checking enabled,
+     *         and false otherwise.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public native boolean isCheckJniEnabled();
 
@@ -258,7 +286,6 @@
      *
      * @return the current ideal heap utilization
      */
-    @libcore.api.CorePlatformApi
     public native float getTargetHeapUtilization();
 
     /**
@@ -282,7 +309,6 @@
      * @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)");
@@ -305,10 +331,12 @@
      * Sets the target SDK version. Should only be called before the
      * app starts to run, because it may change the VM's behavior in
      * dangerous ways. Defaults to {@link #SDK_VERSION_CUR_DEVELOPMENT}.
+     *
+     * @param targetSdkVersion the SDK version the app wants to run with.
      */
     @UnsupportedAppUsage(maxTargetSdk=0, publicAlternatives="Use the {@code targetSdkVersion}"
         +" attribute in the {@code uses-sdk} manifest tag instead.")
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public synchronized void setTargetSdkVersion(int targetSdkVersion) {
         this.targetSdkVersion = targetSdkVersion;
         setTargetSdkVersionNative(this.targetSdkVersion);
@@ -319,8 +347,10 @@
      * Sets the disabled compat changes. Should only be called before the
      * app starts to run, because it may change the VM's behavior in
      * dangerous ways. Defaults to empty.
+     *
+     * @param disabledCompatChanges An array of ChangeIds that we want to disable.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public synchronized void setDisabledCompatChanges(long[] disabledCompatChanges) {
         this.disabledCompatChanges = disabledCompatChanges;
         setDisabledCompatChangesNative(this.disabledCompatChanges);
@@ -329,8 +359,10 @@
     /**
      * Gets the target SDK version. See {@link #setTargetSdkVersion} for
      * special values.
+     *
+     * @return the target SDK version.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public synchronized int getTargetSdkVersion() {
         return targetSdkVersion;
     }
@@ -413,20 +445,6 @@
     }
 
     /**
-     * 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();
-
-    /**
      * Sets the list of exemptions from hidden API access enforcement.
      *
      * @param signaturePrefixes
@@ -434,7 +452,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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void setHiddenApiExemptions(String[] signaturePrefixes);
 
     /**
@@ -443,34 +461,48 @@
      * @param rate Proportion of hidden API accesses that will be logged; an integer between
      *                0 and 0x10000 inclusive.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void setHiddenApiAccessLogSamplingRate(int rate);
 
     /**
      * Returns an array allocated in an area of the Java heap where it will never be moved.
      * This is used to implement native allocations on the Java heap, such as DirectByteBuffers
      * and Bitmaps.
+     *
+     * @param componentType the component type of the returned array.
+     * @param length the length of the returned array.
+     * @return array allocated in an area of the heap where it will never be moved.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @libcore.api.IntraCoreApi
     @FastNative
     public native Object newNonMovableArray(Class<?> componentType, int length);
 
     /**
-     * Returns an array of at least minLength, but potentially larger. The increased size comes from
-     * avoiding any padding after the array. The amount of padding varies depending on the
-     * componentType and the memory allocator implementation.
+     * Returns an array of at least {@code minLength}, but potentially larger. The increased size
+     * comes from avoiding any padding after the array. The amount of padding varies depending on
+     * the componentType and the memory allocator implementation.
+     *
+     * @param componentType the component type of the returned array.
+     * @param minLength     the minimum length of the returned array. The actual length could
+     *                      be greater.
+     * @return              array of at least of {@code minLength}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public native Object newUnpaddedArray(Class<?> componentType, int minLength);
 
     /**
-     * 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.
+     * Returns the address of {@code 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.
+     *
+     * @param array the object we want the native address of.
+     * @return native address of {@code array[0]}.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @libcore.api.IntraCoreApi
     @FastNative
     public native long addressOf(Object array);
 
@@ -479,20 +511,22 @@
      * up to the maximum heap size.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void clampGrowthLimit();
 
     /**
      * Returns true if native debugging is on.
+     *
+     * @return true if native debugging is on, false otherwise.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @FastNative
     public native boolean isNativeDebuggable();
 
@@ -510,37 +544,45 @@
      * 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.
+     *
+     * @param bytes the number of bytes of the native object.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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.
+     * Backward compatibility version of {@link #registerNativeAllocation(long)}. We used to pass
+     * an int instead of a long. The RenderScript support library looks it up via reflection.
+     * @deprecated Use {@link #registerNativeAllocation(long)} instead.
+     *
+     * @param bytes the number of bytes of the native object.
      */
     @UnsupportedAppUsage
     @Deprecated
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public void registerNativeAllocation(int bytes) {
         registerNativeAllocation((long) bytes);
     }
 
     /**
      * Registers a native free by reducing the number of native bytes accounted for.
+     *
+     * @param bytes the number of bytes of the freed object.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void registerNativeFree(long bytes);
 
     /**
-     * Backward compatibility version of registerNativeFree.
-     * @deprecated Use long argument instead.
+     * Backward compatibility version of {@link #registerNativeFree(long)}.
+     * @deprecated Use {@link #registerNativeFree(long)} instead.
+     *
+     * @param bytes the number of bytes of the freed object.
      */
     @UnsupportedAppUsage
     @Deprecated
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public void registerNativeFree(int bytes) {
         registerNativeFree((long) bytes);
     }
@@ -604,9 +646,12 @@
         }
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Request that a garbage collection gets started on a different thread.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void requestConcurrentGC();
-    public native void concurrentGC();
+
     public native void requestHeapTrim();
     public native void trimHeap();
     public native void startHeapTaskProcessor();
@@ -616,31 +661,70 @@
     /**
      * Let the heap know of the new process state. This can change allocation and garbage collection
      * behavior regarding trimming and compaction.
+     *
+     * @param state The state of the process, as defined in art/runtime/process_state.h.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void preloadDexCaches();
 
     /**
-     * Register application info.
-     * @param profileFile the path of the file where the profile information should be stored.
-     * @param codePaths the code paths that should be profiled.
+     * Flag denoting that the code paths passed to
+     * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
+     * contains the app primary APK.
      */
-    @libcore.api.CorePlatformApi
-    public static native void registerAppInfo(String profileFile, String[] codePaths);
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static final int CODE_PATH_TYPE_PRIMARY_APK = 1 << 0;
+    /**
+     * Flag denoting that the code paths passed to
+     * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
+     * contains the a split APK.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static final int CODE_PATH_TYPE_SPLIT_APK = 1 << 1;
+    /**
+     * Flag denoting that the code paths passed to
+     * {@link #registerAppInfo(String, String, String, String[], int, boolean)}
+     * contains a secondary dex file (dynamically loaded by the app).
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static final int CODE_PATH_TYPE_SECONDARY_DEX = 1 << 2;
+
+    /**
+     * Register application info to ART.
+     * This enables ART to support certain low level features (such as profiling) and provide
+     * better debug information. The method should be called after the application loads its
+     * apks or dex files.
+     *
+     * @param packageName the name of the package being ran.
+     * @param currentProfileFile the path of the file where the profile information for the current
+     *        execution should be stored.
+     * @param referenceProfileFile the path of the file where the reference profile information
+     *        (for past executions) is stored.
+     * @param appCodePaths the code paths (apk/dex files) of the applications that were loaded.
+     *        These paths will also be profiled.
+     * @param codePathsTypes the type of the code paths.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static native void registerAppInfo(
+            String packageName,
+            String currentProfileFile,
+            String referenceProfileFile,
+            String[] appCodePaths,
+            int codePathsType);
 
     /**
      * Returns the runtime instruction set corresponding to a given ABI. Multiple
@@ -648,9 +732,11 @@
      * {@code armeabi-v7a} and {@code armeabi} might map to the instruction set {@code arm}.
      *
      * This influences the compilation of the applications classes.
+     *
+     * @param abi The ABI we want the instruction set from.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String getInstructionSet(String abi) {
         final String instructionSet = ABI_TO_INSTRUCTION_SET_MAP.get(abi);
         if (instructionSet == null) {
@@ -660,51 +746,44 @@
         return instructionSet;
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Returns whether the given {@code instructionSet} is 64 bits.
+     *
+     * @param instructionSet a string representing an instruction set.
+     *
+     * @return true if given {@code instructionSet} is 64 bits, false otherwise.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean is64BitInstructionSet(String instructionSet) {
         return "arm64".equals(instructionSet) ||
                 "x86_64".equals(instructionSet) ||
                 "mips64".equals(instructionSet);
     }
 
+    /**
+     * Returns whether the given {@code abi} is 64 bits.
+     *
+     * @param abi a string representing an ABI.
+     *
+     * @return true if given {@code abi} is 64 bits, false otherwise.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean is64BitAbi(String abi) {
         return is64BitInstructionSet(getInstructionSet(abi));
     }
 
     /**
-     * Prevent initialization of the caller's class if they are calling
-     * from their clinit method. This works because calling a JNI method
-     * from clinit causes the transactional runtime to abort the current
-     * transaction.
-     * @hide
-     */
-    @CriticalNative
-    public static native void doNotInitializeInAot();
-
-    /**
      * Return false if the boot class path for the given instruction
      * 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();
-
-    /**
      * Used to notify the runtime that boot completed.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void bootCompleted();
 
     /**
@@ -712,29 +791,23 @@
      * profiling configuration to avoid samples during class preloading. This helps avoid
      * the regression from disabling class profiling.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void resetJitCounters();
 
     /**
      * Returns the instruction set of the current runtime.
+     *
+     * @return instruction set of the current runtime.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native String getCurrentInstructionSet();
 
     /**
-     * Return true if the dalvik cache was pruned when booting. This may have happened for
-     * 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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void registerSensitiveThread();
 
     /**
@@ -744,30 +817,38 @@
 
     /**
      * Sets a callback that the runtime can call whenever a usage of a non SDK API is detected.
+     *
+     * @param consumer an object implementing the {@code java.util.function.Consumer} interface that
+     *      the runtime will call whenever a usage of a non SDK API is detected.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setNonSdkApiUsageConsumer(Consumer<String> consumer) {
         nonSdkApiUsageConsumer = consumer;
     }
 
     /**
      * Sets whether or not the runtime should dedupe detection and warnings for hidden API usage.
-     * If deduping is enabled, only the first usage of each API will be detected. The default
-     * behaviour is to dedupe.
+     *
+     * @param dedupe if set, only the first usage of each API will be detected. The default
+     *      behaviour is to dedupe.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void setDedupeHiddenApiWarnings(boolean dedupe);
 
     /**
      * Sets the package name of the app running in this process.
+     *
+     * @param packageName the value being set
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void setProcessPackageName(String packageName);
 
     /**
      * Sets the full path to data directory of the app running in this process.
+     *
+     * @param dataDir the value being set
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void setProcessDataDirectory(String dataDir);
 
     /**
@@ -775,9 +856,11 @@
      * A class loader context is an internal opaque format used by the runtime to encode the
      * class loader hierarchy (including each ClassLoader's classpath) used to load a dex file.
      *
-     * @return True if encodedClassLoaderContext is a non-null valid encoded class loader context.
-     *   Throws NullPointerException if encodedClassLoaderContext is null.
+     * @param encodedClassLoaderContext the class loader context to analyze
+     * @throws NullPointerException if {@code encodedClassLoaderContext is null.
+     * @return {@code true} if {@code encodedClassLoaderContext} is a non-null valid encoded class
+     *         loader context.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native boolean isValidClassLoaderContext(String encodedClassLoaderContext);
 }
diff --git a/libart/src/main/java/java/lang/StringFactory.java b/libart/src/main/java/java/lang/StringFactory.java
index 6ef664b..ea80b9f 100644
--- a/libart/src/main/java/java/lang/StringFactory.java
+++ b/libart/src/main/java/java/lang/StringFactory.java
@@ -65,14 +65,6 @@
         return newStringFromBytes(data, 0, data.length, Charset.forNameUEE(charsetName));
     }
 
-    private static final int[] TABLE_UTF8_NEEDED = new int[] {
-    //      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
-            0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xc0 - 0xcf
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xd0 - 0xdf
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xe0 - 0xef
-            3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xf0 - 0xff
-    };
-
     // TODO: Implement this method natively.
     public static String newStringFromBytes(byte[] data, int offset, int byteCount, Charset charset) {
         if ((offset | byteCount) < 0 || byteCount > data.length - offset) {
@@ -85,147 +77,7 @@
         // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed.
         String canonicalCharsetName = charset.name();
         if (canonicalCharsetName.equals("UTF-8")) {
-            /*
-            This code converts a UTF-8 byte sequence to a Java String (UTF-16).
-            It implements the W3C recommended UTF-8 decoder.
-            https://www.w3.org/TR/encoding/#utf-8-decoder
-
-            Unicode 3.2 Well-Formed UTF-8 Byte Sequences
-            Code Points        First  Second Third Fourth
-            U+0000..U+007F     00..7F
-            U+0080..U+07FF     C2..DF 80..BF
-            U+0800..U+0FFF     E0     A0..BF 80..BF
-            U+1000..U+CFFF     E1..EC 80..BF 80..BF
-            U+D000..U+D7FF     ED     80..9F 80..BF
-            U+E000..U+FFFF     EE..EF 80..BF 80..BF
-            U+10000..U+3FFFF   F0     90..BF 80..BF 80..BF
-            U+40000..U+FFFFF   F1..F3 80..BF 80..BF 80..BF
-            U+100000..U+10FFFF F4     80..8F 80..BF 80..BF
-
-            Please refer to Unicode as the authority.
-            p.126 Table 3-7 in http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
-
-            Handling Malformed Input
-            The maximal subpart should be replaced by a single U+FFFD. Maximal subpart is
-            the longest code unit subsequence starting at an unconvertible offset that is either
-            1) the initial subsequence of a well-formed code unit sequence, or
-            2) a subsequence of length one:
-            One U+FFFD should be emitted for every sequence of bytes that is an incomplete prefix
-            of a valid sequence, and with the conversion to restart after the incomplete sequence.
-
-            For example, in byte sequence "41 C0 AF 41 F4 80 80 41", the maximal subparts are
-            "C0", "AF", and "F4 80 80". "F4 80 80" can be the initial subsequence of "F4 80 80 80",
-            but "C0" can't be the initial subsequence of any well-formed code unit sequence.
-            Thus, the output should be "A\ufffd\ufffdA\ufffdA".
-
-            Please refer to section "Best Practices for Using U+FFFD." in
-            http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
-            */
-            byte[] d = data;
-            char[] v = new char[byteCount];
-
-            int idx = offset;
-            int last = offset + byteCount;
-            int s = 0;
-
-            int codePoint = 0;
-            int utf8BytesSeen = 0;
-            int utf8BytesNeeded = 0;
-            int lowerBound = 0x80;
-            int upperBound = 0xbf;
-
-            while (idx < last) {
-                int b = d[idx++] & 0xff;
-                if (utf8BytesNeeded == 0) {
-                    if ((b & 0x80) == 0) { // ASCII char. 0xxxxxxx
-                        v[s++] = (char) b;
-                        continue;
-                    }
-
-                    if ((b & 0x40) == 0) { // 10xxxxxx is illegal as first byte
-                        v[s++] = REPLACEMENT_CHAR;
-                        continue;
-                    }
-
-                    // 11xxxxxx
-                    int tableLookupIndex = b & 0x3f;
-                    utf8BytesNeeded = TABLE_UTF8_NEEDED[tableLookupIndex];
-                    if (utf8BytesNeeded == 0) {
-                        v[s++] = REPLACEMENT_CHAR;
-                        continue;
-                    }
-
-                    // utf8BytesNeeded
-                    // 1: b & 0x1f
-                    // 2: b & 0x0f
-                    // 3: b & 0x07
-                    codePoint = b & (0x3f >> utf8BytesNeeded);
-                    if (b == 0xe0) {
-                        lowerBound = 0xa0;
-                    } else if (b == 0xed) {
-                        upperBound = 0x9f;
-                    } else if (b == 0xf0) {
-                        lowerBound = 0x90;
-                    } else if (b == 0xf4) {
-                        upperBound = 0x8f;
-                    }
-                } else {
-                    if (b < lowerBound || b > upperBound) {
-                        // The bytes seen are ill-formed. Substitute them with U+FFFD
-                        v[s++] = REPLACEMENT_CHAR;
-                        codePoint = 0;
-                        utf8BytesNeeded = 0;
-                        utf8BytesSeen = 0;
-                        lowerBound = 0x80;
-                        upperBound = 0xbf;
-                        /*
-                         * According to the Unicode Standard,
-                         * "a UTF-8 conversion process is required to never consume well-formed
-                         * subsequences as part of its error handling for ill-formed subsequences"
-                         * The current byte could be part of well-formed subsequences. Reduce the
-                         * index by 1 to parse it in next loop.
-                         */
-                        idx--;
-                        continue;
-                    }
-
-                    lowerBound = 0x80;
-                    upperBound = 0xbf;
-                    codePoint = (codePoint << 6) | (b & 0x3f);
-                    utf8BytesSeen++;
-                    if (utf8BytesNeeded != utf8BytesSeen) {
-                        continue;
-                    }
-
-                    // Encode chars from U+10000 up as surrogate pairs
-                    if (codePoint < 0x10000) {
-                        v[s++] = (char) codePoint;
-                    } else {
-                        v[s++] = (char) ((codePoint >> 10) + 0xd7c0);
-                        v[s++] = (char) ((codePoint & 0x3ff) + 0xdc00);
-                    }
-
-                    utf8BytesSeen = 0;
-                    utf8BytesNeeded = 0;
-                    codePoint = 0;
-                }
-            }
-
-            // The bytes seen are ill-formed. Substitute them by U+FFFD
-            if (utf8BytesNeeded != 0) {
-                v[s++] = REPLACEMENT_CHAR;
-            }
-
-            if (s == byteCount) {
-                // We guessed right, so we can use our temporary array as-is.
-                value = v;
-                length = s;
-            } else {
-                // Our temporary array was too big, so reallocate and copy.
-                value = new char[s];
-                length = s;
-                System.arraycopy(v, 0, value, 0, s);
-            }
+            return newStringFromUtf8Bytes(data, offset, byteCount);
         } else if (canonicalCharsetName.equals("ISO-8859-1")) {
             value = new char[byteCount];
             length = byteCount;
@@ -267,6 +119,9 @@
     @FastNative
     public static native String newStringFromString(String toCopy);
 
+    @FastNative
+    public static native String newStringFromUtf8Bytes(byte[] data, int offset, int byteCount);
+
     public static String newStringFromStringBuffer(StringBuffer stringBuffer) {
         synchronized (stringBuffer) {
             return newStringFromChars(stringBuffer.getValue(), 0, stringBuffer.length());
diff --git a/luni/Android.bp b/luni/Android.bp
new file mode 100644
index 0000000..ef9ab60
--- /dev/null
+++ b/luni/Android.bp
@@ -0,0 +1,31 @@
+//
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
+// Added automatically by a large-scale-change
+// http://go/android-license-faq
+license {
+    name: "libcore_luni_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "license.html",
+    ],
+}
diff --git a/luni/src/main/java/android/compat/Compatibility.java b/luni/src/main/java/android/compat/Compatibility.java
index 9b4b1af..2a55107 100644
--- a/luni/src/main/java/android/compat/Compatibility.java
+++ b/luni/src/main/java/android/compat/Compatibility.java
@@ -25,6 +25,7 @@
 import java.util.HashSet;
 import java.util.Objects;
 import java.util.Set;
+import libcore.util.NonNull;
 
 /**
  * Internal APIs for logging and gating compatibility changes.
@@ -33,7 +34,7 @@
  *
  * @hide
  */
-@CorePlatformApi
+@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
 @IntraCoreApi
 public final class Compatibility {
 
@@ -53,10 +54,10 @@
      *
      * @param changeId The ID of the compatibility change taking effect.
      */
-    @CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     @IntraCoreApi
-    public static void reportChange(@ChangeId long changeId) {
-        sCallbacks.reportChange(changeId);
+    public static void reportUnconditionalChange(@ChangeId long changeId) {
+        sCallbacks.onChangeReported(changeId);
     }
 
     /**
@@ -68,25 +69,45 @@
      * {@code false}, the calling code should behave as it did in earlier releases.
      *
      * <p>When this method returns {@code true}, it will also report the change as
-     * {@link #reportChange(long)} would, so there is no need to call that method directly.
+     * {@link #reportUnconditionalChange(long)} would, so there is no need to call that method
+     * directly.
      *
      * @param changeId The ID of the compatibility change in question.
      * @return {@code true} if the change is enabled for the current app.
      */
-    @CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     @IntraCoreApi
     public static boolean isChangeEnabled(@ChangeId long changeId) {
         return sCallbacks.isChangeEnabled(changeId);
     }
 
-    private volatile static Callbacks sCallbacks = new Callbacks();
+    private static final BehaviorChangeDelegate DEFAULT_CALLBACKS = new BehaviorChangeDelegate(){};
 
-    @CorePlatformApi
-    public static void setCallbacks(Callbacks callbacks) {
+    private volatile static BehaviorChangeDelegate sCallbacks = DEFAULT_CALLBACKS;
+
+    /**
+     * Sets the behavior change delegate.
+     *
+     * All changes reported via the {@link Compatibility} class will be forwarded to this class.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public static void setBehaviorChangeDelegate(BehaviorChangeDelegate callbacks) {
         sCallbacks = Objects.requireNonNull(callbacks);
     }
 
-    @CorePlatformApi
+    /**
+     * Removes a behavior change delegate previously set via {@link #setBehaviorChangeDelegate}.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public static void clearBehaviorChangeDelegate() {
+        sCallbacks = DEFAULT_CALLBACKS;
+    }
+
+    /**
+     * For use by tests only. Causes values from {@code overrides} to be returned instead of the
+     * real value.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public static void setOverrides(ChangeConfig overrides) {
         // Setting overrides twice in a row does not need to be supported because
         // this method is only for enabling/disabling changes for the duration of
@@ -99,7 +120,10 @@
         sCallbacks = new OverrideCallbacks(sCallbacks, overrides);
     }
 
-    @CorePlatformApi
+    /**
+     * For use by tests only. Removes overrides set by {@link #setOverrides}.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public static void clearOverrides() {
         if (!(sCallbacks instanceof OverrideCallbacks)) {
             throw new IllegalStateException("No overrides set");
@@ -114,31 +138,35 @@
      * This is provided as a class rather than an interface to allow new methods to be added without
      * breaking @CorePlatformApi binary compatibility.
      */
-    @CorePlatformApi
-    public static class Callbacks {
-        @CorePlatformApi
-        protected Callbacks() {
-        }
-        @CorePlatformApi
-        protected void reportChange(long changeId) {
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public interface BehaviorChangeDelegate {
+        /**
+         * Called when a change is reported via {@link Compatibility#reportUnconditionalChange}
+         */
+        @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+        default void onChangeReported(long changeId) {
             // Do not use String.format here (b/160912695)
             System.logW("No Compatibility callbacks set! Reporting change " + changeId);
         }
-        @CorePlatformApi
-        protected boolean isChangeEnabled(long changeId) {
+
+        /**
+         * Called when a change is queried via {@link Compatibility#isChangeEnabled}
+         */
+        @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+        default boolean isChangeEnabled(long changeId) {
             // Do not use String.format here (b/160912695)
             System.logW("No Compatibility callbacks set! Querying change " + changeId);
             return true;
         }
     }
 
-    @CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     @IntraCoreApi
     public static final class ChangeConfig {
         private final Set<Long> enabled;
         private final Set<Long> disabled;
 
-        public ChangeConfig(Set<Long> enabled, Set<Long> disabled) {
+        public ChangeConfig(@NonNull Set<@NonNull Long> enabled, @NonNull Set<@NonNull Long> disabled) {
             this.enabled = Objects.requireNonNull(enabled);
             this.disabled = Objects.requireNonNull(disabled);
             if (enabled.contains(null)) {
@@ -168,19 +196,19 @@
             return result;
         }
 
-        public long[] forceEnabledChangesArray() {
+        public @NonNull long[] getEnabledChangesArray() {
             return toLongArray(enabled);
         }
 
-        public long[] forceDisabledChangesArray() {
+        public @NonNull long[] getDisabledChangesArray() {
             return toLongArray(disabled);
         }
 
-        public Set<Long> forceEnabledSet() {
+        public @NonNull Set<@NonNull Long> getEnabledSet() {
             return Collections.unmodifiableSet(enabled);
         }
 
-        public Set<Long> forceDisabledSet() {
+        public @NonNull Set<@NonNull Long> getDisabledSet() {
             return Collections.unmodifiableSet(disabled);
         }
 
@@ -214,16 +242,16 @@
         }
     }
 
-    private static class OverrideCallbacks extends Callbacks {
-        private final Callbacks delegate;
+    private static class OverrideCallbacks implements BehaviorChangeDelegate {
+        private final BehaviorChangeDelegate delegate;
         private final ChangeConfig changeConfig;
 
-        private OverrideCallbacks(Callbacks delegate, ChangeConfig changeConfig) {
+        private OverrideCallbacks(BehaviorChangeDelegate delegate, ChangeConfig changeConfig) {
             this.delegate = Objects.requireNonNull(delegate);
             this.changeConfig = Objects.requireNonNull(changeConfig);
         }
         @Override
-        protected boolean isChangeEnabled(long changeId) {
+        public boolean isChangeEnabled(long changeId) {
            if (changeConfig.isForceEnabled(changeId)) {
                return true;
            }
diff --git a/luni/src/main/java/android/system/Int32Ref.java b/luni/src/main/java/android/system/Int32Ref.java
index c43c796..70c4876 100644
--- a/luni/src/main/java/android/system/Int32Ref.java
+++ b/luni/src/main/java/android/system/Int32Ref.java
@@ -24,13 +24,10 @@
  * @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 b4f6e74..a9f215b 100644
--- a/luni/src/main/java/android/system/NetlinkSocketAddress.java
+++ b/luni/src/main/java/android/system/NetlinkSocketAddress.java
@@ -27,9 +27,28 @@
  * Corresponds to Linux's {@code struct sockaddr_nl} from
  * <a href="https://github.com/torvalds/linux/blob/master/include/uapi/linux/netlink.h">&lt;linux/netlink.h&gt;</a>.
  *
+ * Netlink socket address descirbes a netlink client is user space or in kernel.
+ * A {@link NetlinkSocketAddress} can be either unicast (only sent to one peer)
+ * or sent to netlink multicast groups ({@code nlGroupsMask} not equal 0).
+ *
+ * Any {@link NetlinkSocketAddress} is described by {@code nlPortId} and {@code nlGroupsMask}.
+ *
+ * {@code nlPortId} is the unicast address of netlink socket. It's always 0
+ * if the destination is in the kernel. For a user-space process,
+ * {@nlPortId} is usually the PID of the process owning the destination
+ * socket. However, {@nlPortId} identifies a netlink socket, not a
+ * process. If a process owns several netlink sockets, then {@nlPortId}
+ * can be equal to the process ID only for at most one socket.
+ *
+ * {@code nlGroupsMask} is a bit mask with every bit representing a netlink
+ * group number. The default value for this field is zero which means that
+ * no multicasts will be received. A socket may multicast messages to any
+ * of the multicast groups by setting {@code nlGroupsMask} to a bit mask of
+ * the groups it wishes to send to.
+ *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class NetlinkSocketAddress extends SocketAddress {
     /** port ID */
     private final int nlPortId;
@@ -37,27 +56,45 @@
     /** multicast groups mask */
     private final int nlGroupsMask;
 
+    // VisibleForTesting
     public NetlinkSocketAddress() {
         this(0, 0);
     }
 
+    // VisibleForTesting
     public NetlinkSocketAddress(int nlPortId) {
         this(nlPortId, 0);
     }
 
+    /**
+     * Constructs an instance with the given port id and groups mask.
+     *
+     * @param nlPortId     port id
+     * @param nlGroupsMask groups mask
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public NetlinkSocketAddress(int nlPortId, int nlGroupsMask) {
         this.nlPortId = nlPortId;
         this.nlGroupsMask = nlGroupsMask;
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Returns this address's port id.
+     *
+     * @return port id
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public int getPortId() {
         return nlPortId;
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Returns this address's groups multicast mask.
+     *
+     * @return groups mask
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
old mode 100644
new mode 100755
index 70fdce5..437edc6
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -18,6 +18,10 @@
 
 import android.compat.annotation.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;
@@ -25,9 +29,6 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
-import libcore.io.Libcore;
-import libcore.util.NonNull;
-import libcore.util.Nullable;
 
 /**
  * Access to low-level system functionality. Most of these are system calls. Most users will want
@@ -73,20 +74,38 @@
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
      *
+     * @param hdr capabilities header, containing version and pid
+     * @return list of capabilities data structures, each containing effective, permitted,
+     *         and inheritable fields are bit masks of the capabilities
+     * @throws ErrnoException if {@code hdr} structure contains invalid data
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @Nullable StructCapUserData[] capget(@NonNull StructCapUserHeader hdr) throws ErrnoException {
         return Libcore.os.capget(hdr);
     }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/capset.2.html">capset(2)</a>.
      *
+     * @param hdr capabilities header, containing version and pid
+     * @param data capabilities data list, containing effective, permitted,
+     *             and inheritable fields. Must be the same length as returned value
+     * @throws ErrnoException if {@code hdr} structure contains invalid data; or
+     *                        an attempt was made to add a capability to the permitted
+     *                        set, or to set a capability in the effective set that is
+     *                        not in the permitted set; or
+     *                        the caller attempted to use
+     *                        {@link capset(StructCapUserHeader, StructCapUserData[])}
+     *                        to modify the capabilities of a thread other than itself,
+     *                        but lacked sufficient privilege;
+     *                        or there is no such thread.
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void capset(@NonNull StructCapUserHeader hdr, @NonNull StructCapUserData[] data)
             throws ErrnoException {
         Libcore.os.capset(hdr, data);
     }
@@ -224,10 +243,17 @@
     public static SocketAddress getpeername(FileDescriptor fd) throws ErrnoException { return Libcore.os.getpeername(fd); }
 
     /**
+     * Gets process's pgid (process group ID).
+     *
      * See <a href="http://man7.org/linux/man-pages/man2/getpgid.2.html">getpgid(2)</a>.
+     *
+     * @param pid process id to get the pgid of
+     * @return process's pgid
+     * @throws ErrnoException if {@code pid} does not match any process
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int getpgid(int pid) throws ErrnoException { return Libcore.os.getpgid(pid); }
 
     /**
@@ -246,9 +272,19 @@
     /** @hide */
     public static StructPasswd getpwuid(int uid) throws ErrnoException { return Libcore.os.getpwuid(uid); }
 
-    /** @hide */
-    @libcore.api.CorePlatformApi
-    public static StructRlimit getrlimit(int resource) throws ErrnoException { return Libcore.os.getrlimit(resource); }
+    /**
+     * Gets the resource limit.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man3/vlimit.3.html">getrlimit(2)</a>.
+     *
+     * @param resource resource id
+     * @return         the limit of the given resource
+     * @throws ErrnoException the value specified in {@code resource} is not valid
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @Nullable 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>.
@@ -261,13 +297,45 @@
     /** @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); }
+    /**
+     * Gets socket options for the socket referred to by the file descriptor {@code fd}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/getsockopt.2.html">getsockopt(2)</a>.
+     * For the list of available options see <a href="https://man7.org/linux/man-pages/man7/socket.7.html">socket(7)</a>.
+     *
+     * @param fd    file descriptor of the socket to get options of
+     * @param level level at which the {@code option} resides. For example,
+     *              to indicate that an option is to be interpreted by the TCP protocol,
+     *              level should be set to the protocol number of TCP
+     * @param option name of the option to get
+     * @return socket options for file descriptor {@code fd}
+     * @throws ErrnoException if {@code fd} is invalid; or
+     *                        {@code option} is unknown at given {@code level}
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static int getsockoptInt(@NonNull 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); }
+    /**
+     * Gets {@link OsConstants#SO_LINGER} option for the socket referred to by the file descriptor {@code fd}.
+     * When enabled, a {@link close(FileDescriptor) or {@link shutdown(FileDescriptor, int)} will
+     * not return until all queued messages for the socket have been successfully sent or the
+     * linger timeout has been reached. Otherwise, the call returns immediately and the closing is
+     * done in the background.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man7/socket.7.html">socket(7)</a>.
+     *
+     * @param fd     file descriptor of the socket to get {@code OsConstants.SO_LINGER} option of
+     * @param level  level at which the {@code option} resides
+     * @param option name of the option to get
+     * @return       {@link StructLinger} associated with given {@code fd}
+     * @throws ErrnoException
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @Nullable StructLinger getsockoptLinger(@NonNull 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>.
@@ -314,11 +382,22 @@
     /** @hide */
     public static InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return Libcore.os.ioctlInetAddress(fd, cmd, interfaceName); }
 
-
-    /** @hide */
-    @libcore.api.CorePlatformApi
-    public static int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException {
-        return Libcore.os.ioctlInt(fd, cmd, arg);
+    /**
+     * See <a href="https://man7.org/linux/man-pages/man2/ioctl.2.html">ioctl(3)</a>.
+     * System call manipulates the underlying device parameters of special files. In particular,
+     * many operating characteristics of character special files.
+     *
+     * @param fd    an open file descriptor
+     * @param cmd   encoded in it whether the argument is an "in" parameter or "out" parameter
+     * @return      returns a nonnegative value on success
+     * @throws ErrnoException A checked exception thrown when {@link Os} methods fail.
+     *                        {@see android.system.ErrnoException}
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static int ioctlInt(@NonNull FileDescriptor fd, int cmd) throws ErrnoException {
+        return Libcore.os.ioctlInt(fd, cmd);
     }
 
     /**
@@ -416,9 +495,28 @@
      */
     public static FileDescriptor[] pipe() throws ErrnoException { return Libcore.os.pipe2(0); }
 
-    /** @hide */
-    @libcore.api.CorePlatformApi
-    public static FileDescriptor[] pipe2(int flags) throws ErrnoException { return Libcore.os.pipe2(flags); }
+    /**
+     * Creates a pipe, a unidirectional data channel that can be used for interprocess communication.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/pipe.2.html">pipe(2)</a>.
+     *
+     * @param flags bitmask of options, e.g. {@link OsConstants#O_CLOEXEC}, {@link OsConstants#O_DIRECT}
+     *              or {@link OsConstants#O_NONBLOCK}.
+     *              If {@code flags} is {@code 0}, then {@link pipe2(int)} is the same as {@link pipe()}.
+     * @return array of two file descriptors referring to the ends of the pipe, where
+     *         first file descriptor is the read end of the pipe, and second is a write end
+     * @throws ErrnoException if {@code flags} contains invalid value; or
+     *                        the per-process limit on the number of open file
+     *                        descriptors has been reached; or
+     *                        the system-wide limit on the total number of open files
+     *                        has been reached; or
+     *                        the user hard limit on memory that can be allocated for
+     *                        pipes has been reached and the caller is not privileged
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @Nullable 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>.
@@ -475,11 +573,27 @@
     public static String readlink(String path) throws ErrnoException { return Libcore.os.readlink(path); }
 
     /**
+     * Eexpands all symbolic links and resolves references to {@code /./},
+     * {@code /../} and extra {@code /} characters string named by path
+     * to produce a canonicalized absolute pathname.
+     *
      * See <a href="http://man7.org/linux/man-pages/man3/realpath.3.html">realpath(3)</a>.
+     *
+     * @param path string to resolve
+     * @return     resolved path if no error occurred. Returns {@code null} if {@code path}
+     *             is {@code null}
+     * @throws ErrnoException read or search permission was denied for a component of
+     *                        the path prefix; or an I/O error occurred while reading
+     *                        from the filesystem; or too many symbolic links were
+     *                        encountered in translating the pathname; or
+     *                        the named file does not exist; or a component of the path
+     *                        prefix is not a directory
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static String realpath(String path) throws ErrnoException { return Libcore.os.realpath(path); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    @libcore.api.IntraCoreApi
+    public static @Nullable String realpath(@Nullable 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>.
@@ -497,6 +611,11 @@
     public static int recvfrom(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException { return Libcore.os.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress); }
 
     /**
+     * See <a href="http://man7.org/linux/man-pages/man2/recvmsg.2.html">recvmsg(2)</a>.
+     */
+    public static int recvmsg(@NonNull FileDescriptor fd, @NonNull StructMsghdr msg, int flags) throws ErrnoException, SocketException { return Libcore.os.recvmsg(fd, msg, flags); }
+
+    /**
      * See <a href="http://man7.org/linux/man-pages/man3/remove.3.html">remove(3)</a>.
      */
     public static void remove(String path) throws ErrnoException { Libcore.os.remove(path); }
@@ -519,6 +638,13 @@
     }
 
     /**
+     * See <a href="http://man7.org/linux/man-pages/man2/sendmsg.2.html">sendmsg(2)</a>.
+     */
+    public static int sendmsg(@NonNull FileDescriptor fd, @NonNull StructMsghdr msg, int flags) throws ErrnoException, SocketException {
+        return Libcore.os.sendmsg(fd, msg, flags);
+    }
+
+    /**
      * See <a href="http://man7.org/linux/man-pages/man2/sendto.2.html">sendto(2)</a>.
      */
     public static int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException { return Libcore.os.sendto(fd, buffer, flags, inetAddress, port); }
@@ -560,24 +686,59 @@
     public static void setgid(int gid) throws ErrnoException { Libcore.os.setgid(gid); }
 
     /**
+     * Sets process's pgid (process group ID).
+     *
      * See <a href="http://man7.org/linux/man-pages/man2/setpgid.2.html">setpgid(2)</a>.
+     *
+     * @param pid  process id to set the pgid of
+     * @param pgid new pgid for process {@code pid}
+     * @throws ErrnoException an attempt was made to change the process group ID of one
+     *                        of the children of the calling process and the child had
+     *                        already performed an {@link execve(String, String[], String[])}; or
+     *                        {@code pgid} is less than {@code 0}; or
+     *                        an attempt was made to move a process into a process group
+     *                        in a different session, or to change the process group ID
+     *                        of one of the children of the calling process and the
+     *                        child was in a different session, or to change the process
+     *                        group ID of a session leader; or
+     *                        {@code pid} is not the calling process and not a child
+     *                        of the calling process
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setpgid(int pid, int pgid) throws ErrnoException { Libcore.os.setpgid(pid, pgid); }
 
     /**
+     * Set real and/or effective group ID of the calling process.
+     *
      * See <a href="http://man7.org/linux/man-pages/man2/setregid.2.html">setregid(2)</a>.
+     *
+     * @param rgid real group ID
+     * @param egid effective group ID
+     * @throws ErrnoException one or more of the target group IDs is not valid
+     *                        in this user namespace; or the calling process is
+     *                        not privileged
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setregid(int rgid, int egid) throws ErrnoException { Libcore.os.setregid(rgid, egid); }
 
     /**
+     * Set real and/or effective user ID of the calling process.
+     *
      * See <a href="http://man7.org/linux/man-pages/man2/setreuid.2.html">setreuid(2)</a>.
+     *
+     * @param ruid real user ID
+     * @param euid effective user ID
+     * @throws ErrnoException one or more of the target user IDs is not valid
+     *                        in this user namespace; or the calling process is
+     *                        not privileged
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setreuid(int ruid, int euid) throws ErrnoException { Libcore.os.setreuid(ruid, euid); }
 
     /**
@@ -588,10 +749,28 @@
     /** @hide */
     public static void setsockoptByte(FileDescriptor fd, int level, int option, int value) throws ErrnoException { Libcore.os.setsockoptByte(fd, level, option, value); }
 
-    /** @hide */
+    /**
+     * Sets a supplied socket {@code option} to {@code value}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/getsockopt.2.html">getsockopt(2)</a>.
+     * For the list of available options see <a href="https://man7.org/linux/man-pages/man7/socket.7.html">socket(7)</a>.
+     * Corresponding socket options constants reside in {@link OsCosntants}, e.g. {@link OsConstants#SO_REUSEADDR}.
+     *
+     * @param fd    file descriptor of the socket to set options of
+     * @param level level at which the {@code option} resides. For example,
+     *              to indicate that an option is to be interpreted by the TCP protocol,
+     *              level should be set to the protocol number of TCP
+     * @param option name of the option to set
+     * @param value  interface name
+     * @return socket options for file descriptor {@code fd}
+     * @throws ErrnoException if {@code fd} is invalid; or
+     *                        {@code option} is unknown at given {@code level}
+     *
+     * @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); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void setsockoptIfreq(@NonNull FileDescriptor fd, int level, int option, @Nullable 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>.
@@ -604,9 +783,21 @@
     /** @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); }
+    /**
+     * Sets {@link OsConstants#SO_LINGER} option for the socket referred to by the file descriptor
+     * {@code fd}.
+     *
+     * @param fd     file descriptor
+     * @param level  level at which the {@code option} resides
+     * @param option name of the option to set
+     * @param value  {@link StructLinger} to set for {@code fd}
+     * @throws ErrnoException if {@code fd} is invalid; or
+     *                        {@code option} is unknown at given {@code level}
+     *
+     * @hide
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void setsockoptLinger(@NonNull FileDescriptor fd, int level, int option, @NonNull 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>.
@@ -645,11 +836,64 @@
     public static void socketpair(int domain, int type, int protocol, FileDescriptor fd1, FileDescriptor fd2) throws ErrnoException { Libcore.os.socketpair(domain, type, protocol, fd1, fd2); }
 
     /**
+     * Moves data between two file descriptors without copying
+     * between kernel address space and user address space. It
+     * transfers up to {@code len} bytes of data from the file descriptor {@code fdIn}
+     * to the file descriptor {@code fdOut}, where one of the file descriptors
+     * must refer to a pipe.
+     *
+     * The following semantics apply for {@code fdIn} and {@code offIn}:
+     * <ul>
+     *   <li>If {@code fdIn} refers to a pipe, then {@code offIn} must be {@code null}.</li>
+     *   <li>If {@code fdIn} does not refer to a pipe and {@code offIn} is {@code null}, then
+     *       bytes are read from {@code fdIn} starting from the file offset, and
+     *       the file offset is adjusted appropriately.</li>
+     *   <li>If {@code fdIn} does not refer to a pipe and {@code offIn} is not {@code null}, then
+     *       {@code offIn} must point to a buffer which specifies the starting
+     *       offset from which bytes will be read from {@code fdIn}; in this case,
+     *       the file offset of {@code fdIn} is not changed.</li>
+     * </ul>
+     *
+     * Analogous statements apply for {@code fdOut} and {@code offOut}.
+     *
+     * The flags argument is a bit mask that is composed by ORing
+     * together zero or more of the following values:
+     * <ul>
+     *   <li>{@link OsConstants#SPLICE_F_MOVE}
+     *       Attempt to move pages instead of copying. This is only a
+     *       hint to the kernel: pages may still be copied if the
+     *       kernel cannot move the pages from the pipe, or if the pipe
+     *       buffers don't refer to full pages.</li>
+     *   <li>{@link OsConstants#SPLICE_F_NONBLOCK}
+     *       Do not block on I/O. This makes the splice pipe
+     *       operations nonblocking, but
+     *       {@link splice(FileDescriptor, Int64Ref, FileDescriptor, Int64Ref, long, int)}
+     *       may nevertheless block because the file descriptors that are spliced
+     *       to/from may block (unless they have the {@link OsConstants#O_NONBLOCK} flag set).</li>
+     *   <li>{@link OsConstants#SPLICE_F_MORE}
+     *       More data will be coming in a subsequent splice.</li>
+     *   <li>{@link OsConstants#SPLICE_F_GIFT} Unused</li>
+     * </ul>
+     *
      * See <a href="http://man7.org/linux/man-pages/man2/splice.2.html">splice(2)</a>.
+     *
+     * @param fdIn   file descriptor to read from
+     * @param offIn  {@code null} for pipe; file offset; or pointer to a buffer that specifies starting offset
+     * @param fdOut  file descriptor to write to
+     * @param offOut {@code null} for pipe; file offset; or pointer to a buffer that specifies starting offset
+     * @param len    number of bytes to read/write
+     * @param flags  bitmask of options
+     * @return       number of bytes spliced on success. A return value of {@code 0} means end of input.
+     * @throws ErrnoException if target fs does not support splicing; or
+     *                        target file opened in append mode; or
+     *                        one or both file descriptors are invalid; or
+     *                        neither of file descriptors refer to a pipe; or
+     *                        {@code fdIn} and {@code fdOut} refer to a same pipe
+     *
      * @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); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static long splice(@NonNull FileDescriptor fdIn, @Nullable Int64Ref offIn, @NonNull FileDescriptor fdOut, @Nullable Int64Ref offOut, long len, int flags) throws ErrnoException { return Libcore.os.splice(fdIn, offIn, fdOut, offOut, len, flags); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man2/stat.2.html">stat(2)</a>.
@@ -702,10 +946,23 @@
     public static StructUtsname uname() { return Libcore.os.uname(); }
 
     /**
-     * @hide See <a href="http://man7.org/linux/man-pages/man2/unlink.2.html">unlink(2)</a>.
+     * Deletes a name from the filesystem. If that name was the last link to a file
+     * and no processes have the file open, the file is deleted and the space it was
+     * using is made available for reuse.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/unlink.2.html">unlink(2)</a>.
+     *
+     * @param pathname name in the filesystem to delete
+     * @throws ErrnoException write access to {@code pathname} is not allowed; or
+     *                        I/O error occurred; or
+     *                        {@code pathname} refers to directory; or
+     *                        too many symbolic links were encountered in translating {@code pathname}; or
+     *                        {@code pathname} is used by the system or another process
+     *
+     * @hide
      */
-    @libcore.api.CorePlatformApi
-    public static void unlink(String pathname) throws ErrnoException { Libcore.os.unlink(pathname); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void unlink(@Nullable String pathname) throws ErrnoException { Libcore.os.unlink(pathname); }
 
     /**
      * See <a href="http://man7.org/linux/man-pages/man3/unsetenv.3.html">unsetenv(3)</a>.
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 1b0dc16..dabb41a 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -27,21 +27,30 @@
     }
 
     /**
-     * Returns the index of the element in the cap_user_data array that this capability is stored
-     * in.
+     * Returns the index of the element in the {@link StructCapUserData} (cap_user_data)
+     * array that this capability is stored in.
+     *
+     * @param x capability
+     * @return index of the element in the {@link StructCapUserData} array storing this capability
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int CAP_TO_INDEX(int x) { return x >>> 5; }
 
     /**
-     * Returns the mask for the given capability. This is relative to the capability's cap_user_data
-     * element, the index of which can be retrieved with CAP_TO_INDEX.
+     * Returns the mask for the given capability. This is relative to the capability's
+     * {@link StructCapUserData} (cap_user_data) element, the index of which can be
+     * retrieved with {@link CAP_TO_INDEX}.
+     *
+     * @param x capability
+     * @return mask for given capability
+     *
      * @hide
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int CAP_TO_MASK(int x) { return 1 << (x & 31); }
 
     /**
@@ -119,6 +128,15 @@
     public static final int AF_NETLINK = placeholder();
     public static final int AF_PACKET = placeholder();
     public static final int AF_UNIX = placeholder();
+
+    /**
+     * The virt-vsock address family, linux specific.
+     * It is used with {@code struct sockaddr_vm} from uapi/linux/vm_sockets.h.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+     * @see VmSocketAddress
+     */
+    public static final int AF_VSOCK = placeholder();
     public static final int AF_UNSPEC = placeholder();
     public static final int AI_ADDRCONFIG = placeholder();
     public static final int AI_ALL = placeholder();
@@ -128,9 +146,46 @@
     public static final int AI_PASSIVE = placeholder();
     public static final int AI_V4MAPPED = placeholder();
     public static final int ARPHRD_ETHER = placeholder();
-    /** @hide */
+
+    /**
+      * The virtio-vsock {@code svmPort} value to bind for any available port.
+      *
+      * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+      * @see VmSocketAddress
+      */
+    public static final int VMADDR_PORT_ANY = placeholder();
+
+    /**
+      * The virtio-vsock {@code svmCid} value to listens for all CIDs.
+      *
+      * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+      * @see VmSocketAddress
+      */
+    public static final int VMADDR_CID_ANY = placeholder();
+
+    /**
+      * The virtio-vsock {@code svmCid} value for host communication.
+      *
+      * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+      * @see VmSocketAddress
+      */
+    public static final int VMADDR_CID_LOCAL = placeholder();
+
+    /**
+      * The virtio-vsock {@code svmCid} value for loopback communication.
+      *
+      * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+      * @see VmSocketAddress
+      */
+    public static final int VMADDR_CID_HOST = placeholder();
+
+    /**
+     * ARP protocol loopback device identifier.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int ARPHRD_LOOPBACK = placeholder();
     public static final int CAP_AUDIT_CONTROL = placeholder();
     public static final int CAP_AUDIT_WRITE = placeholder();
@@ -231,9 +286,6 @@
     public static final int ENOLINK = placeholder();
     public static final int ENOMEM = placeholder();
     public static final int ENOMSG = placeholder();
-    /** @hide */
-    @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
     public static final int ENONET = placeholder();
     public static final int ENOPROTOOPT = placeholder();
     public static final int ENOSPC = placeholder();
@@ -266,9 +318,14 @@
     public static final int ETIME = placeholder();
     public static final int ETIMEDOUT = placeholder();
     public static final int ETXTBSY = placeholder();
-    /** @hide */
+    /**
+     * "Too many users" error.
+     * See <a href="https://man7.org/linux/man-pages/man3/errno.3.html">errno(3)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int EUSERS = placeholder();
     // On Linux, EWOULDBLOCK == EAGAIN. Use EAGAIN instead, to reduce confusion.
     public static final int EXDEV = placeholder();
@@ -354,15 +411,29 @@
     public static final int IP_RECVTOS = placeholder();
     public static final int IP_TOS = placeholder();
     public static final int IP_TTL = placeholder();
-    /** @hide */
+    /**
+     * Version constant to be used in {@link StructCapUserHeader} with
+     * {@link Os#capset(StructCapUserHeader, StructCapUserData[])} and
+     * {@link Os#capget(StructCapUserHeader)}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
     public static final int MAP_FIXED = placeholder();
     public static final int MAP_ANONYMOUS = placeholder();
-    /** @hide */
+    /**
+     * Flag argument for {@code mmap(long, long, int, int, FileDescriptor, long)}.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/mmap.2.html">mmap(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int MAP_POPULATE = placeholder();
     public static final int MAP_PRIVATE = placeholder();
     public static final int MAP_SHARED = placeholder();
@@ -400,9 +471,25 @@
     public static final int O_APPEND = placeholder();
     public static final int O_CLOEXEC = placeholder();
     public static final int O_CREAT = placeholder();
-    /** @hide */
+    /**
+     * Flag for {@code Os#open(String, int, int)}.
+     *
+     * When enabled, tries to minimize cache effects of the I/O to and from this
+     * file. In general this will degrade performance, but it is
+     * useful in special situations, such as when applications do
+     * their own caching. File I/O is done directly to/from
+     * user-space buffers. The {@link O_DIRECT} flag on its own makes an
+     * effort to transfer data synchronously, but does not give
+     * the guarantees of the {@link O_SYNC} flag that data and necessary
+     * metadata are transferred. To guarantee synchronous I/O,
+     * {@link O_SYNC} must be used in addition to {@link O_DIRECT}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/open.2.html">open(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int O_DIRECT = placeholder();
     public static final int O_EXCL = placeholder();
     public static final int O_NOCTTY = placeholder();
@@ -424,13 +511,28 @@
     public static final int POLLRDNORM = placeholder();
     public static final int POLLWRBAND = placeholder();
     public static final int POLLWRNORM = placeholder();
-    /** @hide */
+    /**
+     * Reads or changes the ambient capability set of the calling thread.
+     * Has to be used as a first argument for {@link Os#prctl(int, long, long, long, long)}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/prctl.2.html">prctl(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int PR_CAP_AMBIENT = placeholder();
-    /** @hide */
+    /**
+     * The capability specified in {@code arg3} of {@link Os#prctl(int, long, long, long, long)}
+     * is added to the ambient set. The specified capability must already
+     * be present in both the permitted and the inheritable sets of the process.
+     * Has to be used as a second argument for {@link Os#prctl(int, long, long, long, long)}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/prctl.2.html">prctl(2)</a>.
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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();
@@ -440,18 +542,36 @@
     public static final int PROT_READ = placeholder();
     public static final int PROT_WRITE = placeholder();
     public static final int R_OK = placeholder();
-    /** @hide */
+    /**
+     * Specifies a value one greater than the maximum file
+     * descriptor number that can be opened by this process.
+     *
+     * <p>Attempts ({@link Os#open(String, int, int)}, {@link Os#pipe()},
+     * {@link Os#dup(java.io.FileDescriptor)}, etc.) to exceed this
+     * limit yield the error {@link EMFILE}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man3/vlimit.3.html">getrlimit(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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 */
+    /**
+     * Bitmask for IPv4 addresses add/delete events multicast groups mask.
+     * Used in {@link NetlinkSocketAddress}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man7/netlink.7.html">netlink(7)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int RTMGRP_IPV4_IFADDR = placeholder();
     /** @hide */
     @UnsupportedAppUsage
@@ -560,6 +680,7 @@
     public static final int SOCK_SEQPACKET = placeholder();
     public static final int SOCK_STREAM = placeholder();
     public static final int SOL_SOCKET = placeholder();
+    public static final int SOL_UDP = placeholder();
     public static final int SO_BINDTODEVICE = placeholder();
     public static final int SO_BROADCAST = placeholder();
     public static final int SO_DEBUG = placeholder();
@@ -584,16 +705,38 @@
     public static final int SO_SNDLOWAT = placeholder();
     public static final int SO_SNDTIMEO = placeholder();
     public static final int SO_TYPE = placeholder();
-    /** @hide */
+    /**
+     * Bitmask for flags argument of
+     * {@link splice(java.io.FileDescriptor, Int64Ref, FileDescriptor, Int64Ref, long, int)}.
+     *
+     * Attempt to move pages instead of copying.  This is only a
+     * hint to the kernel: pages may still be copied if the
+     * kernel cannot move the pages from the pipe, or if the pipe
+     * buffers don't refer to full pages.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/splice.2.html">splice(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SPLICE_F_MOVE = placeholder();
     /** @hide */
     @UnsupportedAppUsage
     public static final int SPLICE_F_NONBLOCK = placeholder();
-    /** @hide */
+    /**
+     * Bitmask for flags argument of
+     * {@link splice(java.io.FileDescriptor, Int64Ref, FileDescriptor, Int64Ref, long, int)}.
+     *
+     * <p>Indicates that more data will be coming in a subsequent splice. This is
+     * a helpful hint when the {@code fdOut} refers to a socket.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/splice.2.html">splice(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SPLICE_F_MORE = placeholder();
     public static final int STDERR_FILENO = placeholder();
     public static final int STDIN_FILENO = placeholder();
@@ -632,20 +775,32 @@
     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 UDP_GRO = placeholder();
+    public static final int UDP_SEGMENT = placeholder();
+    /**
+     * Get the number of bytes in the output buffer.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man2/ioctl.2.html">ioctl(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int TIOCOUTQ = placeholder();
-    /** @hide */
+    /**
+     * Sockopt option to encapsulate ESP packets in UDP.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int UDP_ENCAP = placeholder();
     /** @hide */
     @UnsupportedAppUsage
     public static final int UDP_ENCAP_ESPINUDP_NON_IKE = placeholder();
     /** @hide */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int UDP_ENCAP_ESPINUDP = placeholder();
     /** @hide */
     @UnsupportedAppUsage
@@ -657,12 +812,30 @@
     public static final int WSTOPPED = placeholder();
     public static final int WUNTRACED = placeholder();
     public static final int W_OK = placeholder();
-    /** @hide */
+    /**
+     * {@code flags} option for {@link Os#setxattr(String, String, byte[], int)}.
+     *
+     * <p>Performs a pure create, which fails if the named attribute exists already.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/setxattr.2.html">setxattr(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int XATTR_CREATE = placeholder();
-    /** @hide */
+    /**
+     * {@code flags} option for {@link Os#setxattr(String, String, byte[], int)}.
+     *
+     * <p>Perform a pure replace operation, which fails if the named attribute
+     * does not already exist.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/setxattr.2.html">setxattr(2)</a>.
+     *
+     * @hide
+     */
     @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int XATTR_REPLACE = placeholder();
     public static final int X_OK = placeholder();
     public static final int _SC_2_CHAR_TERM = placeholder();
diff --git a/luni/src/main/java/android/system/PacketSocketAddress.java b/luni/src/main/java/android/system/PacketSocketAddress.java
index c3f15a6..f611775 100644
--- a/luni/src/main/java/android/system/PacketSocketAddress.java
+++ b/luni/src/main/java/android/system/PacketSocketAddress.java
@@ -26,9 +26,11 @@
  *
  * Corresponds to Linux's {@code struct sockaddr_ll}.
  *
+ * See <a href="https://man7.org/linux/man-pages/man7/packet.7.html">packet(7)</a>.
+ *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class PacketSocketAddress extends SocketAddress {
     /** Protocol. An Ethernet protocol type, e.g., {@link OsConstants#ETH_P_IPV6}. */
     public final int sll_protocol;
@@ -60,8 +62,17 @@
         this.sll_addr = sll_addr;
     }
 
-    /** Constructs a new PacketSocketAddress with all the "in" parameters. */
-    @libcore.api.CorePlatformApi
+    /**
+     * Constructs a new PacketSocketAddress with all the "in" parameters which
+     * correspond to Linux's {@code struct sockaddr_ll}.
+     *
+     * See <a href="https://man7.org/linux/man-pages/man7/packet.7.html">packet(7)</a>.
+     *
+     * @param sll_protocol protocol field in {@code struct sockaddr_ll}
+     * @param sll_ifindex  interface index number field in {@code struct sockaddr_ll}
+     * @param sll_addr     physical-layer address field in {@code struct sockaddr_ll}
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public PacketSocketAddress(int sll_protocol, int sll_ifindex, byte[] sll_addr) {
         this.sll_protocol = sll_protocol;
         this.sll_ifindex = sll_ifindex;
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructCapUserData.java
index c175898..f8865fa 100644
--- a/luni/src/main/java/android/system/StructCapUserData.java
+++ b/luni/src/main/java/android/system/StructCapUserData.java
@@ -20,27 +20,35 @@
 
 /**
  * Corresponds to Linux' __user_cap_data_struct for capget and capset.
+ * Used in {@link Os.capget(StructCapUserHeader)} and
+ * {@link Os.capset(StructCapUserHeader, StructCapUserData[])}.
+ *
+ * See <a href="https://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class StructCapUserData {
     /** Effective capability mask. */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final int effective; /* __u32 */
 
     /** Permitted capability mask. */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final int permitted; /* __u32 */
 
     /** Inheritable capability mask. */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final int inheritable; /* __u32 */
 
     /**
      * Constructs an instance with the given field values.
+     *
+     * @param effective   effective capability mask
+     * @param permitted   permitted capability mask
+     * @param inheritable inheritable capability mask
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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 aa1f876..424db1b 100644
--- a/luni/src/main/java/android/system/StructCapUserHeader.java
+++ b/luni/src/main/java/android/system/StructCapUserHeader.java
@@ -20,15 +20,21 @@
 
 /**
  * Corresponds to Linux' __user_cap_header_struct for capget and capset.
+ * Used in {@link Os.capget(StructCapUserHeader)} and
+ * {@link Os.capset(StructCapUserHeader, StructCapUserData[])}.
  *
+ * Capabilities defined in <a href="https://man7.org/linux/man-pages/man7/capabilities.7.html">capabilities(7)</a>
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class StructCapUserHeader {
     /**
      * Version of the header. Note this is not final as capget() may mutate the field when an
-     * invalid version is provided. See
-     * <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+     * invalid version is provided.
+     *
+     * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+     *
+     * @see {@link OsConstants._LINUX_CAPABILITY_VERSION_3}.
      */
     public int version; /* __u32 */
 
@@ -37,8 +43,11 @@
 
     /**
      * Constructs an instance with the given field values.
+     *
+     * @param version linux capability version
+     * @param pid     process id
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public StructCapUserHeader(int version, int pid) {
         this.version = version;
         this.pid = pid;
diff --git a/luni/src/main/java/android/system/StructCmsghdr.java b/luni/src/main/java/android/system/StructCmsghdr.java
new file mode 100755
index 0000000..1f2f3ed
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCmsghdr.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 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 android.system;
+
+import libcore.util.NonNull;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Corresponds to C's {@code struct cmsghdr}.
+ *
+ */
+public final class StructCmsghdr {
+    /** Originating protocol */
+    public final int cmsg_level;
+
+    /** Protocol-specific type */
+    public final int cmsg_type;
+
+    /** message data sent/received */
+    @NonNull public final byte[] cmsg_data;
+
+    public StructCmsghdr(int cmsg_level, int cmsg_type, short value) {
+        // Short.Size unit is bits, ByteBuffer data unit is bytes
+        ByteBuffer buf = ByteBuffer.allocate(Short.SIZE / 8);
+        buf.order(ByteOrder.nativeOrder());
+        buf.putShort(value);
+
+        this.cmsg_level = cmsg_level;
+        this.cmsg_type = cmsg_type;
+        this.cmsg_data = buf.array();
+    }
+
+    public StructCmsghdr(int cmsg_level, int cmsg_type, @NonNull byte[] value) {
+        this.cmsg_level = cmsg_level;
+        this.cmsg_type = cmsg_type;
+        this.cmsg_data = value;
+    }
+
+}
diff --git a/luni/src/main/java/android/system/StructLinger.java b/luni/src/main/java/android/system/StructLinger.java
index bf030a8..6726d59 100644
--- a/luni/src/main/java/android/system/StructLinger.java
+++ b/luni/src/main/java/android/system/StructLinger.java
@@ -22,24 +22,47 @@
  * Corresponds to C's {@code struct linger} from
  * <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html">&lt;sys/socket.h&gt;</a>
  *
+ * When enabled, a {@link Os.close(java.io.FileDescriptor) or
+ * {@link Os.shutdown(java.io.FileDescriptor, int)} will
+ * not return until all queued messages for the socket have been successfully sent or the
+ * linger timeout has been reached. Otherwise, the call returns immediately and the closing is
+ * done in the background.
+ *
+ * See <a href="https://man7.org/linux/man-pages/man7/socket.7.html">socket(7)</a>
+ * for linger struct description.
+ *
+ * @see {@link Os.getsockoptLinger(java.io.FileDescriptor, int, int)}.
+ * @see {@link OsConstants.SO_LINGER}.
+ *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public final int l_linger;
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Constructs linger structure.
+     *
+     * @param l_onoff  whether or not linger is enabled, non-zero is on
+     * @param l_linger linger time, in seconds
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public StructLinger(int l_onoff, int l_linger) {
         this.l_onoff = l_onoff;
         this.l_linger = l_linger;
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Returns whether linger is on or not.
+     *
+     * @return {@code true} if linger is enabled, and {@code false} otherwise
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public boolean isOn() {
         return l_onoff != 0;
     }
diff --git a/luni/src/main/java/android/system/StructMsghdr.java b/luni/src/main/java/android/system/StructMsghdr.java
new file mode 100755
index 0000000..9b5dcce
--- /dev/null
+++ b/luni/src/main/java/android/system/StructMsghdr.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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 android.system;
+
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * Corresponds to C's {@code struct msghdr}
+ *
+ */
+public final class StructMsghdr{
+    /**
+     * Optional address.
+     * <p>Sendmsg: Caller must populate to specify the target address for a datagram, or pass
+     * {@code null} to send to the destination of an already-connected socket.
+     * Recvmsg: Populated by the system to specify the source address.
+     */
+    @Nullable public SocketAddress msg_name;
+
+    /** Scatter/gather array */
+    @NonNull public final ByteBuffer[] msg_iov;
+
+    /** Ancillary data */
+    @Nullable public StructCmsghdr[] msg_control;
+
+    /** Flags on received message. */
+    public int msg_flags;
+
+    /**
+     * Constructs an instance with the given field values
+     */
+    public StructMsghdr(@Nullable SocketAddress msg_name, @NonNull ByteBuffer[] msg_iov,
+                        @Nullable StructCmsghdr[] msg_control, int msg_flags) {
+        this.msg_name = msg_name;
+        this.msg_iov = msg_iov;
+        this.msg_control = msg_control;
+        this.msg_flags = msg_flags;
+    }
+}
diff --git a/luni/src/main/java/android/system/StructRlimit.java b/luni/src/main/java/android/system/StructRlimit.java
index e1f3437..44a33a3 100644
--- a/luni/src/main/java/android/system/StructRlimit.java
+++ b/luni/src/main/java/android/system/StructRlimit.java
@@ -22,12 +22,16 @@
  * Information returned by {@link Os#getrlimit}. Corresponds to C's {@code struct rlimit} from
  * {@code <sys/resource.h>}.
  *
+ * See <a href="https://man7.org/linux/man-pages/man3/vlimit.3.html">getrlimit(2)</a>.
+ *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class StructRlimit {
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    /** Soft limit */
     public final long rlim_cur;
+    /** Hard limit (ceiling for rlim_cur) */
     public final long rlim_max;
 
     public StructRlimit(long rlim_cur, long rlim_max) {
diff --git a/luni/src/main/java/android/system/StructTimeval.java b/luni/src/main/java/android/system/StructTimeval.java
index 559056a..7b39462 100644
--- a/luni/src/main/java/android/system/StructTimeval.java
+++ b/luni/src/main/java/android/system/StructTimeval.java
@@ -43,11 +43,10 @@
         // 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;
+        if (tv_sec * 1000 > millis) {
+            --tv_sec;
         }
+        long tv_usec = (millis - (tv_sec * 1000)) * 1000;
         return new StructTimeval(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 993cc5b..71f4347 100644
--- a/luni/src/main/java/android/system/UnixSocketAddress.java
+++ b/luni/src/main/java/android/system/UnixSocketAddress.java
@@ -23,9 +23,13 @@
 /**
  * A UNIX-domain (AF_UNIX / AF_LOCAL) socket address.
  *
+ * See <a href="https://man7.org/linux/man-pages/man7/unix.7.html">unix(7)</a>.
+ *
+ * @see OsConstants#AF_UNIX
+ *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class UnixSocketAddress extends SocketAddress {
 
     private static final int NAMED_PATH_LENGTH = OsConstants.UNIX_PATH_MAX;
@@ -70,12 +74,15 @@
     }
 
     /**
-     * Creates a named, filesystem AF_UNIX socket address.
+     * Creates a named, filesystem {@link OsConstants#AF_UNIX} socket address.
      *
-     * @throws NullPointerException if {@code name} is null
+     * See <a href="https://man7.org/linux/man-pages/man7/unix.7.html">unix(7)</a>.
+     *
+     * @param pathname filename for named unix socket
+     * @throws NullPointerException if {@code name} is {@code null}
      * @throws IllegalArgumentException if {@code name} is invalid, e.g. too long
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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/android/system/VmSocketAddress.java b/luni/src/main/java/android/system/VmSocketAddress.java
new file mode 100644
index 0000000..8e4ddb0
--- /dev/null
+++ b/luni/src/main/java/android/system/VmSocketAddress.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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 android.system;
+
+import java.net.SocketAddress;
+import libcore.api.CorePlatformApi;
+import libcore.util.Objects;
+
+/**
+ * A virtio-vsock address {@link VmSocketAddress}.
+ *
+ * <p>
+ * virtio-vsock socket address, linux specific.
+ *
+ * <p>
+ * {@link VmSocketAddress} corresponds to {@code struct sockaddr_vm} in
+ * bionic/libc/kernel/uapi/linux/vm_sockets.h.
+ *
+ * <p>
+ * Currently virtio-vsock is used as a generic purpose pipe in emulators
+ * to talk to the host.
+ *
+ * @see <a href="https://man7.org/linux/man-pages/man7/vsock.7.html">vsock(7)</a>
+ * @hide
+ */
+@libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+public final class VmSocketAddress extends SocketAddress {
+    /**
+      * sockaddr_vm::svmPort, see {@code struct sockaddr_vm} in
+      * bionic/libc/kernel/uapi/linux/vm_sockets.h for more details.
+      */
+    private int svmPort;
+
+    /**
+      * sockaddr_vm::svmCid, see {@code struct sockaddr_vm} in
+      * bionic/libc/kernel/uapi/linux/vm_sockets.h for more details.
+      */
+    private int svmCid;
+
+    /**
+      * Creates a new instance of VmSocketAddress.
+      *
+      * @param svmPort      The svmPort field value,
+      *                     see {@link OsConstants.VMADDR_PORT_ANY}.
+      * @param svmCid       The svmCid field value,
+      *                     see OsConstants.VMADDR_CID_* for VMADDR_CID_* values.
+      */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public VmSocketAddress(int svmPort, int svmCid) {
+        this.svmPort = svmPort;
+        this.svmCid = svmCid;
+    }
+
+    /** Returns the value of the svmPort field */
+    @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public int getSvmPort() {
+        return svmPort;
+    }
+
+    /** Returns the value of the svmCid field */
+    @libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public int getSvmCid() {
+        return svmCid;
+    }
+}
diff --git a/luni/src/main/java/java/lang/ref/FinalizerReference.java b/luni/src/main/java/java/lang/ref/FinalizerReference.java
index 037af4a..a71044c 100644
--- a/luni/src/main/java/java/lang/ref/FinalizerReference.java
+++ b/luni/src/main/java/java/lang/ref/FinalizerReference.java
@@ -160,16 +160,15 @@
 
         synchronized void awaitFinalization(long timeout) throws InterruptedException {
             final long startTime = System.nanoTime();
-            final long endTime = startTime + timeout;
+            final long endTime = startTime + timeout;  // May wrap.
             while (!finalized) {
                 // 0 signifies no timeout.
                 if (timeout != 0) {
-                    final long currentTime = System.nanoTime();
-                    if (currentTime >= endTime) {
+                    final long deltaTime = endTime - System.nanoTime();
+                    if (deltaTime <= 0) {
                         break;
                     } else {
-                        final long deltaTime = endTime - currentTime;
-                        wait(deltaTime / 1000000, (int)(deltaTime % 1000000));
+                        wait(deltaTime / 1_000_000, (int)(deltaTime % 1_000_000));
                     }
                 } else {
                     wait();
diff --git a/luni/src/main/java/java/math/BigDecimal.java b/luni/src/main/java/java/math/BigDecimal.java
deleted file mode 100644
index 6ba251b..0000000
--- a/luni/src/main/java/java/math/BigDecimal.java
+++ /dev/null
@@ -1,2973 +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 java.math;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.Arrays;
-import libcore.math.MathUtils;
-
-/**
- * An immutable arbitrary-precision signed decimal.
- *
- * <p>A value is represented by an arbitrary-precision "unscaled value" and a signed 32-bit "scale",
- * combined thus: {@code unscaled * 10<sup>-scale</sup>}. See {@link #unscaledValue} and {@link #scale}.
- *
- * <p>Most operations allow you to supply a {@link MathContext} to specify a desired rounding mode.
- */
-public class BigDecimal extends Number implements Comparable<BigDecimal>, Serializable {
-
-    /**
-     * Rounding mode where positive values are rounded towards positive infinity
-     * and negative values towards negative infinity.
-     *
-     * @see RoundingMode#UP
-     */
-    public static final int ROUND_UP = 0;
-
-    /**
-     * Rounding mode where the values are rounded towards zero.
-     *
-     * @see RoundingMode#DOWN
-     */
-    public static final int ROUND_DOWN = 1;
-
-    /**
-     * Rounding mode to round towards positive infinity. For positive values
-     * this rounding mode behaves as {@link #ROUND_UP}, for negative values as
-     * {@link #ROUND_DOWN}.
-     *
-     * @see RoundingMode#CEILING
-     */
-    public static final int ROUND_CEILING = 2;
-
-    /**
-     * Rounding mode to round towards negative infinity. For positive values
-     * this rounding mode behaves as {@link #ROUND_DOWN}, for negative values as
-     * {@link #ROUND_UP}.
-     *
-     * @see RoundingMode#FLOOR
-     */
-    public static final int ROUND_FLOOR = 3;
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor.
-     * Ties are broken by rounding up.
-     *
-     * @see RoundingMode#HALF_UP
-     */
-    public static final int ROUND_HALF_UP = 4;
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor.
-     * Ties are broken by rounding down.
-     *
-     * @see RoundingMode#HALF_DOWN
-     */
-    public static final int ROUND_HALF_DOWN = 5;
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor.
-     * Ties are broken by rounding to the even neighbor.
-     *
-     * @see RoundingMode#HALF_EVEN
-     */
-    public static final int ROUND_HALF_EVEN = 6;
-
-    /**
-     * Rounding mode where the rounding operations throws an {@code
-     * ArithmeticException} for the case that rounding is necessary, i.e. for
-     * the case that the value cannot be represented exactly.
-     *
-     * @see RoundingMode#UNNECESSARY
-     */
-    public static final int ROUND_UNNECESSARY = 7;
-
-    /** This is the serialVersionUID used by the sun implementation. */
-    private static final long serialVersionUID = 6108874887143696463L;
-
-    /** The double closest to {@code Log10(2)}. */
-    private static final double LOG10_2 = 0.3010299956639812;
-
-    /** The <code>String</code> representation is cached. */
-    private transient String toStringImage = null;
-
-    /** Cache for the hash code. */
-    private transient int hashCode = 0;
-
-    /**
-     * An array with powers of five that fit in the type <code>long</code>
-     * (<code>5^0,5^1,...,5^27</code>).
-     */
-    private static final BigInteger[] FIVE_POW;
-
-    /**
-     * An array with powers of ten that fit in the type <code>long</code>
-     * (<code>10^0,10^1,...,10^18</code>).
-     */
-    private static final BigInteger[] TEN_POW;
-
-    private static final long[] LONG_FIVE_POW = new long[]
-    {   1L,
-        5L,
-        25L,
-        125L,
-        625L,
-        3125L,
-        15625L,
-        78125L,
-        390625L,
-        1953125L,
-        9765625L,
-        48828125L,
-        244140625L,
-        1220703125L,
-        6103515625L,
-        30517578125L,
-        152587890625L,
-        762939453125L,
-        3814697265625L,
-        19073486328125L,
-        95367431640625L,
-        476837158203125L,
-        2384185791015625L,
-        11920928955078125L,
-        59604644775390625L,
-        298023223876953125L,
-        1490116119384765625L,
-        7450580596923828125L, };
-
-    private static final int[] LONG_FIVE_POW_BIT_LENGTH = new int[LONG_FIVE_POW.length];
-    private static final int[] LONG_POWERS_OF_TEN_BIT_LENGTH = new int[MathUtils.LONG_POWERS_OF_TEN.length];
-
-    private static final int BI_SCALED_BY_ZERO_LENGTH = 11;
-
-    /**
-     * An array with the first <code>BigInteger</code> scaled by zero.
-     * (<code>[0,0],[1,0],...,[10,0]</code>).
-     */
-    private static final BigDecimal[] BI_SCALED_BY_ZERO = new BigDecimal[BI_SCALED_BY_ZERO_LENGTH];
-
-    /**
-     * An array with the zero number scaled by the first positive scales.
-     * (<code>0*10^0, 0*10^1, ..., 0*10^10</code>).
-     */
-    private static final BigDecimal[] ZERO_SCALED_BY = new BigDecimal[11];
-
-    /** An array filled with characters <code>'0'</code>. */
-    private static final char[] CH_ZEROS = new char[100];
-
-    static {
-        Arrays.fill(CH_ZEROS, '0');
-
-        for (int i = 0; i < ZERO_SCALED_BY.length; ++i) {
-            BI_SCALED_BY_ZERO[i] = new BigDecimal(i, 0);
-            ZERO_SCALED_BY[i] = new BigDecimal(0, i);
-        }
-        for (int i = 0; i < LONG_FIVE_POW_BIT_LENGTH.length; ++i) {
-            LONG_FIVE_POW_BIT_LENGTH[i] = bitLength(LONG_FIVE_POW[i]);
-        }
-        for (int i = 0; i < LONG_POWERS_OF_TEN_BIT_LENGTH.length; ++i) {
-            LONG_POWERS_OF_TEN_BIT_LENGTH[i] = bitLength(MathUtils.LONG_POWERS_OF_TEN[i]);
-        }
-
-        // Taking the references of useful powers.
-        TEN_POW = Multiplication.bigTenPows;
-        FIVE_POW = Multiplication.bigFivePows;
-    }
-
-    /**
-     * The constant zero as a {@code BigDecimal}.
-     */
-    public static final BigDecimal ZERO = new BigDecimal(0, 0);
-
-    /**
-     * The constant one as a {@code BigDecimal}.
-     */
-    public static final BigDecimal ONE = new BigDecimal(1, 0);
-
-    /**
-     * The constant ten as a {@code BigDecimal}.
-     */
-    public static final BigDecimal TEN = new BigDecimal(10, 0);
-
-    /**
-     * The arbitrary precision integer (unscaled value) in the internal
-     * representation of {@code BigDecimal}.
-     */
-    private BigInteger intVal;
-
-    private transient int bitLength;
-
-    private transient long smallValue;
-
-    /**
-     * The 32-bit integer scale in the internal representation of {@code BigDecimal}.
-     */
-    private int scale;
-
-    /**
-     * Represent the number of decimal digits in the unscaled value. This
-     * precision is calculated the first time, and used in the following calls
-     * of method <code>precision()</code>. Note that some call to the private
-     * method <code>inplaceRound()</code> could update this field.
-     *
-     * @see #precision()
-     * @see #inplaceRound(MathContext)
-     */
-    private transient int precision = 0;
-
-    private BigDecimal(long smallValue, int scale){
-        this.smallValue = smallValue;
-        this.scale = scale;
-        this.bitLength = bitLength(smallValue);
-    }
-
-    private BigDecimal(int smallValue, int scale){
-        this.smallValue = smallValue;
-        this.scale = scale;
-        this.bitLength = bitLength(smallValue);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string representation
-     * given as a character array.
-     *
-     * @param in
-     *            array of characters containing the string representation of
-     *            this {@code BigDecimal}.
-     * @param offset
-     *            first index to be copied.
-     * @param len
-     *            number of characters to be used.
-     * @throws NumberFormatException
-     *             if {@code offset < 0 || len <= 0 || offset+len-1 < 0 ||
-     *             offset+len-1 >= in.length}, or if {@code in} does not
-     *             contain a valid string representation of a big decimal.
-     */
-    public BigDecimal(char[] in, int offset, int len) {
-        int begin = offset; // first index to be copied
-        int last = offset + (len - 1); // last index to be copied
-        String scaleString; // buffer for scale
-        StringBuilder unscaledBuffer; // buffer for unscaled value
-        long newScale; // the new scale
-
-        if (in == null) {
-            throw new NullPointerException("in == null");
-        }
-        if ((last >= in.length) || (offset < 0) || (len <= 0) || (last < 0)) {
-            throw new NumberFormatException("Bad offset/length: offset=" + offset +
-                    " len=" + len + " in.length=" + in.length);
-        }
-        unscaledBuffer = new StringBuilder(len);
-        int bufLength = 0;
-        // To skip a possible '+' symbol
-        if ((offset <= last) && (in[offset] == '+')) {
-            offset++;
-            begin++;
-        }
-        int counter = 0;
-        boolean wasNonZero = false;
-        // Accumulating all digits until a possible decimal point
-        for (; (offset <= last) && (in[offset] != '.') && (in[offset] != 'e') && (in[offset] != 'E'); offset++) {
-            if (!wasNonZero) {
-                if (in[offset] == '0') {
-                    counter++;
-                } else {
-                    wasNonZero = true;
-                }
-            }
-
-        }
-        unscaledBuffer.append(in, begin, offset - begin);
-        bufLength += offset - begin;
-        // A decimal point was found
-        if ((offset <= last) && (in[offset] == '.')) {
-            offset++;
-            // Accumulating all digits until a possible exponent
-            begin = offset;
-            for (; (offset <= last) && (in[offset] != 'e')
-            && (in[offset] != 'E'); offset++) {
-                if (!wasNonZero) {
-                    if (in[offset] == '0') {
-                        counter++;
-                    } else {
-                        wasNonZero = true;
-                    }
-                }
-            }
-            scale = offset - begin;
-            bufLength +=scale;
-            unscaledBuffer.append(in, begin, scale);
-        } else {
-            scale = 0;
-        }
-        // An exponent was found
-        if ((offset <= last) && ((in[offset] == 'e') || (in[offset] == 'E'))) {
-            offset++;
-            // Checking for a possible sign of scale
-            begin = offset;
-            if ((offset <= last) && (in[offset] == '+')) {
-                offset++;
-                if ((offset <= last) && (in[offset] != '-')) {
-                    begin++;
-                }
-            }
-            // Accumulating all remaining digits
-            scaleString = String.valueOf(in, begin, last + 1 - begin);
-            // Checking if the scale is defined
-            newScale = (long)scale - Integer.parseInt(scaleString);
-            scale = (int)newScale;
-            if (newScale != scale) {
-                throw new NumberFormatException("Scale out of range");
-            }
-        }
-        // Parsing the unscaled value
-        if (bufLength < 19) {
-            smallValue = Long.parseLong(unscaledBuffer.toString());
-            bitLength = bitLength(smallValue);
-        } else {
-            setUnscaledValue(new BigInteger(unscaledBuffer.toString()));
-        }
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string representation
-     * given as a character array.
-     *
-     * @param in
-     *            array of characters containing the string representation of
-     *            this {@code BigDecimal}.
-     * @param offset
-     *            first index to be copied.
-     * @param len
-     *            number of characters to be used.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws NumberFormatException
-     *             if {@code offset < 0 || len <= 0 || offset+len-1 < 0 ||
-     *             offset+len-1 >= in.length}, or if {@code in} does not
-     *             contain a valid string representation of a big decimal.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(char[] in, int offset, int len, MathContext mc) {
-        this(in, offset, len);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string representation
-     * given as a character array.
-     *
-     * @param in
-     *            array of characters containing the string representation of
-     *            this {@code BigDecimal}.
-     * @throws NumberFormatException
-     *             if {@code in} does not contain a valid string representation
-     *             of a big decimal.
-     */
-    public BigDecimal(char[] in) {
-        this(in, 0, in.length);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string representation
-     * given as a character array. The result is rounded according to the
-     * specified math context.
-     *
-     * @param in
-     *            array of characters containing the string representation of
-     *            this {@code BigDecimal}.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws NumberFormatException
-     *             if {@code in} does not contain a valid string representation
-     *             of a big decimal.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(char[] in, MathContext mc) {
-        this(in, 0, in.length);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string
-     * representation.
-     *
-     * @throws NumberFormatException
-     *             if {@code val} does not contain a valid string representation
-     *             of a big decimal.
-     */
-    public BigDecimal(String val) {
-        this(val.toCharArray(), 0, val.length());
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a string
-     * representation. The result is rounded according to the specified math
-     * context.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws NumberFormatException
-     *             if {@code val} does not contain a valid string representation
-     *             of a big decimal.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(String val, MathContext mc) {
-        this(val.toCharArray(), 0, val.length());
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the 64bit double
-     * {@code val}. The constructed big decimal is equivalent to the given
-     * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
-     * 0.1000000000000000055511151231257827021181583404541015625}. This happens
-     * as {@code 0.1} cannot be represented exactly in binary.
-     * <p>
-     * To generate a big decimal instance which is equivalent to {@code 0.1} use
-     * the {@code BigDecimal(String)} constructor.
-     *
-     * @param val
-     *            double value to be converted to a {@code BigDecimal} instance.
-     * @throws NumberFormatException
-     *             if {@code val} is infinity or not a number.
-     */
-    public BigDecimal(double val) {
-        if (Double.isInfinite(val) || Double.isNaN(val)) {
-            throw new NumberFormatException("Infinity or NaN: " + val);
-        }
-        long bits = Double.doubleToLongBits(val); // IEEE-754
-        long mantissa;
-        int trailingZeros;
-        // Extracting the exponent, note that the bias is 1023
-        scale = 1075 - (int)((bits >> 52) & 0x7FFL);
-        // Extracting the 52 bits of the mantissa.
-        mantissa = (scale == 1075) ? (bits & 0xFFFFFFFFFFFFFL) << 1
-                : (bits & 0xFFFFFFFFFFFFFL) | 0x10000000000000L;
-        if (mantissa == 0) {
-            scale = 0;
-            precision = 1;
-        }
-        // To simplify all factors '2' in the mantissa
-        if (scale > 0) {
-            trailingZeros = Math.min(scale, Long.numberOfTrailingZeros(mantissa));
-            mantissa >>>= trailingZeros;
-            scale -= trailingZeros;
-        }
-        // Calculating the new unscaled value and the new scale
-        if((bits >> 63) != 0) {
-            mantissa = -mantissa;
-        }
-        int mantissaBits = bitLength(mantissa);
-        if (scale < 0) {
-            bitLength = mantissaBits == 0 ? 0 : mantissaBits - scale;
-            if(bitLength < 64) {
-                smallValue = mantissa << (-scale);
-            } else {
-                BigInt bi = new BigInt();
-                bi.putLongInt(mantissa);
-                bi.shift(-scale);
-                intVal = new BigInteger(bi);
-            }
-            scale = 0;
-        } else if (scale > 0) {
-            // m * 2^e =  (m * 5^(-e)) * 10^e
-            if(scale < LONG_FIVE_POW.length
-                    && mantissaBits+LONG_FIVE_POW_BIT_LENGTH[scale] < 64) {
-                smallValue = mantissa * LONG_FIVE_POW[scale];
-                bitLength = bitLength(smallValue);
-            } else {
-                setUnscaledValue(Multiplication.multiplyByFivePow(BigInteger.valueOf(mantissa), scale));
-            }
-        } else { // scale == 0
-            smallValue = mantissa;
-            bitLength = mantissaBits;
-        }
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the 64bit double
-     * {@code val}. The constructed big decimal is equivalent to the given
-     * double. For example, {@code new BigDecimal(0.1)} is equal to {@code
-     * 0.1000000000000000055511151231257827021181583404541015625}. This happens
-     * as {@code 0.1} cannot be represented exactly in binary.
-     * <p>
-     * To generate a big decimal instance which is equivalent to {@code 0.1} use
-     * the {@code BigDecimal(String)} constructor.
-     *
-     * @param val
-     *            double value to be converted to a {@code BigDecimal} instance.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws NumberFormatException
-     *             if {@code val} is infinity or not a number.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(double val, MathContext mc) {
-        this(val);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given big integer
-     * {@code val}. The scale of the result is {@code 0}.
-     */
-    public BigDecimal(BigInteger val) {
-        this(val, 0);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given big integer
-     * {@code val}. The scale of the result is {@code 0}.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(BigInteger val, MathContext mc) {
-        this(val);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a given unscaled value
-     * {@code unscaledVal} and a given scale. The value of this instance is
-     * {@code unscaledVal * 10<sup>-scale</sup>}).
-     *
-     * @throws NullPointerException
-     *             if {@code unscaledVal == null}.
-     */
-    public BigDecimal(BigInteger unscaledVal, int scale) {
-        if (unscaledVal == null) {
-            throw new NullPointerException("unscaledVal == null");
-        }
-        this.scale = scale;
-        setUnscaledValue(unscaledVal);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from a given unscaled value
-     * {@code unscaledVal} and a given scale. The value of this instance is
-     * {@code unscaledVal * 10<sup>-scale</sup>). The result is rounded according
-     * to the specified math context.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     * @throws NullPointerException
-     *             if {@code unscaledVal == null}.
-     */
-    public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
-        this(unscaledVal, scale);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given int
-     * {@code val}. The scale of the result is 0.
-     *
-     * @param val
-     *            int value to be converted to a {@code BigDecimal} instance.
-     */
-    public BigDecimal(int val) {
-        this(val,0);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given int {@code
-     * val}. The scale of the result is {@code 0}. The result is rounded
-     * according to the specified math context.
-     *
-     * @param val
-     *            int value to be converted to a {@code BigDecimal} instance.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code c.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(int val, MathContext mc) {
-        this(val,0);
-        inplaceRound(mc);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given long {@code
-     * val}. The scale of the result is {@code 0}.
-     *
-     * @param val
-     *            long value to be converted to a {@code BigDecimal} instance.
-     */
-    public BigDecimal(long val) {
-        this(val,0);
-    }
-
-    /**
-     * Constructs a new {@code BigDecimal} instance from the given long {@code
-     * val}. The scale of the result is {@code 0}. The result is rounded
-     * according to the specified math context.
-     *
-     * @param val
-     *            long value to be converted to a {@code BigDecimal} instance.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and the new big decimal cannot be represented
-     *             within the given precision without rounding.
-     */
-    public BigDecimal(long val, MathContext mc) {
-        this(val);
-        inplaceRound(mc);
-    }
-
-    /* Public Methods */
-
-    /**
-     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
-     * unscaledVal * 10<sup>-scale</sup>}). The scale of the result is {@code
-     * scale}, and its unscaled value is {@code unscaledVal}.
-     */
-    public static BigDecimal valueOf(long unscaledVal, int scale) {
-        if (scale == 0) {
-            return valueOf(unscaledVal);
-        }
-        if ((unscaledVal == 0) && (scale >= 0)
-                && (scale < ZERO_SCALED_BY.length)) {
-            return ZERO_SCALED_BY[scale];
-        }
-        return new BigDecimal(unscaledVal, scale);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
-     * unscaledVal}. The scale of the result is {@code 0}, and its unscaled
-     * value is {@code unscaledVal}.
-     *
-     * @param unscaledVal
-     *            value to be converted to a {@code BigDecimal}.
-     * @return {@code BigDecimal} instance with the value {@code unscaledVal}.
-     */
-    public static BigDecimal valueOf(long unscaledVal) {
-        if ((unscaledVal >= 0) && (unscaledVal < BI_SCALED_BY_ZERO_LENGTH)) {
-            return BI_SCALED_BY_ZERO[(int)unscaledVal];
-        }
-        return new BigDecimal(unscaledVal,0);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance whose value is equal to {@code
-     * val}. The new decimal is constructed as if the {@code BigDecimal(String)}
-     * constructor is called with an argument which is equal to {@code
-     * Double.toString(val)}. For example, {@code valueOf("0.1")} is converted to
-     * (unscaled=1, scale=1), although the double {@code 0.1} cannot be
-     * represented exactly as a double value. In contrast to that, a new {@code
-     * BigDecimal(0.1)} instance has the value {@code
-     * 0.1000000000000000055511151231257827021181583404541015625} with an
-     * unscaled value {@code 1000000000000000055511151231257827021181583404541015625}
-     * and the scale {@code 55}.
-     *
-     * @param val
-     *            double value to be converted to a {@code BigDecimal}.
-     * @return {@code BigDecimal} instance with the value {@code val}.
-     * @throws NumberFormatException
-     *             if {@code val} is infinite or {@code val} is not a number
-     */
-    public static BigDecimal valueOf(double val) {
-        if (Double.isInfinite(val) || Double.isNaN(val)) {
-            throw new NumberFormatException("Infinity or NaN: " + val);
-        }
-        return new BigDecimal(Double.toString(val));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
-     * The scale of the result is the maximum of the scales of the two
-     * arguments.
-     *
-     * @param augend
-     *            value to be added to {@code this}.
-     * @return {@code this + augend}.
-     * @throws NullPointerException
-     *             if {@code augend == null}.
-     */
-    public BigDecimal add(BigDecimal augend) {
-        int diffScale = this.scale - augend.scale;
-        // Fast return when some operand is zero
-        if (this.isZero()) {
-            if (diffScale <= 0) {
-                return augend;
-            }
-            if (augend.isZero()) {
-                return this;
-            }
-        } else if (augend.isZero()) {
-            if (diffScale >= 0) {
-                return this;
-            }
-        }
-        // Let be:  this = [u1,s1]  and  augend = [u2,s2]
-        if (diffScale == 0) {
-            // case s1 == s2: [u1 + u2 , s1]
-            if (Math.max(this.bitLength, augend.bitLength) + 1 < 64) {
-                return valueOf(this.smallValue + augend.smallValue, this.scale);
-            }
-            return new BigDecimal(this.getUnscaledValue().add(augend.getUnscaledValue()), this.scale);
-        } else if (diffScale > 0) {
-            // case s1 > s2 : [(u1 + u2) * 10 ^ (s1 - s2) , s1]
-            return addAndMult10(this, augend, diffScale);
-        } else {// case s2 > s1 : [(u2 + u1) * 10 ^ (s2 - s1) , s2]
-            return addAndMult10(augend, this, -diffScale);
-        }
-    }
-
-    private static BigDecimal addAndMult10(BigDecimal thisValue,BigDecimal augend, int diffScale) {
-        if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                Math.max(thisValue.bitLength,augend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) {
-            return valueOf(thisValue.smallValue+augend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],thisValue.scale);
-        } else {
-            BigInt bi = Multiplication.multiplyByTenPow(augend.getUnscaledValue(),diffScale).getBigInt();
-            bi.add(thisValue.getUnscaledValue().getBigInt());
-            return new BigDecimal(new BigInteger(bi), thisValue.scale);
-        }
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this + augend}.
-     * The result is rounded according to the passed context {@code mc}.
-     *
-     * @param augend
-     *            value to be added to {@code this}.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this + augend}.
-     * @throws NullPointerException
-     *             if {@code augend == null} or {@code mc == null}.
-     */
-    public BigDecimal add(BigDecimal augend, MathContext mc) {
-        BigDecimal larger; // operand with the largest unscaled value
-        BigDecimal smaller; // operand with the smallest unscaled value
-        BigInteger tempBI;
-        long diffScale = (long)this.scale - augend.scale;
-        int largerSignum;
-        // Some operand is zero or the precision is infinity
-        if ((augend.isZero()) || (this.isZero())
-                || (mc.getPrecision() == 0)) {
-            return add(augend).round(mc);
-        }
-        // Cases where there is room for optimizations
-        if (this.approxPrecision() < diffScale - 1) {
-            larger = augend;
-            smaller = this;
-        } else if (augend.approxPrecision() < -diffScale - 1) {
-            larger = this;
-            smaller = augend;
-        } else {// No optimization is done
-            return add(augend).round(mc);
-        }
-        if (mc.getPrecision() >= larger.approxPrecision()) {
-            // No optimization is done
-            return add(augend).round(mc);
-        }
-        // Cases where it's unnecessary to add two numbers with very different scales
-        largerSignum = larger.signum();
-        if (largerSignum == smaller.signum()) {
-            tempBI = Multiplication.multiplyByPositiveInt(larger.getUnscaledValue(),10)
-            .add(BigInteger.valueOf(largerSignum));
-        } else {
-            tempBI = larger.getUnscaledValue().subtract(
-                    BigInteger.valueOf(largerSignum));
-            tempBI = Multiplication.multiplyByPositiveInt(tempBI,10)
-            .add(BigInteger.valueOf(largerSignum * 9));
-        }
-        // Rounding the improved adding
-        larger = new BigDecimal(tempBI, larger.scale + 1);
-        return larger.round(mc);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
-     * The scale of the result is the maximum of the scales of the two arguments.
-     *
-     * @param subtrahend
-     *            value to be subtracted from {@code this}.
-     * @return {@code this - subtrahend}.
-     * @throws NullPointerException
-     *             if {@code subtrahend == null}.
-     */
-    public BigDecimal subtract(BigDecimal subtrahend) {
-        int diffScale = this.scale - subtrahend.scale;
-        // Fast return when some operand is zero
-        if (this.isZero()) {
-            if (diffScale <= 0) {
-                return subtrahend.negate();
-            }
-            if (subtrahend.isZero()) {
-                return this;
-            }
-        } else if (subtrahend.isZero()) {
-            if (diffScale >= 0) {
-                return this;
-            }
-        }
-        // Let be: this = [u1,s1] and subtrahend = [u2,s2] so:
-        if (diffScale == 0) {
-            // case s1 = s2 : [u1 - u2 , s1]
-            if (Math.max(this.bitLength, subtrahend.bitLength) + 1 < 64) {
-                return valueOf(this.smallValue - subtrahend.smallValue,this.scale);
-            }
-            return new BigDecimal(this.getUnscaledValue().subtract(subtrahend.getUnscaledValue()), this.scale);
-        } else if (diffScale > 0) {
-            // case s1 > s2 : [ u1 - u2 * 10 ^ (s1 - s2) , s1 ]
-            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                    Math.max(this.bitLength,subtrahend.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale])+1<64) {
-                return valueOf(this.smallValue-subtrahend.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale],this.scale);
-            }
-            return new BigDecimal(this.getUnscaledValue().subtract(
-                    Multiplication.multiplyByTenPow(subtrahend.getUnscaledValue(),diffScale)), this.scale);
-        } else {// case s2 > s1 : [ u1 * 10 ^ (s2 - s1) - u2 , s2 ]
-            diffScale = -diffScale;
-            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                    Math.max(this.bitLength+LONG_POWERS_OF_TEN_BIT_LENGTH[diffScale],subtrahend.bitLength)+1<64) {
-                return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[diffScale]-subtrahend.smallValue,subtrahend.scale);
-            }
-            return new BigDecimal(Multiplication.multiplyByTenPow(this.getUnscaledValue(),diffScale)
-            .subtract(subtrahend.getUnscaledValue()), subtrahend.scale);
-        }
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this - subtrahend}.
-     * The result is rounded according to the passed context {@code mc}.
-     *
-     * @param subtrahend
-     *            value to be subtracted from {@code this}.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this - subtrahend}.
-     * @throws NullPointerException
-     *             if {@code subtrahend == null} or {@code mc == null}.
-     */
-    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
-        long diffScale = subtrahend.scale - (long)this.scale;
-        int thisSignum;
-        BigDecimal leftOperand; // it will be only the left operand (this)
-        BigInteger tempBI;
-        // Some operand is zero or the precision is infinity
-        if ((subtrahend.isZero()) || (this.isZero())
-                || (mc.getPrecision() == 0)) {
-            return subtract(subtrahend).round(mc);
-        }
-        // Now:   this != 0   and   subtrahend != 0
-        if (subtrahend.approxPrecision() < diffScale - 1) {
-            // Cases where it is unnecessary to subtract two numbers with very different scales
-            if (mc.getPrecision() < this.approxPrecision()) {
-                thisSignum = this.signum();
-                if (thisSignum != subtrahend.signum()) {
-                    tempBI = Multiplication.multiplyByPositiveInt(this.getUnscaledValue(), 10)
-                    .add(BigInteger.valueOf(thisSignum));
-                } else {
-                    tempBI = this.getUnscaledValue().subtract(BigInteger.valueOf(thisSignum));
-                    tempBI = Multiplication.multiplyByPositiveInt(tempBI, 10)
-                    .add(BigInteger.valueOf(thisSignum * 9));
-                }
-                // Rounding the improved subtracting
-                leftOperand = new BigDecimal(tempBI, this.scale + 1);
-                return leftOperand.round(mc);
-            }
-        }
-        // No optimization is done
-        return subtract(subtrahend).round(mc);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this *
-     * multiplicand}. The scale of the result is the sum of the scales of the
-     * two arguments.
-     *
-     * @param multiplicand
-     *            value to be multiplied with {@code this}.
-     * @return {@code this * multiplicand}.
-     * @throws NullPointerException
-     *             if {@code multiplicand == null}.
-     */
-    public BigDecimal multiply(BigDecimal multiplicand) {
-        long newScale = (long)this.scale + multiplicand.scale;
-
-        if ((this.isZero()) || (multiplicand.isZero())) {
-            return zeroScaledBy(newScale);
-        }
-        /* Let be: this = [u1,s1] and multiplicand = [u2,s2] so:
-         * this x multiplicand = [ s1 * s2 , s1 + s2 ] */
-        if (this.bitLength + multiplicand.bitLength < 64) {
-            long unscaledValue = this.smallValue * multiplicand.smallValue;
-            // b/19185440 Case where result should be +2^63 but unscaledValue overflowed to -2^63
-            boolean longMultiplicationOverflowed = (unscaledValue == Long.MIN_VALUE) &&
-                    (Math.signum(smallValue) * Math.signum(multiplicand.smallValue) > 0);
-            if (!longMultiplicationOverflowed) {
-                return valueOf(unscaledValue, safeLongToInt(newScale));
-            }
-        }
-        return new BigDecimal(this.getUnscaledValue().multiply(
-                multiplicand.getUnscaledValue()), safeLongToInt(newScale));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this *
-     * multiplicand}. The result is rounded according to the passed context
-     * {@code mc}.
-     *
-     * @param multiplicand
-     *            value to be multiplied with {@code this}.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this * multiplicand}.
-     * @throws NullPointerException
-     *             if {@code multiplicand == null} or {@code mc == null}.
-     */
-    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
-        BigDecimal result = multiply(multiplicand);
-
-        result.inplaceRound(mc);
-        return result;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * As scale of the result the parameter {@code scale} is used. If rounding
-     * is required to meet the specified scale, then the specified rounding mode
-     * {@code roundingMode} is applied.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param scale
-     *            the scale of the result returned.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return {@code this / divisor} rounded according to the given rounding
-     *         mode.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws IllegalArgumentException
-     *             if {@code roundingMode} is not a valid rounding mode.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
-     *             necessary according to the given scale.
-     */
-    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
-        return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * As scale of the result the parameter {@code scale} is used. If rounding
-     * is required to meet the specified scale, then the specified rounding mode
-     * {@code roundingMode} is applied.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param scale
-     *            the scale of the result returned.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return {@code this / divisor} rounded according to the given rounding
-     *         mode.
-     * @throws NullPointerException
-     *             if {@code divisor == null} or {@code roundingMode == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == RoundingMode.UNNECESSAR}Y and
-     *             rounding is necessary according to the given scale and given
-     *             precision.
-     */
-    public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
-        // Let be: this = [u1,s1]  and  divisor = [u2,s2]
-        if (roundingMode == null) {
-            throw new NullPointerException("roundingMode == null");
-        }
-        if (divisor.isZero()) {
-            throw new ArithmeticException("Division by zero");
-        }
-
-        long diffScale = ((long)this.scale - divisor.scale) - scale;
-
-        // Check whether the diffScale will fit into an int. See http://b/17393664.
-        if (bitLength(diffScale) > 32) {
-            throw new ArithmeticException(
-                    "Unable to perform divisor / dividend scaling: the difference in scale is too" +
-                            " big (" + diffScale + ")");
-        }
-
-        if(this.bitLength < 64 && divisor.bitLength < 64 ) {
-            if(diffScale == 0) {
-                // http://b/26105053 - corner case: Long.MIN_VALUE / (-1) overflows a long
-                if (this.smallValue != Long.MIN_VALUE || divisor.smallValue != -1) {
-                    return dividePrimitiveLongs(this.smallValue,
-                            divisor.smallValue,
-                            scale,
-                            roundingMode);
-                }
-            } else if(diffScale > 0) {
-                if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                        divisor.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale] < 64) {
-                    return dividePrimitiveLongs(this.smallValue,
-                            divisor.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale],
-                            scale,
-                            roundingMode);
-                }
-            } else { // diffScale < 0
-                if(-diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                        this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-diffScale] < 64) {
-                    return dividePrimitiveLongs(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale],
-                            divisor.smallValue,
-                            scale,
-                            roundingMode);
-                }
-
-            }
-        }
-        BigInteger scaledDividend = this.getUnscaledValue();
-        BigInteger scaledDivisor = divisor.getUnscaledValue(); // for scaling of 'u2'
-
-        if (diffScale > 0) {
-            // Multiply 'u2'  by:  10^((s1 - s2) - scale)
-            scaledDivisor = Multiplication.multiplyByTenPow(scaledDivisor, (int)diffScale);
-        } else if (diffScale < 0) {
-            // Multiply 'u1'  by:  10^(scale - (s1 - s2))
-            scaledDividend  = Multiplication.multiplyByTenPow(scaledDividend, (int)-diffScale);
-        }
-        return divideBigIntegers(scaledDividend, scaledDivisor, scale, roundingMode);
-        }
-
-    private static BigDecimal divideBigIntegers(BigInteger scaledDividend, BigInteger scaledDivisor, int scale, RoundingMode roundingMode) {
-
-        BigInteger[] quotAndRem = scaledDividend.divideAndRemainder(scaledDivisor);  // quotient and remainder
-        // If after division there is a remainder...
-        BigInteger quotient = quotAndRem[0];
-        BigInteger remainder = quotAndRem[1];
-        if (remainder.signum() == 0) {
-            return new BigDecimal(quotient, scale);
-        }
-        int sign = scaledDividend.signum() * scaledDivisor.signum();
-        int compRem;                                      // 'compare to remainder'
-        if(scaledDivisor.bitLength() < 63) { // 63 in order to avoid out of long after *2
-            long rem = remainder.longValue();
-            long divisor = scaledDivisor.longValue();
-            compRem = compareForRounding(rem, divisor);
-            // To look if there is a carry
-            compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
-                    sign * (5 + compRem), roundingMode);
-
-        } else {
-            // Checking if:  remainder * 2 >= scaledDivisor
-            compRem = remainder.abs().shiftLeftOneBit().compareTo(scaledDivisor.abs());
-            compRem = roundingBehavior(quotient.testBit(0) ? 1 : 0,
-                    sign * (5 + compRem), roundingMode);
-        }
-            if (compRem != 0) {
-            if(quotient.bitLength() < 63) {
-                return valueOf(quotient.longValue() + compRem,scale);
-            }
-            quotient = quotient.add(BigInteger.valueOf(compRem));
-            return new BigDecimal(quotient, scale);
-        }
-        // Constructing the result with the appropriate unscaled value
-        return new BigDecimal(quotient, scale);
-    }
-
-    private static BigDecimal dividePrimitiveLongs(long scaledDividend, long scaledDivisor, int scale, RoundingMode roundingMode) {
-        long quotient = scaledDividend / scaledDivisor;
-        long remainder = scaledDividend % scaledDivisor;
-        int sign = Long.signum( scaledDividend ) * Long.signum( scaledDivisor );
-        if (remainder != 0) {
-            // Checking if:  remainder * 2 >= scaledDivisor
-            int compRem = compareForRounding(remainder, scaledDivisor); // 'compare to remainder'
-            // To look if there is a carry
-            quotient += roundingBehavior(((int)quotient) & 1,
-                    sign * (5 + compRem),
-                    roundingMode);
-        }
-        // Constructing the result with the appropriate unscaled value
-        return valueOf(quotient, scale);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * The scale of the result is the scale of {@code this}. If rounding is
-     * required to meet the specified scale, then the specified rounding mode
-     * {@code roundingMode} is applied.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return {@code this / divisor} rounded according to the given rounding
-     *         mode.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws IllegalArgumentException
-     *             if {@code roundingMode} is not a valid rounding mode.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
-     *             necessary according to the scale of this.
-     */
-    public BigDecimal divide(BigDecimal divisor, int roundingMode) {
-        return divide(divisor, scale, RoundingMode.valueOf(roundingMode));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * The scale of the result is the scale of {@code this}. If rounding is
-     * required to meet the specified scale, then the specified rounding mode
-     * {@code roundingMode} is applied.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return {@code this / divisor} rounded according to the given rounding
-     *         mode.
-     * @throws NullPointerException
-     *             if {@code divisor == null} or {@code roundingMode == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == RoundingMode.UNNECESSARY} and
-     *             rounding is necessary according to the scale of this.
-     */
-    public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
-        return divide(divisor, scale, roundingMode);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * The scale of the result is the difference of the scales of {@code this}
-     * and {@code divisor}. If the exact result requires more digits, then the
-     * scale is adjusted accordingly. For example, {@code 1/128 = 0.0078125}
-     * which has a scale of {@code 7} and precision {@code 5}.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @return {@code this / divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if the result cannot be represented exactly.
-     */
-    public BigDecimal divide(BigDecimal divisor) {
-        BigInteger p = this.getUnscaledValue();
-        BigInteger q = divisor.getUnscaledValue();
-        BigInteger gcd; // greatest common divisor between 'p' and 'q'
-        BigInteger quotAndRem[];
-        long diffScale = (long)scale - divisor.scale;
-        int newScale; // the new scale for final quotient
-        int k; // number of factors "2" in 'q'
-        int l = 0; // number of factors "5" in 'q'
-        int i = 1;
-        int lastPow = FIVE_POW.length - 1;
-
-        if (divisor.isZero()) {
-            throw new ArithmeticException("Division by zero");
-        }
-        if (p.signum() == 0) {
-            return zeroScaledBy(diffScale);
-        }
-        // To divide both by the GCD
-        gcd = p.gcd(q);
-        p = p.divide(gcd);
-        q = q.divide(gcd);
-        // To simplify all "2" factors of q, dividing by 2^k
-        k = q.getLowestSetBit();
-        q = q.shiftRight(k);
-        // To simplify all "5" factors of q, dividing by 5^l
-        do {
-            quotAndRem = q.divideAndRemainder(FIVE_POW[i]);
-            if (quotAndRem[1].signum() == 0) {
-                l += i;
-                if (i < lastPow) {
-                    i++;
-                }
-                q = quotAndRem[0];
-            } else {
-                if (i == 1) {
-                    break;
-                }
-                i = 1;
-            }
-        } while (true);
-        // If  abs(q) != 1  then the quotient is periodic
-        if (!q.abs().equals(BigInteger.ONE)) {
-            throw new ArithmeticException("Non-terminating decimal expansion; no exact representable decimal result");
-        }
-        // The sign of the is fixed and the quotient will be saved in 'p'
-        if (q.signum() < 0) {
-            p = p.negate();
-        }
-        // Checking if the new scale is out of range
-        newScale = safeLongToInt(diffScale + Math.max(k, l));
-        // k >= 0  and  l >= 0  implies that  k - l  is in the 32-bit range
-        i = k - l;
-
-        p = (i > 0) ? Multiplication.multiplyByFivePow(p, i)
-        : p.shiftLeft(-i);
-        return new BigDecimal(p, newScale);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this / divisor}.
-     * The result is rounded according to the passed context {@code mc}. If the
-     * passed math context specifies precision {@code 0}, then this call is
-     * equivalent to {@code this.divide(divisor)}.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this / divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null} or {@code mc == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code mc.getRoundingMode() == UNNECESSARY} and rounding
-     *             is necessary according {@code mc.getPrecision()}.
-     */
-    public BigDecimal divide(BigDecimal divisor, MathContext mc) {
-        /* Calculating how many zeros must be append to 'dividend'
-         * to obtain a  quotient with at least 'mc.precision()' digits */
-        long trailingZeros = mc.getPrecision() + 2L
-                + divisor.approxPrecision() - approxPrecision();
-        long diffScale = (long)scale - divisor.scale;
-        long newScale = diffScale; // scale of the final quotient
-        int compRem; // to compare the remainder
-        int i = 1; // index
-        int lastPow = TEN_POW.length - 1; // last power of ten
-        BigInteger integerQuot; // for temporal results
-        BigInteger quotAndRem[] = {getUnscaledValue()};
-        // In special cases it reduces the problem to call the dual method
-        if ((mc.getPrecision() == 0) || (this.isZero())
-        || (divisor.isZero())) {
-            return this.divide(divisor);
-        }
-        if (trailingZeros > 0) {
-            // To append trailing zeros at end of dividend
-            quotAndRem[0] = getUnscaledValue().multiply( Multiplication.powerOf10(trailingZeros) );
-            newScale += trailingZeros;
-        }
-        quotAndRem = quotAndRem[0].divideAndRemainder( divisor.getUnscaledValue() );
-        integerQuot = quotAndRem[0];
-        // Calculating the exact quotient with at least 'mc.precision()' digits
-        if (quotAndRem[1].signum() != 0) {
-            // Checking if:   2 * remainder >= divisor ?
-            compRem = quotAndRem[1].shiftLeftOneBit().compareTo( divisor.getUnscaledValue() );
-            // quot := quot * 10 + r;     with 'r' in {-6,-5,-4, 0,+4,+5,+6}
-            integerQuot = integerQuot.multiply(BigInteger.TEN)
-            .add(BigInteger.valueOf(quotAndRem[0].signum() * (5 + compRem)));
-            newScale++;
-        } else {
-            // To strip trailing zeros until the preferred scale is reached
-            while (!integerQuot.testBit(0)) {
-                quotAndRem = integerQuot.divideAndRemainder(TEN_POW[i]);
-                if ((quotAndRem[1].signum() == 0)
-                        && (newScale - i >= diffScale)) {
-                    newScale -= i;
-                    if (i < lastPow) {
-                        i++;
-                    }
-                    integerQuot = quotAndRem[0];
-                } else {
-                    if (i == 1) {
-                        break;
-                    }
-                    i = 1;
-                }
-            }
-        }
-        // To perform rounding
-        return new BigDecimal(integerQuot, safeLongToInt(newScale), mc);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is the integral part of
-     * {@code this / divisor}. The quotient is rounded down towards zero to the
-     * next integer. For example, {@code 0.5/0.2 = 2}.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @return integral part of {@code this / divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     */
-    public BigDecimal divideToIntegralValue(BigDecimal divisor) {
-        BigInteger integralValue; // the integer of result
-        BigInteger powerOfTen; // some power of ten
-
-        long newScale = (long)this.scale - divisor.scale;
-        long tempScale = 0;
-        int i = 1;
-        int lastPow = TEN_POW.length - 1;
-
-        if (divisor.isZero()) {
-            throw new ArithmeticException("Division by zero");
-        }
-        if ((divisor.approxPrecision() + newScale > this.approxPrecision() + 1L)
-        || (this.isZero())) {
-            /* If the divisor's integer part is greater than this's integer part,
-             * the result must be zero with the appropriate scale */
-            integralValue = BigInteger.ZERO;
-        } else if (newScale == 0) {
-            integralValue = getUnscaledValue().divide( divisor.getUnscaledValue() );
-        } else if (newScale > 0) {
-            powerOfTen = Multiplication.powerOf10(newScale);
-            integralValue = getUnscaledValue().divide( divisor.getUnscaledValue().multiply(powerOfTen) );
-            integralValue = integralValue.multiply(powerOfTen);
-        } else {// (newScale < 0)
-            powerOfTen = Multiplication.powerOf10(-newScale);
-            integralValue = getUnscaledValue().multiply(powerOfTen).divide( divisor.getUnscaledValue() );
-            // To strip trailing zeros approximating to the preferred scale
-            while (!integralValue.testBit(0)) {
-                BigInteger[] quotAndRem = integralValue.divideAndRemainder(TEN_POW[i]);
-                if ((quotAndRem[1].signum() == 0)
-                        && (tempScale - i >= newScale)) {
-                    tempScale -= i;
-                    if (i < lastPow) {
-                        i++;
-                    }
-                    integralValue = quotAndRem[0];
-                } else {
-                    if (i == 1) {
-                        break;
-                    }
-                    i = 1;
-                }
-            }
-            newScale = tempScale;
-        }
-        return ((integralValue.signum() == 0)
-        ? zeroScaledBy(newScale)
-                : new BigDecimal(integralValue, safeLongToInt(newScale)));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is the integral part of
-     * {@code this / divisor}. The quotient is rounded down towards zero to the
-     * next integer. The rounding mode passed with the parameter {@code mc} is
-     * not considered. But if the precision of {@code mc > 0} and the integral
-     * part requires more digits, then an {@code ArithmeticException} is thrown.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param mc
-     *            math context which determines the maximal precision of the
-     *            result.
-     * @return integral part of {@code this / divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null} or {@code mc == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code mc.getPrecision() > 0} and the result requires more
-     *             digits to be represented.
-     */
-    public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
-        int mcPrecision = mc.getPrecision();
-        int diffPrecision = this.precision() - divisor.precision();
-        int lastPow = TEN_POW.length - 1;
-        long diffScale = (long)this.scale - divisor.scale;
-        long newScale = diffScale;
-        long quotPrecision = diffPrecision - diffScale + 1;
-        BigInteger quotAndRem[] = new BigInteger[2];
-        // In special cases it call the dual method
-        if ((mcPrecision == 0) || (this.isZero()) || (divisor.isZero())) {
-            return this.divideToIntegralValue(divisor);
-        }
-        // Let be:   this = [u1,s1]   and   divisor = [u2,s2]
-        if (quotPrecision <= 0) {
-            quotAndRem[0] = BigInteger.ZERO;
-        } else if (diffScale == 0) {
-            // CASE s1 == s2:  to calculate   u1 / u2
-            quotAndRem[0] = this.getUnscaledValue().divide( divisor.getUnscaledValue() );
-        } else if (diffScale > 0) {
-            // CASE s1 >= s2:  to calculate   u1 / (u2 * 10^(s1-s2)
-            quotAndRem[0] = this.getUnscaledValue().divide(
-                    divisor.getUnscaledValue().multiply(Multiplication.powerOf10(diffScale)) );
-            // To chose  10^newScale  to get a quotient with at least 'mc.precision()' digits
-            newScale = Math.min(diffScale, Math.max(mcPrecision - quotPrecision + 1, 0));
-            // To calculate: (u1 / (u2 * 10^(s1-s2)) * 10^newScale
-            quotAndRem[0] = quotAndRem[0].multiply(Multiplication.powerOf10(newScale));
-        } else {// CASE s2 > s1:
-            /* To calculate the minimum power of ten, such that the quotient
-             *   (u1 * 10^exp) / u2   has at least 'mc.precision()' digits. */
-            long exp = Math.min(-diffScale, Math.max((long)mcPrecision - diffPrecision, 0));
-            long compRemDiv;
-            // Let be:   (u1 * 10^exp) / u2 = [q,r]
-            quotAndRem = this.getUnscaledValue().multiply(Multiplication.powerOf10(exp)).
-                    divideAndRemainder(divisor.getUnscaledValue());
-            newScale += exp; // To fix the scale
-            exp = -newScale; // The remaining power of ten
-            // If after division there is a remainder...
-            if ((quotAndRem[1].signum() != 0) && (exp > 0)) {
-                // Log10(r) + ((s2 - s1) - exp) > mc.precision ?
-                compRemDiv = (new BigDecimal(quotAndRem[1])).precision()
-                + exp - divisor.precision();
-                if (compRemDiv == 0) {
-                    // To calculate:  (r * 10^exp2) / u2
-                    quotAndRem[1] = quotAndRem[1].multiply(Multiplication.powerOf10(exp)).
-                            divide(divisor.getUnscaledValue());
-                    compRemDiv = Math.abs(quotAndRem[1].signum());
-                }
-                if (compRemDiv > 0) {
-                    throw new ArithmeticException("Division impossible");
-                }
-            }
-        }
-        // Fast return if the quotient is zero
-        if (quotAndRem[0].signum() == 0) {
-            return zeroScaledBy(diffScale);
-        }
-        BigInteger strippedBI = quotAndRem[0];
-        BigDecimal integralValue = new BigDecimal(quotAndRem[0]);
-        long resultPrecision = integralValue.precision();
-        int i = 1;
-        // To strip trailing zeros until the specified precision is reached
-        while (!strippedBI.testBit(0)) {
-            quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
-            if ((quotAndRem[1].signum() == 0) &&
-                    ((resultPrecision - i >= mcPrecision)
-                    || (newScale - i >= diffScale)) ) {
-                resultPrecision -= i;
-                newScale -= i;
-                if (i < lastPow) {
-                    i++;
-                }
-                strippedBI = quotAndRem[0];
-            } else {
-                if (i == 1) {
-                    break;
-                }
-                i = 1;
-            }
-        }
-        // To check if the result fit in 'mc.precision()' digits
-        if (resultPrecision > mcPrecision) {
-            throw new ArithmeticException("Division impossible");
-        }
-        integralValue.scale = safeLongToInt(newScale);
-        integralValue.setUnscaledValue(strippedBI);
-        return integralValue;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
-     * <p>
-     * The remainder is defined as {@code this -
-     * this.divideToIntegralValue(divisor) * divisor}.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @return {@code this % divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     */
-    public BigDecimal remainder(BigDecimal divisor) {
-        return divideAndRemainder(divisor)[1];
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this % divisor}.
-     * <p>
-     * The remainder is defined as {@code this -
-     * this.divideToIntegralValue(divisor) * divisor}.
-     * <p>
-     * The specified rounding mode {@code mc} is used for the division only.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param mc
-     *            rounding mode and precision to be used.
-     * @return {@code this % divisor}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @throws ArithmeticException
-     *             if {@code mc.getPrecision() > 0} and the result of {@code
-     *             this.divideToIntegralValue(divisor, mc)} requires more digits
-     *             to be represented.
-     */
-    public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
-        return divideAndRemainder(divisor, mc)[1];
-    }
-
-    /**
-     * Returns a {@code BigDecimal} array which contains the integral part of
-     * {@code this / divisor} at index 0 and the remainder {@code this %
-     * divisor} at index 1. The quotient is rounded down towards zero to the
-     * next integer.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @return {@code [this.divideToIntegralValue(divisor),
-     *         this.remainder(divisor)]}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @see #divideToIntegralValue
-     * @see #remainder
-     */
-    public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
-        BigDecimal quotAndRem[] = new BigDecimal[2];
-
-        quotAndRem[0] = this.divideToIntegralValue(divisor);
-        quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
-        return quotAndRem;
-    }
-
-    /**
-     * Returns a {@code BigDecimal} array which contains the integral part of
-     * {@code this / divisor} at index 0 and the remainder {@code this %
-     * divisor} at index 1. The quotient is rounded down towards zero to the
-     * next integer. The rounding mode passed with the parameter {@code mc} is
-     * not considered. But if the precision of {@code mc > 0} and the integral
-     * part requires more digits, then an {@code ArithmeticException} is thrown.
-     *
-     * @param divisor
-     *            value by which {@code this} is divided.
-     * @param mc
-     *            math context which determines the maximal precision of the
-     *            result.
-     * @return {@code [this.divideToIntegralValue(divisor),
-     *         this.remainder(divisor)]}.
-     * @throws NullPointerException
-     *             if {@code divisor == null}.
-     * @throws ArithmeticException
-     *             if {@code divisor == 0}.
-     * @see #divideToIntegralValue
-     * @see #remainder
-     */
-    public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
-        BigDecimal quotAndRem[] = new BigDecimal[2];
-
-        quotAndRem[0] = this.divideToIntegralValue(divisor, mc);
-        quotAndRem[1] = this.subtract( quotAndRem[0].multiply(divisor) );
-        return quotAndRem;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this<sup>n</sup>}. The
-     * scale of the result is {@code n * this.scale()}.
-     *
-     * <p>{@code x.pow(0)} returns {@code 1}, even if {@code x == 0}.
-     *
-     * <p>Implementation Note: The implementation is based on the ANSI standard
-     * X3.274-1996 algorithm.
-     *
-     * @throws ArithmeticException
-     *             if {@code n < 0} or {@code n > 999999999}.
-     */
-    public BigDecimal pow(int n) {
-        if (n == 0) {
-            return ONE;
-        }
-        if ((n < 0) || (n > 999999999)) {
-            throw new ArithmeticException("Invalid operation");
-        }
-        long newScale = scale * (long)n;
-        // Let be: this = [u,s]   so:  this^n = [u^n, s*n]
-        return isZero() ? zeroScaledBy(newScale)
-                : new BigDecimal(getUnscaledValue().pow(n), safeLongToInt(newScale));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this<sup>n</sup>}. The
-     * result is rounded according to the passed context {@code mc}.
-     *
-     * <p>Implementation Note: The implementation is based on the ANSI standard
-     * X3.274-1996 algorithm.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @throws ArithmeticException
-     *             if {@code n < 0} or {@code n > 999999999}.
-     */
-    public BigDecimal pow(int n, MathContext mc) {
-        // The ANSI standard X3.274-1996 algorithm
-        int m = Math.abs(n);
-        int mcPrecision = mc.getPrecision();
-        int elength = (int)Math.log10(m) + 1;   // decimal digits in 'n'
-        int oneBitMask; // mask of bits
-        BigDecimal accum; // the single accumulator
-        MathContext newPrecision = mc; // MathContext by default
-
-        // In particular cases, it reduces the problem to call the other 'pow()'
-        if ((n == 0) || ((isZero()) && (n > 0))) {
-            return pow(n);
-        }
-        if ((m > 999999999) || ((mcPrecision == 0) && (n < 0))
-                || ((mcPrecision > 0) && (elength > mcPrecision))) {
-            throw new ArithmeticException("Invalid operation");
-        }
-        if (mcPrecision > 0) {
-            newPrecision = new MathContext( mcPrecision + elength + 1,
-                    mc.getRoundingMode());
-        }
-        // The result is calculated as if 'n' were positive
-        accum = round(newPrecision);
-        oneBitMask = Integer.highestOneBit(m) >> 1;
-
-        while (oneBitMask > 0) {
-            accum = accum.multiply(accum, newPrecision);
-            if ((m & oneBitMask) == oneBitMask) {
-                accum = accum.multiply(this, newPrecision);
-            }
-            oneBitMask >>= 1;
-        }
-        // If 'n' is negative, the value is divided into 'ONE'
-        if (n < 0) {
-            accum = ONE.divide(accum, newPrecision);
-        }
-        // The final value is rounded to the destination precision
-        accum.inplaceRound(mc);
-        return accum;
-    }
-
-    /**
-     * Returns a {@code BigDecimal} whose value is the absolute value of
-     * {@code this}. The scale of the result is the same as the scale of this.
-     */
-    public BigDecimal abs() {
-        return ((signum() < 0) ? negate() : this);
-    }
-
-    /**
-     * Returns a {@code BigDecimal} whose value is the absolute value of
-     * {@code this}. The result is rounded according to the passed context
-     * {@code mc}.
-     */
-    public BigDecimal abs(MathContext mc) {
-        BigDecimal result = (signum() < 0) ? negate() : new BigDecimal(getUnscaledValue(), scale);
-        result.inplaceRound(mc);
-        return result;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is the {@code -this}. The
-     * scale of the result is the same as the scale of this.
-     *
-     * @return {@code -this}
-     */
-    public BigDecimal negate() {
-        if(bitLength < 63 || (bitLength == 63 && smallValue!=Long.MIN_VALUE)) {
-            return valueOf(-smallValue,scale);
-        }
-        return new BigDecimal(getUnscaledValue().negate(), scale);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is the {@code -this}. The
-     * result is rounded according to the passed context {@code mc}.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code -this}
-     */
-    public BigDecimal negate(MathContext mc) {
-        BigDecimal result = negate();
-        result.inplaceRound(mc);
-        return result;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code +this}. The scale
-     * of the result is the same as the scale of this.
-     *
-     * @return {@code this}
-     */
-    public BigDecimal plus() {
-        return this;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code +this}. The result
-     * is rounded according to the passed context {@code mc}.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this}, rounded
-     */
-    public BigDecimal plus(MathContext mc) {
-        return round(mc);
-    }
-
-    /**
-     * Returns the sign of this {@code BigDecimal}.
-     *
-     * @return {@code -1} if {@code this < 0},
-     *         {@code 0} if {@code this == 0},
-     *         {@code 1} if {@code this > 0}.
-     */
-    public int signum() {
-        if( bitLength < 64) {
-            return Long.signum( this.smallValue );
-        }
-        return getUnscaledValue().signum();
-    }
-
-    private boolean isZero() {
-        //Watch out: -1 has a bitLength=0
-        return bitLength == 0 && this.smallValue != -1;
-    }
-
-    /**
-     * Returns the scale of this {@code BigDecimal}. The scale is the number of
-     * digits behind the decimal point. The value of this {@code BigDecimal} is
-     * the {@code unsignedValue * 10<sup>-scale</sup>}. If the scale is negative,
-     * then this {@code BigDecimal} represents a big integer.
-     *
-     * @return the scale of this {@code BigDecimal}.
-     */
-    public int scale() {
-        return scale;
-    }
-
-    /**
-     * Returns the precision of this {@code BigDecimal}. The precision is the
-     * number of decimal digits used to represent this decimal. It is equivalent
-     * to the number of digits of the unscaled value. The precision of {@code 0}
-     * is {@code 1} (independent of the scale).
-     *
-     * @return the precision of this {@code BigDecimal}.
-     */
-    public int precision() {
-        // Return the cached value if we have one.
-        if (precision != 0) {
-            return precision;
-        }
-
-        if (bitLength == 0) {
-            precision = 1;
-        } else if (bitLength < 64) {
-            precision = decimalDigitsInLong(smallValue);
-        } else {
-            int decimalDigits = 1 + (int) ((bitLength - 1) * LOG10_2);
-            // If after division the number isn't zero, there exists an additional digit
-            if (getUnscaledValue().divide(Multiplication.powerOf10(decimalDigits)).signum() != 0) {
-                decimalDigits++;
-            }
-            precision = decimalDigits;
-        }
-        return precision;
-    }
-
-    private int decimalDigitsInLong(long value) {
-        if (value == Long.MIN_VALUE) {
-            return 19; // special case required because abs(MIN_VALUE) == MIN_VALUE
-        } else {
-            int index = Arrays.binarySearch(MathUtils.LONG_POWERS_OF_TEN, Math.abs(value));
-            return (index < 0) ? (-index - 1) : (index + 1);
-        }
-    }
-
-    /**
-     * Returns the unscaled value (mantissa) of this {@code BigDecimal} instance
-     * as a {@code BigInteger}. The unscaled value can be computed as
-     * {@code this * 10<sup>scale</sup>}.
-     */
-    public BigInteger unscaledValue() {
-        return getUnscaledValue();
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this}, rounded
-     * according to the passed context {@code mc}.
-     * <p>
-     * If {@code mc.precision = 0}, then no rounding is performed.
-     * <p>
-     * If {@code mc.precision > 0} and {@code mc.roundingMode == UNNECESSARY},
-     * then an {@code ArithmeticException} is thrown if the result cannot be
-     * represented exactly within the given precision.
-     *
-     * @param mc
-     *            rounding mode and precision for the result of this operation.
-     * @return {@code this} rounded according to the passed context.
-     * @throws ArithmeticException
-     *             if {@code mc.precision > 0} and {@code mc.roundingMode ==
-     *             UNNECESSARY} and this cannot be represented within the given
-     *             precision.
-     */
-    public BigDecimal round(MathContext mc) {
-        BigDecimal thisBD = new BigDecimal(getUnscaledValue(), scale);
-
-        thisBD.inplaceRound(mc);
-        return thisBD;
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance with the specified scale.
-     * <p>
-     * If the new scale is greater than the old scale, then additional zeros are
-     * added to the unscaled value. In this case no rounding is necessary.
-     * <p>
-     * If the new scale is smaller than the old scale, then trailing digits are
-     * removed. If these trailing digits are not zero, then the remaining
-     * unscaled value has to be rounded. For this rounding operation the
-     * specified rounding mode is used.
-     *
-     * @param newScale
-     *            scale of the result returned.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return a new {@code BigDecimal} instance with the specified scale.
-     * @throws NullPointerException
-     *             if {@code roundingMode == null}.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
-     *             necessary according to the given scale.
-     */
-    public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
-        if (roundingMode == null) {
-            throw new NullPointerException("roundingMode == null");
-        }
-        long diffScale = newScale - (long)scale;
-        // Let be:  'this' = [u,s]
-        if(diffScale == 0) {
-            return this;
-        }
-        if(diffScale > 0) {
-        // return  [u * 10^(s2 - s), newScale]
-            if(diffScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                    (this.bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)diffScale]) < 64 ) {
-                return valueOf(this.smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)diffScale],newScale);
-            }
-            return new BigDecimal(Multiplication.multiplyByTenPow(getUnscaledValue(),(int)diffScale), newScale);
-        }
-        // diffScale < 0
-        // return  [u,s] / [1,newScale]  with the appropriate scale and rounding
-        if(this.bitLength < 64 && -diffScale < MathUtils.LONG_POWERS_OF_TEN.length) {
-            return dividePrimitiveLongs(this.smallValue, MathUtils.LONG_POWERS_OF_TEN[(int)-diffScale], newScale,roundingMode);
-        }
-        return divideBigIntegers(this.getUnscaledValue(),Multiplication.powerOf10(-diffScale),newScale,roundingMode);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance with the specified scale.
-     * <p>
-     * If the new scale is greater than the old scale, then additional zeros are
-     * added to the unscaled value. In this case no rounding is necessary.
-     * <p>
-     * If the new scale is smaller than the old scale, then trailing digits are
-     * removed. If these trailing digits are not zero, then the remaining
-     * unscaled value has to be rounded. For this rounding operation the
-     * specified rounding mode is used.
-     *
-     * @param newScale
-     *            scale of the result returned.
-     * @param roundingMode
-     *            rounding mode to be used to round the result.
-     * @return a new {@code BigDecimal} instance with the specified scale.
-     * @throws IllegalArgumentException
-     *             if {@code roundingMode} is not a valid rounding mode.
-     * @throws ArithmeticException
-     *             if {@code roundingMode == ROUND_UNNECESSARY} and rounding is
-     *             necessary according to the given scale.
-     */
-    public BigDecimal setScale(int newScale, int roundingMode) {
-        return setScale(newScale, RoundingMode.valueOf(roundingMode));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance with the specified scale. If
-     * the new scale is greater than the old scale, then additional zeros are
-     * added to the unscaled value. If the new scale is smaller than the old
-     * scale, then trailing zeros are removed. If the trailing digits are not
-     * zeros then an ArithmeticException is thrown.
-     * <p>
-     * If no exception is thrown, then the following equation holds: {@code
-     * x.setScale(s).compareTo(x) == 0}.
-     *
-     * @param newScale
-     *            scale of the result returned.
-     * @return a new {@code BigDecimal} instance with the specified scale.
-     * @throws ArithmeticException
-     *             if rounding would be necessary.
-     */
-    public BigDecimal setScale(int newScale) {
-        return setScale(newScale, RoundingMode.UNNECESSARY);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance where the decimal point has
-     * been moved {@code n} places to the left. If {@code n < 0} then the
-     * decimal point is moved {@code -n} places to the right.
-     *
-     * <p>The result is obtained by changing its scale. If the scale of the result
-     * becomes negative, then its precision is increased such that the scale is
-     * zero.
-     *
-     * <p>Note, that {@code movePointLeft(0)} returns a result which is
-     * mathematically equivalent, but which has {@code scale >= 0}.
-     */
-    public BigDecimal movePointLeft(int n) {
-        return movePoint(scale + (long)n);
-    }
-
-    private BigDecimal movePoint(long newScale) {
-        if (isZero()) {
-            return zeroScaledBy(Math.max(newScale, 0));
-        }
-        /*
-         * When: 'n'== Integer.MIN_VALUE isn't possible to call to
-         * movePointRight(-n) since -Integer.MIN_VALUE == Integer.MIN_VALUE
-         */
-        if(newScale >= 0) {
-            if(bitLength < 64) {
-                return valueOf(smallValue, safeLongToInt(newScale));
-            }
-            return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale));
-        }
-        if(-newScale < MathUtils.LONG_POWERS_OF_TEN.length &&
-                bitLength + LONG_POWERS_OF_TEN_BIT_LENGTH[(int)-newScale] < 64 ) {
-            return valueOf(smallValue*MathUtils.LONG_POWERS_OF_TEN[(int)-newScale],0);
-        }
-        return new BigDecimal(Multiplication.multiplyByTenPow(
-                getUnscaledValue(), safeLongToInt(-newScale)), 0);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance where the decimal point has
-     * been moved {@code n} places to the right. If {@code n < 0} then the
-     * decimal point is moved {@code -n} places to the left.
-     *
-     * <p>The result is obtained by changing its scale. If the scale of the result
-     * becomes negative, then its precision is increased such that the scale is
-     * zero.
-     *
-     * <p>Note, that {@code movePointRight(0)} returns a result which is
-     * mathematically equivalent, but which has scale >= 0.
-     */
-    public BigDecimal movePointRight(int n) {
-        return movePoint(scale - (long)n);
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} whose value is {@code this * 10<sup>n</sup>}.
-     * The scale of the result is {@code this.scale()} - {@code n}.
-     * The precision of the result is the precision of {@code this}.
-     *
-     * <p>This method has the same effect as {@link #movePointRight}, except that
-     * the precision is not changed.
-     */
-    public BigDecimal scaleByPowerOfTen(int n) {
-        long newScale = scale - (long)n;
-        if(bitLength < 64) {
-            //Taking care when a 0 is to be scaled
-            if( smallValue==0  ){
-                return zeroScaledBy( newScale );
-            }
-            return valueOf(smallValue, safeLongToInt(newScale));
-        }
-        return new BigDecimal(getUnscaledValue(), safeLongToInt(newScale));
-    }
-
-    /**
-     * Returns a new {@code BigDecimal} instance with the same value as {@code
-     * this} but with a unscaled value where the trailing zeros have been
-     * removed. If the unscaled value of {@code this} has n trailing zeros, then
-     * the scale and the precision of the result has been reduced by n.
-     *
-     * @return a new {@code BigDecimal} instance equivalent to this where the
-     *         trailing zeros of the unscaled value have been removed.
-     */
-    public BigDecimal stripTrailingZeros() {
-        int i = 1; // 1 <= i <= 18
-        int lastPow = TEN_POW.length - 1;
-        long newScale = scale;
-
-        if (isZero()) {
-            return new BigDecimal(BigInteger.ZERO, 0);
-        }
-        BigInteger strippedBI = getUnscaledValue();
-        BigInteger[] quotAndRem;
-
-        // while the number is even...
-        while (!strippedBI.testBit(0)) {
-            // To divide by 10^i
-            quotAndRem = strippedBI.divideAndRemainder(TEN_POW[i]);
-            // To look the remainder
-            if (quotAndRem[1].signum() == 0) {
-                // To adjust the scale
-                newScale -= i;
-                if (i < lastPow) {
-                    // To set to the next power
-                    i++;
-                }
-                strippedBI = quotAndRem[0];
-            } else {
-                if (i == 1) {
-                    // 'this' has no more trailing zeros
-                    break;
-                }
-                // To set to the smallest power of ten
-                i = 1;
-            }
-        }
-        return new BigDecimal(strippedBI, safeLongToInt(newScale));
-    }
-
-    /**
-     * Compares this {@code BigDecimal} with {@code val}. Returns one of the
-     * three values {@code 1}, {@code 0}, or {@code -1}. The method behaves as
-     * if {@code this.subtract(val)} is computed. If this difference is > 0 then
-     * 1 is returned, if the difference is < 0 then -1 is returned, and if the
-     * difference is 0 then 0 is returned. This means, that if two decimal
-     * instances are compared which are equal in value but differ in scale, then
-     * these two instances are considered as equal.
-     *
-     * @param val
-     *            value to be compared with {@code this}.
-     * @return {@code 1} if {@code this > val}, {@code -1} if {@code this < val},
-     *         {@code 0} if {@code this == val}.
-     * @throws NullPointerException
-     *             if {@code val == null}.
-     */
-    public int compareTo(BigDecimal val) {
-        int thisSign = signum();
-        int valueSign = val.signum();
-
-        if( thisSign == valueSign) {
-            if(this.scale == val.scale && this.bitLength<64 && val.bitLength<64 ) {
-                return (smallValue < val.smallValue) ? -1 : (smallValue > val.smallValue) ? 1 : 0;
-            }
-            long diffScale = (long)this.scale - val.scale;
-            int diffPrecision = this.approxPrecision() - val.approxPrecision();
-            if (diffPrecision > diffScale + 1) {
-                return thisSign;
-            } else if (diffPrecision < diffScale - 1) {
-                return -thisSign;
-            } else {// thisSign == val.signum()  and  diffPrecision is aprox. diffScale
-                BigInteger thisUnscaled = this.getUnscaledValue();
-                BigInteger valUnscaled = val.getUnscaledValue();
-                // If any of both precision is bigger, append zeros to the shorter one
-                if (diffScale < 0) {
-                    thisUnscaled = thisUnscaled.multiply(Multiplication.powerOf10(-diffScale));
-                } else if (diffScale > 0) {
-                    valUnscaled = valUnscaled.multiply(Multiplication.powerOf10(diffScale));
-                }
-                return thisUnscaled.compareTo(valUnscaled);
-            }
-        } else if (thisSign < valueSign) {
-            return -1;
-        } else  {
-            return 1;
-        }
-    }
-
-    /**
-     * Returns {@code true} if {@code x} is a {@code BigDecimal} instance and if
-     * this instance is equal to this big decimal. Two big decimals are equal if
-     * their unscaled value and their scale is equal. For example, 1.0
-     * (10*10<sup>-1</sup>) is not equal to 1.00 (100*10<sup>-2</sup>). Similarly, zero
-     * instances are not equal if their scale differs.
-     */
-    @Override
-    public boolean equals(Object x) {
-        if (this == x) {
-            return true;
-        }
-        if (x instanceof BigDecimal) {
-            BigDecimal x1 = (BigDecimal) x;
-            return x1.scale == scale
-                    && x1.bitLength == bitLength
-                    && (bitLength < 64 ? (x1.smallValue == smallValue) : x1.intVal.equals(intVal));
-        }
-        return false;
-    }
-
-    /**
-     * Returns the minimum of this {@code BigDecimal} and {@code val}.
-     *
-     * @param val
-     *            value to be used to compute the minimum with this.
-     * @return {@code min(this, val}.
-     * @throws NullPointerException
-     *             if {@code val == null}.
-     */
-    public BigDecimal min(BigDecimal val) {
-        return ((compareTo(val) <= 0) ? this : val);
-    }
-
-    /**
-     * Returns the maximum of this {@code BigDecimal} and {@code val}.
-     *
-     * @param val
-     *            value to be used to compute the maximum with this.
-     * @return {@code max(this, val}.
-     * @throws NullPointerException
-     *             if {@code val == null}.
-     */
-    public BigDecimal max(BigDecimal val) {
-        return ((compareTo(val) >= 0) ? this : val);
-    }
-
-    /**
-     * Returns a hash code for this {@code BigDecimal}.
-     *
-     * @return hash code for {@code this}.
-     */
-    @Override
-    public int hashCode() {
-        if (hashCode != 0) {
-            return hashCode;
-        }
-        if (bitLength < 64) {
-            hashCode = (int)(smallValue & 0xffffffff);
-            hashCode = 33 * hashCode +  (int)((smallValue >> 32) & 0xffffffff);
-            hashCode = 17 * hashCode + scale;
-            return hashCode;
-        }
-        hashCode = 17 * intVal.hashCode() + scale;
-        return hashCode;
-    }
-
-    /**
-     * Returns a canonical string representation of this {@code BigDecimal}. If
-     * necessary, scientific notation is used. This representation always prints
-     * all significant digits of this value.
-     * <p>
-     * If the scale is negative or if {@code scale - precision >= 6} then
-     * scientific notation is used.
-     *
-     * @return a string representation of {@code this} in scientific notation if
-     *         necessary.
-     */
-    @Override
-    public String toString() {
-        if (toStringImage != null) {
-            return toStringImage;
-        }
-        if(bitLength < 32) {
-            toStringImage = Conversion.toDecimalScaledString(smallValue,scale);
-            return toStringImage;
-        }
-        String intString = getUnscaledValue().toString();
-        if (scale == 0) {
-            return intString;
-        }
-        int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
-        int end = intString.length();
-        long exponent = -(long)scale + end - begin;
-        StringBuilder result = new StringBuilder();
-
-        result.append(intString);
-        if ((scale > 0) && (exponent >= -6)) {
-            if (exponent >= 0) {
-                result.insert(end - scale, '.');
-            } else {
-                result.insert(begin - 1, "0.");
-                result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
-            }
-        } else {
-            if (end - begin >= 1) {
-                result.insert(begin, '.');
-                end++;
-            }
-            result.insert(end, 'E');
-            if (exponent > 0) {
-                result.insert(++end, '+');
-            }
-            result.insert(++end, Long.toString(exponent));
-        }
-        toStringImage = result.toString();
-        return toStringImage;
-    }
-
-    /**
-     * Returns a string representation of this {@code BigDecimal}. This
-     * representation always prints all significant digits of this value.
-     * <p>
-     * If the scale is negative or if {@code scale - precision >= 6} then
-     * engineering notation is used. Engineering notation is similar to the
-     * scientific notation except that the exponent is made to be a multiple of
-     * 3 such that the integer part is >= 1 and < 1000.
-     *
-     * @return a string representation of {@code this} in engineering notation
-     *         if necessary.
-     */
-    public String toEngineeringString() {
-        String intString = getUnscaledValue().toString();
-        if (scale == 0) {
-            return intString;
-        }
-        int begin = (getUnscaledValue().signum() < 0) ? 2 : 1;
-        int end = intString.length();
-        long exponent = -(long)scale + end - begin;
-        StringBuilder result = new StringBuilder(intString);
-
-        if ((scale > 0) && (exponent >= -6)) {
-            if (exponent >= 0) {
-                result.insert(end - scale, '.');
-            } else {
-                result.insert(begin - 1, "0.");
-                result.insert(begin + 1, CH_ZEROS, 0, -(int)exponent - 1);
-            }
-        } else {
-            int delta = end - begin;
-            int rem = (int)(exponent % 3);
-
-            if (rem != 0) {
-                // adjust exponent so it is a multiple of three
-                if (getUnscaledValue().signum() == 0) {
-                    // zero value
-                    rem = (rem < 0) ? -rem : 3 - rem;
-                    exponent += rem;
-                } else {
-                    // nonzero value
-                    rem = (rem < 0) ? rem + 3 : rem;
-                    exponent -= rem;
-                    begin += rem;
-                }
-                if (delta < 3) {
-                    for (int i = rem - delta; i > 0; i--) {
-                        result.insert(end++, '0');
-                    }
-                }
-            }
-            if (end - begin >= 1) {
-                result.insert(begin, '.');
-                end++;
-            }
-            if (exponent != 0) {
-                result.insert(end, 'E');
-                if (exponent > 0) {
-                    result.insert(++end, '+');
-                }
-                result.insert(++end, Long.toString(exponent));
-            }
-        }
-        return result.toString();
-    }
-
-    /**
-     * Returns a string representation of this {@code BigDecimal}. No scientific
-     * notation is used. This methods adds zeros where necessary.
-     * <p>
-     * If this string representation is used to create a new instance, this
-     * instance is generally not identical to {@code this} as the precision
-     * changes.
-     * <p>
-     * {@code x.equals(new BigDecimal(x.toPlainString())} usually returns
-     * {@code false}.
-     * <p>
-     * {@code x.compareTo(new BigDecimal(x.toPlainString())} returns {@code 0}.
-     *
-     * @return a string representation of {@code this} without exponent part.
-     */
-    public String toPlainString() {
-        String intStr = getUnscaledValue().toString();
-        if ((scale == 0) || ((isZero()) && (scale < 0))) {
-            return intStr;
-        }
-        int begin = (signum() < 0) ? 1 : 0;
-        int delta = scale;
-        // We take space for all digits, plus a possible decimal point, plus 'scale'
-        StringBuilder result = new StringBuilder(intStr.length() + 1 + Math.abs(scale));
-
-        if (begin == 1) {
-            // If the number is negative, we insert a '-' character at front
-            result.append('-');
-        }
-        if (scale > 0) {
-            delta -= (intStr.length() - begin);
-            if (delta >= 0) {
-                result.append("0.");
-                // To append zeros after the decimal point
-                for (; delta > CH_ZEROS.length; delta -= CH_ZEROS.length) {
-                    result.append(CH_ZEROS);
-                }
-                result.append(CH_ZEROS, 0, delta);
-                result.append(intStr.substring(begin));
-            } else {
-                delta = begin - delta;
-                result.append(intStr.substring(begin, delta));
-                result.append('.');
-                result.append(intStr.substring(delta));
-            }
-        } else {// (scale <= 0)
-            result.append(intStr.substring(begin));
-            // To append trailing zeros
-            for (; delta < -CH_ZEROS.length; delta += CH_ZEROS.length) {
-                result.append(CH_ZEROS);
-            }
-            result.append(CH_ZEROS, 0, -delta);
-        }
-        return result.toString();
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a big integer instance. A fractional
-     * part is discarded.
-     *
-     * @return this {@code BigDecimal} as a big integer instance.
-     */
-    public BigInteger toBigInteger() {
-        if ((scale == 0) || (isZero())) {
-            return getUnscaledValue();
-        } else if (scale < 0) {
-            return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
-        } else {// (scale > 0)
-            return getUnscaledValue().divide(Multiplication.powerOf10(scale));
-        }
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a big integer instance if it has no
-     * fractional part. If this {@code BigDecimal} has a fractional part, i.e.
-     * if rounding would be necessary, an {@code ArithmeticException} is thrown.
-     *
-     * @return this {@code BigDecimal} as a big integer value.
-     * @throws ArithmeticException
-     *             if rounding is necessary.
-     */
-    public BigInteger toBigIntegerExact() {
-        if ((scale == 0) || (isZero())) {
-            return getUnscaledValue();
-        } else if (scale < 0) {
-            return getUnscaledValue().multiply(Multiplication.powerOf10(-(long)scale));
-        } else {// (scale > 0)
-            BigInteger[] integerAndFraction;
-            // An optimization before do a heavy division
-            if ((scale > approxPrecision()) || (scale > getUnscaledValue().getLowestSetBit())) {
-                throw new ArithmeticException("Rounding necessary");
-            }
-            integerAndFraction = getUnscaledValue().divideAndRemainder(Multiplication.powerOf10(scale));
-            if (integerAndFraction[1].signum() != 0) {
-                // It exists a non-zero fractional part
-                throw new ArithmeticException("Rounding necessary");
-            }
-            return integerAndFraction[0];
-        }
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as an long value. Any fractional part is
-     * discarded. If the integral part of {@code this} is too big to be
-     * represented as an long, then {@code this % 2<sup>64</sup>} is returned.
-     */
-    @Override
-    public long longValue() {
-        /*
-         * If scale <= -64 there are at least 64 trailing bits zero in
-         * 10^(-scale). If the scale is positive and very large the long value
-         * could be zero.
-         */
-        return ((scale <= -64) || (scale > approxPrecision()) ? 0L : toBigInteger().longValue());
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a long value if it has no fractional
-     * part and if its value fits to the int range ([-2<sup>63</sup>..2<sup>63</sup>-1]). If
-     * these conditions are not met, an {@code ArithmeticException} is thrown.
-     *
-     * @throws ArithmeticException
-     *             if rounding is necessary or the number doesn't fit in a long.
-     */
-    public long longValueExact() {
-        return valueExact(64);
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as an int value. Any fractional part is
-     * discarded. If the integral part of {@code this} is too big to be
-     * represented as an int, then {@code this % 2<sup>32</sup>} is returned.
-     */
-    @Override
-    public int intValue() {
-        /*
-         * If scale <= -32 there are at least 32 trailing bits zero in
-         * 10^(-scale). If the scale is positive and very large the long value
-         * could be zero.
-         */
-        return ((scale <= -32) || (scale > approxPrecision()) ? 0 : toBigInteger().intValue());
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a int value if it has no fractional
-     * part and if its value fits to the int range ([-2<sup>31</sup>..2<sup>31</sup>-1]). If
-     * these conditions are not met, an {@code ArithmeticException} is thrown.
-     *
-     * @throws ArithmeticException
-     *             if rounding is necessary or the number doesn't fit in an int.
-     */
-    public int intValueExact() {
-        return (int) valueExact(32);
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a short value if it has no fractional
-     * part and if its value fits to the short range ([-2<sup>15</sup>..2<sup>15</sup>-1]). If
-     * these conditions are not met, an {@code ArithmeticException} is thrown.
-     *
-     * @throws ArithmeticException
-     *             if rounding is necessary of the number doesn't fit in a short.
-     */
-    public short shortValueExact() {
-        return (short) valueExact(16);
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a byte value if it has no fractional
-     * part and if its value fits to the byte range ([-128..127]). If these
-     * conditions are not met, an {@code ArithmeticException} is thrown.
-     *
-     * @throws ArithmeticException
-     *             if rounding is necessary or the number doesn't fit in a byte.
-     */
-    public byte byteValueExact() {
-        return (byte) valueExact(8);
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a float value. If {@code this} is too
-     * big to be represented as an float, then {@code Float.POSITIVE_INFINITY}
-     * or {@code Float.NEGATIVE_INFINITY} is returned.
-     * <p>
-     * Note, that if the unscaled value has more than 24 significant digits,
-     * then this decimal cannot be represented exactly in a float variable. In
-     * this case the result is rounded.
-     * <p>
-     * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
-     * represented exactly as a float, and thus {@code x1.equals(new
-     * BigDecimal(x1.floatValue())} returns {@code false} for this case.
-     * <p>
-     * Similarly, if the instance {@code new BigDecimal(16777217)} is converted
-     * to a float, the result is {@code 1.6777216E}7.
-     *
-     * @return this {@code BigDecimal} as a float value.
-     */
-    @Override
-    public float floatValue() {
-        /* A similar code like in doubleValue() could be repeated here,
-         * but this simple implementation is quite efficient. */
-        float floatResult = signum();
-        long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
-        if ((powerOfTwo < -149) || (floatResult == 0.0f)) {
-            // Cases which 'this' is very small
-            floatResult *= 0.0f;
-        } else if (powerOfTwo > 129) {
-            // Cases which 'this' is very large
-            floatResult *= Float.POSITIVE_INFINITY;
-        } else {
-            floatResult = (float)doubleValue();
-        }
-        return floatResult;
-    }
-
-    /**
-     * Returns this {@code BigDecimal} as a double value. If {@code this} is too
-     * big to be represented as an float, then {@code Double.POSITIVE_INFINITY}
-     * or {@code Double.NEGATIVE_INFINITY} is returned.
-     * <p>
-     * Note, that if the unscaled value has more than 53 significant digits,
-     * then this decimal cannot be represented exactly in a double variable. In
-     * this case the result is rounded.
-     * <p>
-     * For example, if the instance {@code x1 = new BigDecimal("0.1")} cannot be
-     * represented exactly as a double, and thus {@code x1.equals(new
-     * BigDecimal(x1.doubleValue())} returns {@code false} for this case.
-     * <p>
-     * Similarly, if the instance {@code new BigDecimal(9007199254740993L)} is
-     * converted to a double, the result is {@code 9.007199254740992E15}.
-     * <p>
-     *
-     * @return this {@code BigDecimal} as a double value.
-     */
-    @Override
-    public double doubleValue() {
-        int sign = signum();
-        int exponent = 1076; // bias + 53
-        int lowestSetBit;
-        int discardedSize;
-        long powerOfTwo = this.bitLength - (long)(scale / LOG10_2);
-        long bits; // IEEE-754 Standard
-        long tempBits; // for temporal calculations
-        BigInteger mantissa;
-
-        if ((powerOfTwo < -1074) || (sign == 0)) {
-            // Cases which 'this' is very small
-            return (sign * 0.0d);
-        } else if (powerOfTwo > 1025) {
-            // Cases which 'this' is very large
-            return (sign * Double.POSITIVE_INFINITY);
-        }
-        mantissa = getUnscaledValue().abs();
-        // Let be:  this = [u,s], with s > 0
-        if (scale <= 0) {
-            // mantissa = abs(u) * 10^s
-            mantissa = mantissa.multiply(Multiplication.powerOf10(-scale));
-        } else {// (scale > 0)
-            BigInteger quotAndRem[];
-            BigInteger powerOfTen = Multiplication.powerOf10(scale);
-            int k = 100 - (int)powerOfTwo;
-            int compRem;
-
-            if (k > 0) {
-                /* Computing (mantissa * 2^k) , where 'k' is a enough big
-                 * power of '2' to can divide by 10^s */
-                mantissa = mantissa.shiftLeft(k);
-                exponent -= k;
-            }
-            // Computing (mantissa * 2^k) / 10^s
-            quotAndRem = mantissa.divideAndRemainder(powerOfTen);
-            // To check if the fractional part >= 0.5
-            compRem = quotAndRem[1].shiftLeftOneBit().compareTo(powerOfTen);
-            // To add two rounded bits at end of mantissa
-            mantissa = quotAndRem[0].shiftLeft(2).add(
-                    BigInteger.valueOf((compRem * (compRem + 3)) / 2 + 1));
-            exponent -= 2;
-        }
-        lowestSetBit = mantissa.getLowestSetBit();
-        discardedSize = mantissa.bitLength() - 54;
-        if (discardedSize > 0) {// (n > 54)
-            // mantissa = (abs(u) * 10^s) >> (n - 54)
-            bits = mantissa.shiftRight(discardedSize).longValue();
-            tempBits = bits;
-            // #bits = 54, to check if the discarded fraction produces a carry
-            if ((((bits & 1) == 1) && (lowestSetBit < discardedSize))
-                    || ((bits & 3) == 3)) {
-                bits += 2;
-            }
-        } else {// (n <= 54)
-            // mantissa = (abs(u) * 10^s) << (54 - n)
-            bits = mantissa.longValue() << -discardedSize;
-            tempBits = bits;
-            // #bits = 54, to check if the discarded fraction produces a carry:
-            if ((bits & 3) == 3) {
-                bits += 2;
-            }
-        }
-        // Testing bit 54 to check if the carry creates a new binary digit
-        if ((bits & 0x40000000000000L) == 0) {
-            // To drop the last bit of mantissa (first discarded)
-            bits >>= 1;
-            // exponent = 2^(s-n+53+bias)
-            exponent += discardedSize;
-        } else {// #bits = 54
-            bits >>= 2;
-            exponent += discardedSize + 1;
-        }
-        // To test if the 53-bits number fits in 'double'
-        if (exponent > 2046) {// (exponent - bias > 1023)
-            return (sign * Double.POSITIVE_INFINITY);
-        } else if (exponent <= 0) {// (exponent - bias <= -1023)
-            // Denormalized numbers (having exponent == 0)
-            if (exponent < -53) {// exponent - bias < -1076
-                return (sign * 0.0d);
-            }
-            // -1076 <= exponent - bias <= -1023
-            // To discard '- exponent + 1' bits
-            bits = tempBits >> 1;
-            tempBits = bits & (-1L >>> (63 + exponent));
-            bits >>= (-exponent );
-            // To test if after discard bits, a new carry is generated
-            if (((bits & 3) == 3) || (((bits & 1) == 1) && (tempBits != 0)
-            && (lowestSetBit < discardedSize))) {
-                bits += 1;
-            }
-            exponent = 0;
-            bits >>= 1;
-        }
-        // Construct the 64 double bits: [sign(1), exponent(11), mantissa(52)]
-        bits = (sign & 0x8000000000000000L) | ((long)exponent << 52)
-                | (bits & 0xFFFFFFFFFFFFFL);
-        return Double.longBitsToDouble(bits);
-    }
-
-    /**
-     * Returns the unit in the last place (ULP) of this {@code BigDecimal}
-     * instance. An ULP is the distance to the nearest big decimal with the same
-     * precision.
-     *
-     * <p>The amount of a rounding error in the evaluation of a floating-point
-     * operation is often expressed in ULPs. An error of 1 ULP is often seen as
-     * a tolerable error.
-     *
-     * <p>For class {@code BigDecimal}, the ULP of a number is simply 10<sup>-scale</sup>.
-     * For example, {@code new BigDecimal(0.1).ulp()} returns {@code 1E-55}.
-     *
-     * @return unit in the last place (ULP) of this {@code BigDecimal} instance.
-     */
-    public BigDecimal ulp() {
-        return valueOf(1, scale);
-    }
-
-    /* Private Methods */
-
-    /**
-     * It does all rounding work of the public method
-     * {@code round(MathContext)}, performing an inplace rounding
-     * without creating a new object.
-     *
-     * @param mc
-     *            the {@code MathContext} for perform the rounding.
-     * @see #round(MathContext)
-     */
-    private void inplaceRound(MathContext mc) {
-        int mcPrecision = mc.getPrecision();
-        if (approxPrecision() < mcPrecision || mcPrecision == 0) {
-            return;
-        }
-        int discardedPrecision = precision() - mcPrecision;
-        // If no rounding is necessary it returns immediately
-        if ((discardedPrecision <= 0)) {
-            return;
-        }
-        // When the number is small perform an efficient rounding
-        if (this.bitLength < 64) {
-            smallRound(mc, discardedPrecision);
-            return;
-        }
-        // Getting the integer part and the discarded fraction
-        BigInteger sizeOfFraction = Multiplication.powerOf10(discardedPrecision);
-        BigInteger[] integerAndFraction = getUnscaledValue().divideAndRemainder(sizeOfFraction);
-        long newScale = (long)scale - discardedPrecision;
-        int compRem;
-        BigDecimal tempBD;
-        // If the discarded fraction is non-zero, perform rounding
-        if (integerAndFraction[1].signum() != 0) {
-            // To check if the discarded fraction >= 0.5
-            compRem = (integerAndFraction[1].abs().shiftLeftOneBit().compareTo(sizeOfFraction));
-            // To look if there is a carry
-            compRem =  roundingBehavior( integerAndFraction[0].testBit(0) ? 1 : 0,
-                    integerAndFraction[1].signum() * (5 + compRem),
-                    mc.getRoundingMode());
-            if (compRem != 0) {
-                integerAndFraction[0] = integerAndFraction[0].add(BigInteger.valueOf(compRem));
-            }
-            tempBD = new BigDecimal(integerAndFraction[0]);
-            // If after to add the increment the precision changed, we normalize the size
-            if (tempBD.precision() > mcPrecision) {
-                integerAndFraction[0] = integerAndFraction[0].divide(BigInteger.TEN);
-                newScale--;
-            }
-        }
-        // To update all internal fields
-        scale = safeLongToInt(newScale);
-        precision = mcPrecision;
-        setUnscaledValue(integerAndFraction[0]);
-    }
-
-    /**
-     * Returns -1, 0, and 1 if {@code value1 < value2}, {@code value1 == value2},
-     * and {@code value1 > value2}, respectively, when comparing without regard
-     * to the values' sign.
-     *
-     * <p>Note that this implementation deals correctly with Long.MIN_VALUE,
-     * whose absolute magnitude is larger than any other {@code long} value.
-     */
-    private static int compareAbsoluteValues(long value1, long value2) {
-        // Map long values to the range -1 .. Long.MAX_VALUE so that comparison
-        // of absolute magnitude can be done using regular long arithmetics.
-        // This deals correctly with Long.MIN_VALUE, whose absolute magnitude
-        // is larger than any other long value, and which is mapped to
-        // Long.MAX_VALUE here.
-        // Values that only differ by sign get mapped to the same value, for
-        // example both +3 and -3 get mapped to +2.
-        value1 = Math.abs(value1) - 1;
-        value2 = Math.abs(value2) - 1;
-        // Unlike Long.compare(), we guarantee to return specifically -1 and +1
-        return value1 > value2 ? 1 : (value1 < value2 ? -1 : 0);
-    }
-
-    /**
-     * Compares {@code n} against {@code 0.5 * d} in absolute terms (ignoring sign)
-     * and with arithmetics that are safe against overflow or loss of precision.
-     * Returns -1 if {@code n} is less than {@code 0.5 * d}, 0 if {@code n == 0.5 * d},
-     * or +1 if {@code n > 0.5 * d} when comparing the absolute values under such
-     * arithmetics.
-     */
-    private static int compareForRounding(long n, long d) {
-        long halfD = d / 2; //  rounds towards 0
-        if (n == halfD || n == -halfD) {
-            // In absolute terms: Because n == halfD, we know that 2 * n + lsb == d
-            // for some lsb value 0 or 1. This means that n == d/2 (result 0) if
-            // lsb is 0, or n < d/2 (result -1) if lsb is 1. In either case, the
-            // result is -lsb.
-            // Since we're calculating in absolute terms, we need the absolute lsb
-            // (d & 1) as opposed to the signed lsb (d % 2) which would be -1 for
-            // negative odd values of d.
-            int lsb = (int) d & 1;
-            return -lsb; // returns 0 or -1
-        } else {
-            // In absolute terms, either 2 * n + 1 < d (in the case of n < halfD),
-            // or 2 * n > d (in the case of n > halfD).
-            // In either case, comparing n against halfD gets the right result
-            // -1 or +1, respectively.
-            return compareAbsoluteValues(n, halfD);
-        }
-    }
-
-    /**
-     * This method implements an efficient rounding for numbers which unscaled
-     * value fits in the type {@code long}.
-     *
-     * @param mc
-     *            the context to use
-     * @param discardedPrecision
-     *            the number of decimal digits that are discarded
-     * @see #round(MathContext)
-     */
-    private void smallRound(MathContext mc, int discardedPrecision) {
-        long sizeOfFraction = MathUtils.LONG_POWERS_OF_TEN[discardedPrecision];
-        long newScale = (long)scale - discardedPrecision;
-        long unscaledVal = smallValue;
-        // Getting the integer part and the discarded fraction
-        long integer = unscaledVal / sizeOfFraction;
-        long fraction = unscaledVal % sizeOfFraction;
-        int compRem;
-        // If the discarded fraction is non-zero perform rounding
-        if (fraction != 0) {
-            // To check if the discarded fraction >= 0.5
-            compRem = compareForRounding(fraction, sizeOfFraction);
-            // To look if there is a carry
-            integer += roundingBehavior( ((int)integer) & 1,
-                    Long.signum(fraction) * (5 + compRem),
-                    mc.getRoundingMode());
-            // If after to add the increment the precision changed, we normalize the size
-            if (Math.log10(Math.abs(integer)) >= mc.getPrecision()) {
-                integer /= 10;
-                newScale--;
-            }
-        }
-        // To update all internal fields
-        scale = safeLongToInt(newScale);
-        precision = mc.getPrecision();
-        smallValue = integer;
-        bitLength = bitLength(integer);
-        intVal = null;
-    }
-
-    /**
-     * Return an increment that can be -1,0 or 1, depending of
-     * {@code roundingMode}.
-     *
-     * @param parityBit
-     *            can be 0 or 1, it's only used in the case
-     *            {@code HALF_EVEN}
-     * @param fraction
-     *            the mantissa to be analyzed
-     * @param roundingMode
-     *            the type of rounding
-     * @return the carry propagated after rounding
-     */
-    private static int roundingBehavior(int parityBit, int fraction, RoundingMode roundingMode) {
-        int increment = 0; // the carry after rounding
-
-        switch (roundingMode) {
-            case UNNECESSARY:
-                if (fraction != 0) {
-                    throw new ArithmeticException("Rounding necessary");
-                }
-                break;
-            case UP:
-                increment = Integer.signum(fraction);
-                break;
-            case DOWN:
-                break;
-            case CEILING:
-                increment = Math.max(Integer.signum(fraction), 0);
-                break;
-            case FLOOR:
-                increment = Math.min(Integer.signum(fraction), 0);
-                break;
-            case HALF_UP:
-                if (Math.abs(fraction) >= 5) {
-                    increment = Integer.signum(fraction);
-                }
-                break;
-            case HALF_DOWN:
-                if (Math.abs(fraction) > 5) {
-                    increment = Integer.signum(fraction);
-                }
-                break;
-            case HALF_EVEN:
-                if (Math.abs(fraction) + parityBit > 5) {
-                    increment = Integer.signum(fraction);
-                }
-                break;
-        }
-        return increment;
-    }
-
-    /**
-     * If {@code intVal} has a fractional part throws an exception,
-     * otherwise it counts the number of bits of value and checks if it's out of
-     * the range of the primitive type. If the number fits in the primitive type
-     * returns this number as {@code long}, otherwise throws an
-     * exception.
-     *
-     * @param bitLengthOfType
-     *            number of bits of the type whose value will be calculated
-     *            exactly
-     * @return the exact value of the integer part of {@code BigDecimal}
-     *         when is possible
-     * @throws ArithmeticException when rounding is necessary or the
-     *             number don't fit in the primitive type
-     */
-    private long valueExact(int bitLengthOfType) {
-        BigInteger bigInteger = toBigIntegerExact();
-
-        if (bigInteger.bitLength() < bitLengthOfType) {
-            // It fits in the primitive type
-            return bigInteger.longValue();
-        }
-        throw new ArithmeticException("Rounding necessary");
-    }
-
-    /**
-     * If the precision already was calculated it returns that value, otherwise
-     * it calculates a very good approximation efficiently . Note that this
-     * value will be {@code precision()} or {@code precision()-1}
-     * in the worst case.
-     *
-     * @return an approximation of {@code precision()} value
-     */
-    private int approxPrecision() {
-        return precision > 0
-                ? precision
-                : (int) ((this.bitLength - 1) * LOG10_2) + 1;
-    }
-
-    private static int safeLongToInt(long longValue) {
-        if (longValue < Integer.MIN_VALUE || longValue > Integer.MAX_VALUE) {
-            throw new ArithmeticException("Out of int range: " + longValue);
-        }
-        return (int) longValue;
-    }
-
-    /**
-     * It returns the value 0 with the most approximated scale of type
-     * {@code int}. if {@code longScale > Integer.MAX_VALUE} the
-     * scale will be {@code Integer.MAX_VALUE}; if
-     * {@code longScale < Integer.MIN_VALUE} the scale will be
-     * {@code Integer.MIN_VALUE}; otherwise {@code longScale} is
-     * casted to the type {@code int}.
-     *
-     * @param longScale
-     *            the scale to which the value 0 will be scaled.
-     * @return the value 0 scaled by the closer scale of type {@code int}.
-     * @see #scale
-     */
-    private static BigDecimal zeroScaledBy(long longScale) {
-        if (longScale == (int) longScale) {
-            return valueOf(0,(int)longScale);
-            }
-        if (longScale >= 0) {
-            return new BigDecimal( 0, Integer.MAX_VALUE);
-        }
-        return new BigDecimal( 0, Integer.MIN_VALUE);
-    }
-
-    /**
-     * Assigns all transient fields upon deserialization of a
-     * {@code BigDecimal} instance (bitLength and smallValue). The transient
-     * field precision is assigned lazily.
-     */
-    private void readObject(ObjectInputStream in) throws IOException,
-            ClassNotFoundException {
-        in.defaultReadObject();
-
-        this.bitLength = intVal.bitLength();
-        if (this.bitLength < 64) {
-            this.smallValue = intVal.longValue();
-        }
-    }
-
-    /**
-     * Prepares this {@code BigDecimal} for serialization, i.e. the
-     * non-transient field {@code intVal} is assigned.
-     */
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        getUnscaledValue();
-        out.defaultWriteObject();
-    }
-
-    private BigInteger getUnscaledValue() {
-        if(intVal == null) {
-            intVal = BigInteger.valueOf(smallValue);
-        }
-        return intVal;
-    }
-
-    private void setUnscaledValue(BigInteger unscaledValue) {
-        this.intVal = unscaledValue;
-        this.bitLength = unscaledValue.bitLength();
-        if(this.bitLength < 64) {
-            this.smallValue = unscaledValue.longValue();
-        }
-    }
-
-    private static int bitLength(long smallValue) {
-        if(smallValue < 0) {
-            smallValue = ~smallValue;
-        }
-        return 64 - Long.numberOfLeadingZeros(smallValue);
-    }
-
-    private static int bitLength(int smallValue) {
-        if(smallValue < 0) {
-            smallValue = ~smallValue;
-        }
-        return 32 - Integer.numberOfLeadingZeros(smallValue);
-    }
-
-}
diff --git a/luni/src/main/java/java/math/BigInt.java b/luni/src/main/java/java/math/BigInt.java
deleted file mode 100644
index 4448ce1..0000000
--- a/luni/src/main/java/java/math/BigInt.java
+++ /dev/null
@@ -1,346 +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 java.math;
-
-import dalvik.annotation.optimization.ReachabilitySensitive;
-import libcore.util.NativeAllocationRegistry;
-
-/*
- * In contrast to BigIntegers this class doesn't fake two's complement representation.
- * Any Bit-Operations, including Shifting, solely regard the unsigned magnitude.
- * Moreover BigInt objects are mutable and offer efficient in-place-operations.
- */
-final class BigInt {
-
-    private static NativeAllocationRegistry registry = NativeAllocationRegistry.createMalloced(
-            BigInt.class.getClassLoader(), NativeBN.getNativeFinalizer());
-
-    /* Fields used for the internal representation. */
-    @ReachabilitySensitive
-    private transient long bignum = 0;
-
-    @Override
-    public String toString() {
-        return this.decString();
-    }
-
-    boolean hasNativeBignum() {
-        return this.bignum != 0;
-    }
-
-    private void makeValid() {
-        if (this.bignum == 0) {
-            this.bignum = NativeBN.BN_new();
-            registry.registerNativeAllocation(this, this.bignum);
-        }
-    }
-
-    private static BigInt newBigInt() {
-        BigInt bi = new BigInt();
-        bi.bignum = NativeBN.BN_new();
-        registry.registerNativeAllocation(bi, bi.bignum);
-        return bi;
-    }
-
-
-    static int cmp(BigInt a, BigInt b) {
-        return NativeBN.BN_cmp(a.bignum, b.bignum);
-    }
-
-
-    void putCopy(BigInt from) {
-        this.makeValid();
-        NativeBN.BN_copy(this.bignum, from.bignum);
-    }
-
-    BigInt copy() {
-        BigInt bi = new BigInt();
-        bi.putCopy(this);
-        return bi;
-    }
-
-
-    void putLongInt(long val) {
-        this.makeValid();
-        NativeBN.putLongInt(this.bignum, val);
-    }
-
-    void putULongInt(long val, boolean neg) {
-        this.makeValid();
-        NativeBN.putULongInt(this.bignum, val, neg);
-    }
-
-    private NumberFormatException invalidBigInteger(String s) {
-        throw new NumberFormatException("Invalid BigInteger: " + s);
-    }
-
-    void putDecString(String original) {
-        String s = checkString(original, 10);
-        this.makeValid();
-        int usedLen = NativeBN.BN_dec2bn(this.bignum, s);
-        if (usedLen < s.length()) {
-            throw invalidBigInteger(original);
-        }
-    }
-
-    void putHexString(String original) {
-        String s = checkString(original, 16);
-        this.makeValid();
-        int usedLen = NativeBN.BN_hex2bn(this.bignum, s);
-        if (usedLen < s.length()) {
-            throw invalidBigInteger(original);
-        }
-    }
-
-    /**
-     * Returns a string suitable for passing to OpenSSL.
-     * Throws if 's' doesn't match Java's rules for valid BigInteger strings.
-     * BN_dec2bn and BN_hex2bn do very little checking, so we need to manually
-     * ensure we comply with Java's rules.
-     * http://code.google.com/p/android/issues/detail?id=7036
-     */
-    String checkString(String s, int base) {
-        if (s == null) {
-            throw new NullPointerException("s == null");
-        }
-        // A valid big integer consists of an optional '-' or '+' followed by
-        // one or more digit characters appropriate to the given base,
-        // and no other characters.
-        int charCount = s.length();
-        int i = 0;
-        if (charCount > 0) {
-            char ch = s.charAt(0);
-            if (ch == '+') {
-                // Java supports leading +, but OpenSSL doesn't, so we need to strip it.
-                s = s.substring(1);
-                --charCount;
-            } else if (ch == '-') {
-                ++i;
-            }
-        }
-        if (charCount - i == 0) {
-            throw invalidBigInteger(s);
-        }
-        boolean nonAscii = false;
-        for (; i < charCount; ++i) {
-            char ch = s.charAt(i);
-            if (Character.digit(ch, base) == -1) {
-                throw invalidBigInteger(s);
-            }
-            if (ch > 128) {
-                nonAscii = true;
-            }
-        }
-        return nonAscii ? toAscii(s, base) : s;
-    }
-
-    // Java supports non-ASCII decimal digits, but OpenSSL doesn't.
-    // We need to translate the decimal digits but leave any other characters alone.
-    // This method assumes it's being called on a string that has already been validated.
-    private static String toAscii(String s, int base) {
-        int length = s.length();
-        StringBuilder result = new StringBuilder(length);
-        for (int i = 0; i < length; ++i) {
-            char ch = s.charAt(i);
-            int value = Character.digit(ch, base);
-            if (value >= 0 && value <= 9) {
-                ch = (char) ('0' + value);
-            }
-            result.append(ch);
-        }
-        return result.toString();
-    }
-
-    void putBigEndian(byte[] a, boolean neg) {
-        this.makeValid();
-        NativeBN.BN_bin2bn(a, a.length, neg, this.bignum);
-    }
-
-    void putLittleEndianInts(int[] a, boolean neg) {
-        this.makeValid();
-        NativeBN.litEndInts2bn(a, a.length, neg, this.bignum);
-    }
-
-    void putBigEndianTwosComplement(byte[] a) {
-        this.makeValid();
-        NativeBN.twosComp2bn(a, a.length, this.bignum);
-    }
-
-
-    long longInt() {
-        return NativeBN.longInt(this.bignum);
-    }
-
-    String decString() {
-        return NativeBN.BN_bn2dec(this.bignum);
-    }
-
-    String hexString() {
-        return NativeBN.BN_bn2hex(this.bignum);
-    }
-
-    byte[] bigEndianMagnitude() {
-        return NativeBN.BN_bn2bin(this.bignum);
-    }
-
-    int[] littleEndianIntsMagnitude() {
-        return NativeBN.bn2litEndInts(this.bignum);
-    }
-
-    int sign() {
-        return NativeBN.sign(this.bignum);
-    }
-
-    void setSign(int val) {
-        if (val > 0) {
-            NativeBN.BN_set_negative(this.bignum, 0);
-        } else {
-            if (val < 0) NativeBN.BN_set_negative(this.bignum, 1);
-        }
-    }
-
-    boolean twosCompFitsIntoBytes(int desiredByteCount) {
-        int actualByteCount = (NativeBN.bitLength(this.bignum) + 7) / 8;
-        return actualByteCount <= desiredByteCount;
-    }
-
-    int bitLength() {
-        return NativeBN.bitLength(this.bignum);
-    }
-
-    boolean isBitSet(int n) {
-        return NativeBN.BN_is_bit_set(this.bignum, n);
-    }
-
-    // n > 0: shift left (multiply)
-    static BigInt shift(BigInt a, int n) {
-        BigInt r = newBigInt();
-        NativeBN.BN_shift(r.bignum, a.bignum, n);
-        return r;
-    }
-
-    void shift(int n) {
-        NativeBN.BN_shift(this.bignum, this.bignum, n);
-    }
-
-    void addPositiveInt(int w) {
-        NativeBN.BN_add_word(this.bignum, w);
-    }
-
-    void multiplyByPositiveInt(int w) {
-        NativeBN.BN_mul_word(this.bignum, w);
-    }
-
-    static int remainderByPositiveInt(BigInt a, int w) {
-        return NativeBN.BN_mod_word(a.bignum, w);
-    }
-
-    static BigInt addition(BigInt a, BigInt b) {
-        BigInt r = newBigInt();
-        NativeBN.BN_add(r.bignum, a.bignum, b.bignum);
-        return r;
-    }
-
-    void add(BigInt a) {
-        NativeBN.BN_add(this.bignum, this.bignum, a.bignum);
-    }
-
-    static BigInt subtraction(BigInt a, BigInt b) {
-        BigInt r = newBigInt();
-        NativeBN.BN_sub(r.bignum, a.bignum, b.bignum);
-        return r;
-    }
-
-
-    static BigInt gcd(BigInt a, BigInt b) {
-        BigInt r = newBigInt();
-        NativeBN.BN_gcd(r.bignum, a.bignum, b.bignum);
-        return r;
-    }
-
-    static BigInt product(BigInt a, BigInt b) {
-        BigInt r = newBigInt();
-        NativeBN.BN_mul(r.bignum, a.bignum, b.bignum);
-        return r;
-    }
-
-    static BigInt bigExp(BigInt a, BigInt p) {
-        // Sign of p is ignored!
-        BigInt r = newBigInt();
-        NativeBN.BN_exp(r.bignum, a.bignum, p.bignum);
-        return r;
-    }
-
-    static BigInt exp(BigInt a, int p) {
-        // Sign of p is ignored!
-        BigInt power = new BigInt();
-        power.putLongInt(p);
-        return bigExp(a, power);
-        // OPTIONAL:
-        // int BN_sqr(BigInteger r, BigInteger a, BN_CTX ctx);
-        // int BN_sqr(BIGNUM *r, const BIGNUM *a,BN_CTX *ctx);
-    }
-
-    static void division(BigInt dividend, BigInt divisor, BigInt quotient, BigInt remainder) {
-        long quot, rem;
-        if (quotient != null) {
-            quotient.makeValid();
-            quot = quotient.bignum;
-        } else {
-            quot = 0;
-        }
-        if (remainder != null) {
-            remainder.makeValid();
-            rem = remainder.bignum;
-        } else {
-            rem = 0;
-        }
-        NativeBN.BN_div(quot, rem, dividend.bignum, divisor.bignum);
-    }
-
-    static BigInt modulus(BigInt a, BigInt m) {
-        // Sign of p is ignored! ?
-        BigInt r = newBigInt();
-        NativeBN.BN_nnmod(r.bignum, a.bignum, m.bignum);
-        return r;
-    }
-
-    static BigInt modExp(BigInt a, BigInt p, BigInt m) {
-        // Sign of p is ignored!
-        BigInt r = newBigInt();
-        NativeBN.BN_mod_exp(r.bignum, a.bignum, p.bignum, m.bignum);
-        return r;
-    }
-
-
-    static BigInt modInverse(BigInt a, BigInt m) {
-        BigInt r = newBigInt();
-        NativeBN.BN_mod_inverse(r.bignum, a.bignum, m.bignum);
-        return r;
-    }
-
-
-    static BigInt generatePrimeDefault(int bitLength) {
-        BigInt r = newBigInt();
-        NativeBN.BN_generate_prime_ex(r.bignum, bitLength, false, 0, 0);
-        return r;
-    }
-
-    boolean isPrime(int certainty) {
-        return NativeBN.BN_primality_test(bignum, certainty, false);
-    }
-}
diff --git a/luni/src/main/java/java/math/BigInteger.java b/luni/src/main/java/java/math/BigInteger.java
deleted file mode 100644
index b96fdb2..0000000
--- a/luni/src/main/java/java/math/BigInteger.java
+++ /dev/null
@@ -1,1275 +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 java.math;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-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.
- *
- * <h3>Fast Cryptography</h3>
- * This implementation is efficient for operations traditionally used in
- * cryptography, such as the generation of large prime numbers and computation
- * of the modular inverse.
- *
- * <h3>Slow Two's Complement Bitwise Operations</h3>
- * This API includes operations for bitwise operations in two's complement
- * representation. Two's complement is not the internal representation used by
- * this implementation, so such methods may be inefficient. Use {@link
- * java.util.BitSet} for high-performance bitwise operations on
- * arbitrarily-large sequences of bits.
- */
-public class BigInteger extends Number
-        implements Comparable<BigInteger>, Serializable {
-
-    /** This is the serialVersionUID used by the sun implementation. */
-    private static final long serialVersionUID = -8287574255936472291L;
-
-    private transient BigInt bigInt;
-
-    private transient boolean nativeIsValid = false;
-
-    private transient boolean javaIsValid = false;
-
-    /** The magnitude of this in the little-endian representation. */
-    transient int[] digits;
-
-    /**
-     * The length of this in measured in ints. Can be less than
-     * digits.length().
-     */
-    transient int numberLength;
-
-    /** The sign of this. */
-    transient int sign;
-
-    /** The {@code BigInteger} constant 0. */
-    @NonNull public static final BigInteger ZERO = new BigInteger(0, 0);
-
-    /** The {@code BigInteger} constant 1. */
-    @NonNull public static final BigInteger ONE = new BigInteger(1, 1);
-
-    /** The {@code BigInteger} constant 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);
-
-    /** All the {@code BigInteger} numbers in the range [0,10] are cached. */
-    static final BigInteger[] SMALL_VALUES = { ZERO, ONE, new BigInteger(1, 2),
-            new BigInteger(1, 3), new BigInteger(1, 4), new BigInteger(1, 5),
-            new BigInteger(1, 6), new BigInteger(1, 7), new BigInteger(1, 8),
-            new BigInteger(1, 9), TEN };
-
-    private transient int firstNonzeroDigit = -2;
-
-    /** sign field, used for serialization. */
-    private int signum;
-
-    /** absolute value field, used for serialization */
-    private byte[] magnitude;
-
-    /** Cache for the hash code. */
-    private transient int hashCode = 0;
-
-    BigInteger(BigInt bigInt) {
-        if (bigInt == null || !bigInt.hasNativeBignum()) {
-            throw new AssertionError();
-        }
-        setBigInt(bigInt);
-    }
-
-    BigInteger(int sign, long value) {
-        BigInt bigInt = new BigInt();
-        bigInt.putULongInt(value, (sign < 0));
-        setBigInt(bigInt);
-    }
-
-    /**
-     * Constructs a number without creating new space. This construct should be
-     * used only if the three fields of representation are known.
-     *
-     * @param sign the sign of the number.
-     * @param numberLength the length of the internal array.
-     * @param digits a reference of some array created before.
-     */
-    BigInteger(int sign, int numberLength, int[] digits) {
-        setJavaRepresentation(sign, numberLength, digits);
-    }
-
-    /**
-     * Constructs a random non-negative {@code BigInteger} instance in the range
-     * {@code [0, pow(2, numBits)-1]}.
-     *
-     * @param numBits maximum length of the new {@code BigInteger} in bits.
-     * @param random is the random number generator to be used.
-     * @throws IllegalArgumentException if {@code numBits} < 0.
-     */
-    public BigInteger(int numBits, @NonNull Random random) {
-        if (numBits < 0) {
-            throw new IllegalArgumentException("numBits < 0: " + numBits);
-        }
-        if (numBits == 0) {
-            setJavaRepresentation(0, 1, new int[] { 0 });
-        } else {
-            int sign = 1;
-            int numberLength = (numBits + 31) >> 5;
-            int[] digits = new int[numberLength];
-            for (int i = 0; i < numberLength; i++) {
-                digits[i] = random.nextInt();
-            }
-            // Clear any extra bits.
-            digits[numberLength - 1] >>>= (-numBits) & 31;
-            setJavaRepresentation(sign, numberLength, digits);
-        }
-        javaIsValid = true;
-    }
-
-    /**
-     * Constructs a random {@code BigInteger} instance in the range {@code [0,
-     * pow(2, bitLength)-1]} which is probably prime. The probability that the
-     * returned {@code BigInteger} is prime is greater than
-     * {@code 1 - 1/2<sup>certainty</sup>)}.
-     *
-     * <p><b>Note:</b> the {@code Random} argument is ignored if
-     * {@code bitLength >= 16}, where this implementation will use OpenSSL's
-     * {@code BN_generate_prime_ex} as a source of cryptographically strong pseudo-random numbers.
-     *
-     * @param bitLength length of the new {@code BigInteger} in bits.
-     * @param certainty tolerated primality uncertainty.
-     * @throws ArithmeticException if {@code bitLength < 2}.
-     * @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, @NonNull Random random) {
-        if (bitLength < 2) {
-            throw new ArithmeticException("bitLength < 2: " + bitLength);
-        }
-        if (bitLength < 16) {
-            // We have to generate short primes ourselves, because OpenSSL bottoms out at 16 bits.
-            int candidate;
-            do {
-                candidate = random.nextInt() & ((1 << bitLength) - 1);
-                candidate |= (1 << (bitLength - 1)); // Set top bit.
-                if (bitLength > 2) {
-                    candidate |= 1; // Any prime longer than 2 bits must have the bottom bit set.
-                }
-            } while (!isSmallPrime(candidate));
-            BigInt prime = new BigInt();
-            prime.putULongInt(candidate, false);
-            setBigInt(prime);
-        } else {
-            // We need a loop here to work around an OpenSSL bug; http://b/8588028.
-            do {
-                setBigInt(BigInt.generatePrimeDefault(bitLength));
-            } while (bitLength() != bitLength);
-        }
-    }
-
-    private static boolean isSmallPrime(int x) {
-        if (x == 2) {
-            return true;
-        }
-        if ((x % 2) == 0) {
-            return false;
-        }
-        final int max = (int) Math.sqrt(x);
-        for (int i = 3; i <= max; i += 2) {
-            if ((x % i) == 0) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Constructs a new {@code BigInteger} by parsing {@code value}. The string
-     * representation consists of an optional plus or minus sign followed by a
-     * non-empty sequence of decimal digits. Digits are interpreted as if by
-     * {@code Character.digit(char,10)}.
-     *
-     * @param value string representation of the new {@code BigInteger}.
-     * @throws NullPointerException if {@code value == null}.
-     * @throws NumberFormatException if {@code value} is not a valid
-     *     representation of a {@code BigInteger}.
-     */
-    public BigInteger(@NonNull String value) {
-        BigInt bigInt = new BigInt();
-        bigInt.putDecString(value);
-        setBigInt(bigInt);
-    }
-
-    /**
-     * Constructs a new {@code BigInteger} instance by parsing {@code value}.
-     * The string representation consists of an optional plus or minus sign
-     * followed by a non-empty sequence of digits in the specified radix. Digits
-     * are interpreted as if by {@code Character.digit(char, radix)}.
-     *
-     * @param value string representation of the new {@code BigInteger}.
-     * @param radix the base to be used for the conversion.
-     * @throws NullPointerException if {@code value == null}.
-     * @throws NumberFormatException if {@code value} is not a valid
-     *     representation of a {@code BigInteger} or if {@code radix <
-     *     Character.MIN_RADIX} or {@code radix > Character.MAX_RADIX}.
-     */
-    public BigInteger(@NonNull String value, int radix) {
-        if (value == null) {
-            throw new NullPointerException("value == null");
-        }
-        if (radix == 10) {
-            BigInt bigInt = new BigInt();
-            bigInt.putDecString(value);
-            setBigInt(bigInt);
-        } else if (radix == 16) {
-            BigInt bigInt = new BigInt();
-            bigInt.putHexString(value);
-            setBigInt(bigInt);
-        } else {
-            if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX) {
-                throw new NumberFormatException("Invalid radix: " + radix);
-            }
-            if (value.isEmpty()) {
-                throw new NumberFormatException("value.isEmpty()");
-            }
-            BigInteger.parseFromString(this, value, radix);
-        }
-    }
-
-    /**
-     * Constructs a new {@code BigInteger} instance with the given sign and
-     * magnitude.
-     *
-     * @param signum sign of the new {@code BigInteger} (-1 for negative, 0 for
-     *     zero, 1 for positive).
-     * @param magnitude magnitude of the new {@code BigInteger} with the most
-     *     significant byte first.
-     * @throws NullPointerException if {@code magnitude == null}.
-     * @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 @NonNull [] magnitude) {
-        if (magnitude == null) {
-            throw new NullPointerException("magnitude == null");
-        }
-        if (signum < -1 || signum > 1) {
-            throw new NumberFormatException("Invalid signum: " + signum);
-        }
-        if (signum == 0) {
-            for (byte element : magnitude) {
-                if (element != 0) {
-                    throw new NumberFormatException("signum-magnitude mismatch");
-                }
-            }
-        }
-        BigInt bigInt = new BigInt();
-        bigInt.putBigEndian(magnitude, signum < 0);
-        setBigInt(bigInt);
-    }
-
-    /**
-     * Constructs a new {@code BigInteger} from the given two's complement
-     * representation. The most significant byte is the entry at index 0. The
-     * most significant bit of this entry determines the sign of the new {@code
-     * BigInteger} instance. The array must be nonempty.
-     *
-     * @param value two's complement representation of the new {@code
-     *     BigInteger}.
-     * @throws NullPointerException if {@code value == null}.
-     * @throws NumberFormatException if the length of {@code value} is zero.
-     */
-    public BigInteger(byte @NonNull [] value) {
-        if (value.length == 0) {
-            throw new NumberFormatException("value.length == 0");
-        }
-        BigInt bigInt = new BigInt();
-        bigInt.putBigEndianTwosComplement(value);
-        setBigInt(bigInt);
-    }
-
-    /**
-     * Returns the internal native representation of this big integer, computing
-     * it if necessary.
-     */
-    BigInt getBigInt() {
-        if (nativeIsValid) {
-            return bigInt;
-        }
-
-        synchronized (this) {
-            if (nativeIsValid) {
-                return bigInt;
-            }
-            BigInt bigInt = new BigInt();
-            bigInt.putLittleEndianInts(digits, (sign < 0));
-            setBigInt(bigInt);
-            return bigInt;
-        }
-    }
-
-    private void setBigInt(BigInt bigInt) {
-        this.bigInt = bigInt;
-        this.nativeIsValid = true;
-    }
-
-    private void setJavaRepresentation(int sign, int numberLength, int[] digits) {
-        // decrement numberLength to drop leading zeroes...
-        while (numberLength > 0 && digits[--numberLength] == 0) {
-            ;
-        }
-        // ... and then increment it back because we always drop one too many
-        if (digits[numberLength++] == 0) {
-            sign = 0;
-        }
-        this.sign = sign;
-        this.digits = digits;
-        this.numberLength = numberLength;
-        this.javaIsValid = true;
-    }
-
-    void prepareJavaRepresentation() {
-        if (javaIsValid) {
-            return;
-        }
-
-        synchronized (this) {
-            if (javaIsValid) {
-                return;
-            }
-            int sign = bigInt.sign();
-            int[] digits = (sign != 0) ? bigInt.littleEndianIntsMagnitude() : new int[] { 0 };
-            setJavaRepresentation(sign, digits.length, digits);
-        }
-    }
-
-    /** Returns a {@code BigInteger} whose value is equal to {@code value}. */
-    @NonNull public static BigInteger valueOf(long value) {
-        if (value < 0) {
-            if (value != -1) {
-                return new BigInteger(-1, -value);
-            }
-            return MINUS_ONE;
-        } else if (value < SMALL_VALUES.length) {
-            return SMALL_VALUES[(int) value];
-        } else {// (value > 10)
-            return new BigInteger(1, value);
-        }
-    }
-
-    /**
-     * Returns the two's complement representation of this {@code BigInteger} in
-     * a byte array.
-     */
-    public byte @NonNull [] toByteArray() {
-        return twosComplement();
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is the absolute value of {@code
-     * this}.
-     */
-    @NonNull public BigInteger abs() {
-        BigInt bigInt = getBigInt();
-        if (bigInt.sign() >= 0) {
-            return this;
-        }
-        BigInt a = bigInt.copy();
-        a.setSign(1);
-        return new BigInteger(a);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is the {@code -this}.
-     */
-    @NonNull public BigInteger negate() {
-        BigInt bigInt = getBigInt();
-        int sign = bigInt.sign();
-        if (sign == 0) {
-            return this;
-        }
-        BigInt a = bigInt.copy();
-        a.setSign(-sign);
-        return new BigInteger(a);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this + value}.
-     */
-    @NonNull public BigInteger add(@NonNull BigInteger value) {
-        BigInt lhs = getBigInt();
-        BigInt rhs = value.getBigInt();
-        if (rhs.sign() == 0) {
-            return this;
-        }
-        if (lhs.sign() == 0) {
-            return value;
-        }
-        return new BigInteger(BigInt.addition(lhs, rhs));
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this - value}.
-     */
-    @NonNull public BigInteger subtract(@NonNull BigInteger value) {
-        BigInt lhs = getBigInt();
-        BigInt rhs = value.getBigInt();
-        if (rhs.sign() == 0) {
-            return this;
-        }
-        return new BigInteger(BigInt.subtraction(lhs, rhs));
-    }
-
-    /**
-     * Returns the sign of this {@code BigInteger}.
-     *
-     * @return {@code -1} if {@code this < 0}, {@code 0} if {@code this == 0},
-     *     {@code 1} if {@code this > 0}.
-     */
-    public int signum() {
-        if (javaIsValid) {
-            return sign;
-        }
-        return getBigInt().sign();
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this >> n}. For
-     * negative arguments, the result is also negative. The shift distance may
-     * be negative which means that {@code this} is shifted left.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method on negative values is
-     * not recommended as the current implementation is not efficient.
-     *
-     * @param n shift distance
-     * @return {@code this >> n} if {@code n >= 0}; {@code this << (-n)}
-     *     otherwise
-     */
-    @NonNull public BigInteger shiftRight(int n) {
-        return shiftLeft(-n);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this << n}. The
-     * result is equivalent to {@code this * pow(2, n)} if n >= 0. The shift
-     * distance may be negative which means that {@code this} is shifted right.
-     * The result then corresponds to {@code floor(this / pow(2, -n))}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method on negative values is
-     * not recommended as the current implementation is not efficient.
-     *
-     * @param n shift distance.
-     * @return {@code this << n} if {@code n >= 0}; {@code this >> (-n)}.
-     *     otherwise
-     */
-    @NonNull public BigInteger shiftLeft(int n) {
-        if (n == 0) {
-            return this;
-        }
-        int sign = signum();
-        if (sign == 0) {
-            return this;
-        }
-        if ((sign > 0) || (n >= 0)) {
-            return new BigInteger(BigInt.shift(getBigInt(), n));
-        } else {
-            // Negative numbers faking 2's complement:
-            // Not worth optimizing this:
-            // Sticking to Harmony Java implementation.
-            return BitLevel.shiftRight(this, -n);
-        }
-    }
-
-    BigInteger shiftLeftOneBit() {
-        return (signum() == 0) ? this : BitLevel.shiftLeftOneBit(this);
-    }
-
-    /**
-     * Returns the length of the value's two's complement representation without
-     * leading zeros for positive numbers / without leading ones for negative
-     * values.
-     *
-     * <p>The two's complement representation of {@code this} will be at least
-     * {@code bitLength() + 1} bits long.
-     *
-     * <p>The value will fit into an {@code int} if {@code bitLength() < 32} or
-     * into a {@code long} if {@code bitLength() < 64}.
-     *
-     * @return the length of the minimal two's complement representation for
-     *     {@code this} without the sign bit.
-     */
-    public int bitLength() {
-        // Optimization to avoid unnecessary duplicate representation:
-        if (!nativeIsValid && javaIsValid) {
-            return BitLevel.bitLength(this);
-        }
-        return getBigInt().bitLength();
-    }
-
-    /**
-     * Tests whether the bit at position n in {@code this} is set. The result is
-     * equivalent to {@code this & pow(2, n) != 0}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param n position where the bit in {@code this} has to be inspected.
-     * @throws ArithmeticException if {@code n < 0}.
-     */
-    public boolean testBit(int n) {
-        if (n < 0) {
-            throw new ArithmeticException("n < 0: " + n);
-        }
-        int sign = signum();
-        if (sign > 0 && nativeIsValid && !javaIsValid) {
-            return getBigInt().isBitSet(n);
-        } else {
-            // Negative numbers faking 2's complement:
-            // Not worth optimizing this:
-            // Sticking to Harmony Java implementation.
-            prepareJavaRepresentation();
-            if (n == 0) {
-                return ((digits[0] & 1) != 0);
-            }
-            int intCount = n >> 5;
-            if (intCount >= numberLength) {
-                return (sign < 0);
-            }
-            int digit = digits[intCount];
-            n = (1 << (n & 31)); // int with 1 set to the needed position
-            if (sign < 0) {
-                int firstNonZeroDigit = getFirstNonzeroDigit();
-                if (intCount < firstNonZeroDigit) {
-                    return false;
-                } else if (firstNonZeroDigit == intCount) {
-                    digit = -digit;
-                } else {
-                    digit = ~digit;
-                }
-            }
-            return ((digit & n) != 0);
-        }
-    }
-
-    /**
-     * Returns a {@code BigInteger} which has the same binary representation
-     * as {@code this} but with the bit at position n set. The result is
-     * equivalent to {@code this | pow(2, n)}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param n position where the bit in {@code this} has to be set.
-     * @throws ArithmeticException if {@code n < 0}.
-     */
-    @NonNull public BigInteger setBit(int n) {
-        prepareJavaRepresentation();
-        if (!testBit(n)) {
-            return BitLevel.flipBit(this, n);
-        } else {
-            return this;
-        }
-    }
-
-    /**
-     * Returns a {@code BigInteger} which has the same binary representation
-     * as {@code this} but with the bit at position n cleared. The result is
-     * equivalent to {@code this & ~pow(2, n)}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param n position where the bit in {@code this} has to be cleared.
-     * @throws ArithmeticException if {@code n < 0}.
-     */
-    @NonNull public BigInteger clearBit(int n) {
-        prepareJavaRepresentation();
-        if (testBit(n)) {
-            return BitLevel.flipBit(this, n);
-        } else {
-            return this;
-        }
-    }
-
-    /**
-     * Returns a {@code BigInteger} which has the same binary representation
-     * as {@code this} but with the bit at position n flipped. The result is
-     * equivalent to {@code this ^ pow(2, n)}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param n position where the bit in {@code this} has to be flipped.
-     * @throws ArithmeticException if {@code n < 0}.
-     */
-    @NonNull public BigInteger flipBit(int n) {
-        prepareJavaRepresentation();
-        if (n < 0) {
-            throw new ArithmeticException("n < 0: " + n);
-        }
-        return BitLevel.flipBit(this, n);
-    }
-
-    /**
-     * Returns the position of the lowest set bit in the two's complement
-     * representation of this {@code BigInteger}. If all bits are zero (this==0)
-     * then -1 is returned as result.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     */
-    public int getLowestSetBit() {
-        prepareJavaRepresentation();
-        if (sign == 0) {
-            return -1;
-        }
-        // (sign != 0) implies that exists some non zero digit
-        int i = getFirstNonzeroDigit();
-        return ((i << 5) + Integer.numberOfTrailingZeros(digits[i]));
-    }
-
-    /**
-     * Returns the number of bits in the two's complement representation of
-     * {@code this} which differ from the sign bit. If {@code this} is negative,
-     * the result is equivalent to the number of bits set in the two's
-     * complement representation of {@code -this - 1}.
-     *
-     * <p>Use {@code bitLength(0)} to find the length of the binary value in
-     * bits.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     */
-    public int bitCount() {
-        prepareJavaRepresentation();
-        return BitLevel.bitCount(this);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code ~this}. The result
-     * of this operation is {@code -this-1}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     */
-    @NonNull public BigInteger not() {
-        this.prepareJavaRepresentation();
-        return Logical.not(this);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this & value}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended
-     * as the current implementation is not efficient.
-     *
-     * @param value value to be and'ed with {@code this}.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger and(@NonNull BigInteger value) {
-        this.prepareJavaRepresentation();
-        value.prepareJavaRepresentation();
-        return Logical.and(this, value);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this | value}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param value value to be or'ed with {@code this}.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger or(@NonNull BigInteger value) {
-        this.prepareJavaRepresentation();
-        value.prepareJavaRepresentation();
-        return Logical.or(this, value);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this ^ value}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended as
-     * the current implementation is not efficient.
-     *
-     * @param value value to be xor'ed with {@code this}
-     * @throws NullPointerException if {@code value == null}
-     */
-    @NonNull public BigInteger xor(@NonNull BigInteger value) {
-        this.prepareJavaRepresentation();
-        value.prepareJavaRepresentation();
-        return Logical.xor(this, value);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this & ~value}.
-     * Evaluating {@code x.andNot(value)} returns the same result as {@code
-     * x.and(value.not())}.
-     *
-     * <p><b>Implementation Note:</b> Usage of this method is not recommended
-     * as the current implementation is not efficient.
-     *
-     * @param value value to be not'ed and then and'ed with {@code this}.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger andNot(@NonNull BigInteger value) {
-        this.prepareJavaRepresentation();
-        value.prepareJavaRepresentation();
-        return Logical.andNot(this, value);
-    }
-
-    /**
-     * Returns this {@code BigInteger} as an int value. If {@code this} is too
-     * big to be represented as an int, then {@code this % (1 << 32)} is
-     * returned.
-     */
-    @Override
-    public int intValue() {
-        if (nativeIsValid && bigInt.twosCompFitsIntoBytes(4)) {
-            return (int) bigInt.longInt();
-        }
-        this.prepareJavaRepresentation();
-        return (sign * digits[0]);
-    }
-
-    /**
-     * Returns this {@code BigInteger} as a long value. If {@code this} is too
-     * big to be represented as a long, then {@code this % pow(2, 64)} is
-     * returned.
-     */
-    @Override
-    public long longValue() {
-        if (nativeIsValid && bigInt.twosCompFitsIntoBytes(8)) {
-            return bigInt.longInt();
-        }
-        prepareJavaRepresentation();
-        long value = numberLength > 1
-                ? ((long) digits[1]) << 32 | digits[0] & 0xFFFFFFFFL
-                : digits[0] & 0xFFFFFFFFL;
-        return sign * value;
-    }
-
-    /**
-     * Returns this {@code BigInteger} as a float. If {@code this} is too big to
-     * be represented as a float, then {@code Float.POSITIVE_INFINITY} or
-     * {@code Float.NEGATIVE_INFINITY} is returned. Note that not all integers
-     * in the range {@code [-Float.MAX_VALUE, Float.MAX_VALUE]} can be exactly
-     * represented as a float.
-     */
-    @Override
-    public float floatValue() {
-        return (float) doubleValue();
-    }
-
-    /**
-     * Returns this {@code BigInteger} as a double. If {@code this} is too big
-     * to be represented as a double, then {@code Double.POSITIVE_INFINITY} or
-     * {@code Double.NEGATIVE_INFINITY} is returned. Note that not all integers
-     * in the range {@code [-Double.MAX_VALUE, Double.MAX_VALUE]} can be exactly
-     * represented as a double.
-     */
-    @Override
-    public double doubleValue() {
-        return Conversion.bigInteger2Double(this);
-    }
-
-    /**
-     * Compares this {@code BigInteger} with {@code value}. Returns {@code -1}
-     * if {@code this < value}, {@code 0} if {@code this == value} and {@code 1}
-     * if {@code this > value}, .
-     *
-     * @param value value to be compared with {@code this}.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    public int compareTo(@NonNull BigInteger value) {
-        return BigInt.cmp(getBigInt(), value.getBigInt());
-    }
-
-    /**
-     * Returns the minimum of this {@code BigInteger} and {@code value}.
-     *
-     * @param value value to be used to compute the minimum with {@code this}.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger min(@NonNull BigInteger value) {
-        return this.compareTo(value) == -1 ? this : value;
-    }
-
-    /**
-     * Returns the maximum of this {@code BigInteger} and {@code value}.
-     *
-     * @param value value to be used to compute the maximum with {@code this}
-     * @throws NullPointerException if {@code value == null}
-     */
-    @NonNull public BigInteger max(@NonNull BigInteger value) {
-        return this.compareTo(value) == 1 ? this : value;
-    }
-
-    @Override
-    public int hashCode() {
-        if (hashCode == 0) {
-            prepareJavaRepresentation();
-            int hash = 0;
-            for (int i = 0; i < numberLength; ++i) {
-                hash = hash * 33 + digits[i];
-            }
-            hashCode = hash * sign;
-        }
-        return hashCode;
-    }
-
-    @Override
-    public boolean equals(@Nullable Object x) {
-        if (this == x) {
-            return true;
-        }
-        if (x instanceof BigInteger) {
-            return this.compareTo((BigInteger) x) == 0;
-        }
-        return false;
-    }
-
-    /**
-     * Returns a string representation of this {@code BigInteger} in decimal
-     * form.
-     */
-    @Override
-    @NonNull public String toString() {
-        return getBigInt().decString();
-    }
-
-    /**
-     * Returns a string containing a string representation of this {@code
-     * BigInteger} with base radix. If {@code radix < Character.MIN_RADIX} or
-     * {@code radix > Character.MAX_RADIX} then a decimal representation is
-     * returned. The characters of the string representation are generated with
-     * method {@code Character.forDigit}.
-     *
-     * @param radix base to be used for the string representation.
-     */
-    @NonNull public String toString(int radix) {
-        if (radix == 10) {
-            return getBigInt().decString();
-        } else {
-            prepareJavaRepresentation();
-            return Conversion.bigInteger2String(this, radix);
-        }
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is greatest common divisor
-     * of {@code this} and {@code value}. If {@code this == 0} and {@code
-     * value == 0} then zero is returned, otherwise the result is positive.
-     *
-     * @param value value with which the greatest common divisor is computed.
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger gcd(@NonNull BigInteger value) {
-        // First optimize the case in which the two arguments have very different
-        // length.
-        int thisLen = bitLength();
-        int valueLen = value.bitLength();
-        final int gcdDirectRatio = 16;
-        if (thisLen > gcdDirectRatio * valueLen) {
-            // A division-based step reduces the length of this by a factor of at
-            // least gcdDirectRatio, thus ensuring that a division-based step will
-            // easily pay for itself.
-            if (value.signum() == 0) {
-                return this.abs();
-            }
-            return value.gcd(this.mod(value.abs()));
-        } else if (valueLen > gcdDirectRatio * thisLen) {
-            if (signum() == 0) {
-                return value.abs();
-            }
-            return this.gcd(value.mod(this.abs()));
-        }
-
-        return new BigInteger(BigInt.gcd(getBigInt(), value.getBigInt()));
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this * value}.
-     *
-     * @throws NullPointerException if {@code value == null}.
-     */
-    @NonNull public BigInteger multiply(@NonNull BigInteger value) {
-        return new BigInteger(BigInt.product(getBigInt(), value.getBigInt()));
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code pow(this, exp)}.
-     *
-     * @throws ArithmeticException if {@code exp < 0}.
-     */
-    @NonNull public BigInteger pow(int exp) {
-        if (exp < 0) {
-            throw new ArithmeticException("exp < 0: " + exp);
-        }
-        return new BigInteger(BigInt.exp(getBigInt(), exp));
-    }
-
-    /**
-     * Returns a two element {@code BigInteger} array containing
-     * {@code this / divisor} at index 0 and {@code this % divisor} at index 1.
-     *
-     * @param divisor value by which {@code this} is divided.
-     * @throws NullPointerException if {@code divisor == null}.
-     * @throws ArithmeticException if {@code divisor == 0}.
-     * @see #divide
-     * @see #remainder
-     */
-    public @NonNull BigInteger @NonNull [] divideAndRemainder(@NonNull BigInteger divisor) {
-        BigInt divisorBigInt = divisor.getBigInt();
-        BigInt quotient = new BigInt();
-        BigInt remainder = new BigInt();
-        BigInt.division(getBigInt(), divisorBigInt, quotient, remainder);
-        return new BigInteger[] {new BigInteger(quotient), new BigInteger(remainder) };
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this / divisor}.
-     *
-     * @param divisor value by which {@code this} is divided.
-     * @return {@code this / divisor}.
-     * @throws NullPointerException if {@code divisor == null}.
-     * @throws ArithmeticException if {@code divisor == 0}.
-     */
-    @NonNull public BigInteger divide(@NonNull BigInteger divisor) {
-        BigInt quotient = new BigInt();
-        BigInt.division(getBigInt(), divisor.getBigInt(), quotient, null);
-        return new BigInteger(quotient);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this % divisor}.
-     * Regarding signs this methods has the same behavior as the % operator on
-     * ints: the sign of the remainder is the same as the sign of this.
-     *
-     * @param divisor value by which {@code this} is divided.
-     * @throws NullPointerException if {@code divisor == null}.
-     * @throws ArithmeticException if {@code divisor == 0}.
-     */
-    @NonNull public BigInteger remainder(@NonNull BigInteger divisor) {
-        BigInt remainder = new BigInt();
-        BigInt.division(getBigInt(), divisor.getBigInt(), null, remainder);
-        return new BigInteger(remainder);
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code 1/this mod m}. The
-     * modulus {@code m} must be positive. The result is guaranteed to be in the
-     * interval {@code [0, m)} (0 inclusive, m exclusive). If {@code this} is
-     * not relatively prime to m, then an exception is thrown.
-     *
-     * @param m the modulus.
-     * @throws NullPointerException if {@code m == null}
-     * @throws ArithmeticException if {@code m < 0 or} if {@code this} is not
-     *     relatively prime to {@code m}
-     */
-    @NonNull public BigInteger modInverse(@NonNull BigInteger m) {
-        if (m.signum() <= 0) {
-            throw new ArithmeticException("modulus not positive");
-        }
-        return new BigInteger(BigInt.modInverse(getBigInt(), m.getBigInt()));
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code
-     * pow(this, exponent) mod modulus}. The modulus must be positive. The
-     * result is guaranteed to be in the interval {@code [0, modulus)}.
-     * If the exponent is negative, then
-     * {@code pow(this.modInverse(modulus), -exponent) mod modulus} is computed.
-     * The inverse of this only exists if {@code this} is relatively prime to the modulus,
-     * otherwise an exception is thrown.
-     *
-     * @throws NullPointerException if {@code modulus == null} or {@code exponent == null}.
-     * @throws ArithmeticException if {@code modulus < 0} or if {@code exponent < 0} and
-     *     not relatively prime to {@code modulus}.
-     */
-    @NonNull public BigInteger modPow(@NonNull BigInteger exponent, @NonNull BigInteger modulus) {
-        if (modulus.signum() <= 0) {
-            throw new ArithmeticException("modulus.signum() <= 0");
-        }
-        int exponentSignum = exponent.signum();
-        if (exponentSignum == 0) { // OpenSSL gets this case wrong; http://b/8574367.
-            return ONE.mod(modulus);
-        }
-        BigInteger base = exponentSignum < 0 ? modInverse(modulus) : this;
-        return new BigInteger(BigInt.modExp(base.getBigInt(), exponent.getBigInt(), modulus.getBigInt()));
-    }
-
-    /**
-     * Returns a {@code BigInteger} whose value is {@code this mod m}. The
-     * modulus {@code m} must be positive. The result is guaranteed to be in the
-     * interval {@code [0, m)} (0 inclusive, m exclusive). The behavior of this
-     * function is not equivalent to the behavior of the % operator defined for
-     * the built-in {@code int}'s.
-     *
-     * @param m the modulus.
-     * @return {@code this mod m}.
-     * @throws NullPointerException if {@code m == null}.
-     * @throws ArithmeticException if {@code m < 0}.
-     */
-    @NonNull public BigInteger mod(@NonNull BigInteger m) {
-        if (m.signum() <= 0) {
-            throw new ArithmeticException("m.signum() <= 0");
-        }
-        return new BigInteger(BigInt.modulus(getBigInt(), m.getBigInt()));
-    }
-
-    /**
-     * Tests whether this {@code BigInteger} is probably prime. If {@code true}
-     * is returned, then this is prime with a probability greater than
-     * {@code 1 - 1/2<sup>certainty</sup>)}. If {@code false} is returned, then this
-     * is definitely composite. If the argument {@code certainty} <= 0, then
-     * this method returns true.
-     *
-     * @param certainty tolerated primality uncertainty.
-     * @return {@code true}, if {@code this} is probably prime, {@code false}
-     *     otherwise.
-     */
-    public boolean isProbablePrime(int certainty) {
-        if (certainty <= 0) {
-            return true;
-        }
-        return getBigInt().isPrime(certainty);
-    }
-
-    /**
-     * Returns the smallest integer x > {@code this} which is probably prime as
-     * a {@code BigInteger} instance. The probability that the returned {@code
-     * BigInteger} is prime is greater than {@code 1 - 1/2<sup>100</sup>}.
-     *
-     * @return smallest integer > {@code this} which is probably prime.
-     * @throws ArithmeticException if {@code this < 0}.
-     */
-    @NonNull public BigInteger nextProbablePrime() {
-        if (sign < 0) {
-            throw new ArithmeticException("sign < 0");
-        }
-        return Primality.nextProbablePrime(this);
-    }
-
-    /**
-     * Returns a random positive {@code BigInteger} instance in the range {@code
-     * [0, pow(2, bitLength)-1]} which is probably prime. The probability that
-     * the returned {@code BigInteger} is prime is greater than {@code 1 - 1/2<sup>100</sup>)}.
-     *
-     * @param bitLength length of the new {@code BigInteger} in bits.
-     * @return probably prime random {@code BigInteger} instance.
-     * @throws IllegalArgumentException if {@code bitLength < 2}.
-     */
-    @NonNull public static BigInteger probablePrime(int bitLength, @NonNull Random random) {
-        return new BigInteger(bitLength, 100, random);
-    }
-
-    /* Private Methods */
-
-    /**
-     * Returns the two's complement representation of this BigInteger in a byte
-     * array.
-     */
-    private byte[] twosComplement() {
-        prepareJavaRepresentation();
-        if (this.sign == 0) {
-            return new byte[] { 0 };
-        }
-        BigInteger temp = this;
-        int bitLen = bitLength();
-        int iThis = getFirstNonzeroDigit();
-        int bytesLen = (bitLen >> 3) + 1;
-        /* Puts the little-endian int array representing the magnitude
-         * of this BigInteger into the big-endian byte array. */
-        byte[] bytes = new byte[bytesLen];
-        int firstByteNumber = 0;
-        int highBytes;
-        int bytesInInteger = 4;
-        int hB;
-
-        if (bytesLen - (numberLength << 2) == 1) {
-            bytes[0] = (byte) ((sign < 0) ? -1 : 0);
-            highBytes = 4;
-            firstByteNumber++;
-        } else {
-            hB = bytesLen & 3;
-            highBytes = (hB == 0) ? 4 : hB;
-        }
-
-        int digitIndex = iThis;
-        bytesLen -= iThis << 2;
-
-        if (sign < 0) {
-            int digit = -temp.digits[digitIndex];
-            digitIndex++;
-            if (digitIndex == numberLength) {
-                bytesInInteger = highBytes;
-            }
-            for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
-                bytes[--bytesLen] = (byte) digit;
-            }
-            while (bytesLen > firstByteNumber) {
-                digit = ~temp.digits[digitIndex];
-                digitIndex++;
-                if (digitIndex == numberLength) {
-                    bytesInInteger = highBytes;
-                }
-                for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
-                    bytes[--bytesLen] = (byte) digit;
-                }
-            }
-        } else {
-            while (bytesLen > firstByteNumber) {
-                int digit = temp.digits[digitIndex];
-                digitIndex++;
-                if (digitIndex == numberLength) {
-                    bytesInInteger = highBytes;
-                }
-                for (int i = 0; i < bytesInInteger; i++, digit >>= 8) {
-                    bytes[--bytesLen] = (byte) digit;
-                }
-            }
-        }
-        return bytes;
-    }
-
-
-    static int multiplyByInt(int[] res, int[] a, int aSize, int factor) {
-        long carry = 0;
-
-        for (int i = 0; i < aSize; i++) {
-            carry += (a[i] & 0xFFFFFFFFL) * (factor & 0xFFFFFFFFL);
-            res[i] = (int) carry;
-            carry >>>= 32;
-        }
-        return (int) carry;
-    }
-
-    static int inplaceAdd(int[] a, int aSize, int addend) {
-        long carry = addend & 0xFFFFFFFFL;
-
-        for (int i = 0; (carry != 0) && (i < aSize); i++) {
-            carry += a[i] & 0xFFFFFFFFL;
-            a[i] = (int) carry;
-            carry >>= 32;
-        }
-        return (int) carry;
-    }
-
-    /** @see BigInteger#BigInteger(String, int) */
-    private static void parseFromString(BigInteger bi, String value, int radix) {
-        int stringLength = value.length();
-        int endChar = stringLength;
-
-        int sign;
-        int startChar;
-        if (value.charAt(0) == '-') {
-            sign = -1;
-            startChar = 1;
-            stringLength--;
-        } else {
-            sign = 1;
-            startChar = 0;
-        }
-
-        /*
-         * We use the following algorithm: split a string into portions of n
-         * characters and convert each portion to an integer according to the
-         * radix. Then convert an pow(radix, n) based number to binary using the
-         * multiplication method. See D. Knuth, The Art of Computer Programming,
-         * vol. 2.
-         */
-
-        int charsPerInt = Conversion.digitFitInInt[radix];
-        int bigRadixDigitsLength = stringLength / charsPerInt;
-        int topChars = stringLength % charsPerInt;
-
-        if (topChars != 0) {
-            bigRadixDigitsLength++;
-        }
-        int[] digits = new int[bigRadixDigitsLength];
-        // Get the maximal power of radix that fits in int
-        int bigRadix = Conversion.bigRadices[radix - 2];
-        // Parse an input string and accumulate the BigInteger's magnitude
-        int digitIndex = 0; // index of digits array
-        int substrEnd = startChar + ((topChars == 0) ? charsPerInt : topChars);
-
-        for (int substrStart = startChar; substrStart < endChar;
-                substrStart = substrEnd, substrEnd = substrStart + charsPerInt) {
-            int bigRadixDigit = Integer.parseInt(value.substring(substrStart, substrEnd), radix);
-            int newDigit = multiplyByInt(digits, digits, digitIndex, bigRadix);
-            newDigit += inplaceAdd(digits, digitIndex, bigRadixDigit);
-            digits[digitIndex++] = newDigit;
-        }
-        int numberLength = digitIndex;
-        bi.setJavaRepresentation(sign, numberLength, digits);
-    }
-
-    int getFirstNonzeroDigit() {
-        if (firstNonzeroDigit == -2) {
-            int i;
-            if (this.sign == 0) {
-                i = -1;
-            } else {
-                for (i = 0; digits[i] == 0; i++) {
-                    ;
-                }
-            }
-            firstNonzeroDigit = i;
-        }
-        return firstNonzeroDigit;
-    }
-
-    /**
-     * Returns a copy of the current instance to achieve immutability
-     */
-    BigInteger copy() {
-        prepareJavaRepresentation();
-        int[] copyDigits = new int[numberLength];
-        System.arraycopy(digits, 0, copyDigits, 0, numberLength);
-        return new BigInteger(sign, numberLength, copyDigits);
-    }
-
-    /**
-     * Assigns all transient fields upon deserialization of a {@code BigInteger}
-     * instance.
-     */
-    private void readObject(ObjectInputStream in)
-            throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        BigInt bigInt = new BigInt();
-        bigInt.putBigEndian(magnitude, signum < 0);
-        setBigInt(bigInt);
-    }
-
-    /**
-     * Prepares this {@code BigInteger} for serialization, i.e. the
-     * non-transient fields {@code signum} and {@code magnitude} are assigned.
-     */
-    private void writeObject(ObjectOutputStream out) throws IOException {
-        BigInt bigInt = getBigInt();
-        signum = bigInt.sign();
-        magnitude = bigInt.bigEndianMagnitude();
-        out.defaultWriteObject();
-    }
-}
diff --git a/luni/src/main/java/java/math/BitLevel.java b/luni/src/main/java/java/math/BitLevel.java
deleted file mode 100644
index 91f7a9b..0000000
--- a/luni/src/main/java/java/math/BitLevel.java
+++ /dev/null
@@ -1,255 +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 java.math;
-
-/**
- * Static library that provides all the <b>bit level</b> operations for
- * {@link BigInteger}. The operations are:
- * <ul type="circle">
- * <li>Left Shifting</li>
- * <li>Right Shifting</li>
- * <li>Bit clearing</li>
- * <li>Bit setting</li>
- * <li>Bit counting</li>
- * <li>Bit testing</li>
- * <li>Getting of the lowest bit set</li>
- * </ul>
- * All operations are provided in immutable way, and some in both mutable and
- * immutable.
- */
-class BitLevel {
-
-    /** Just to denote that this class can't be instantiated. */
-    private BitLevel() {}
-
-    /** @see BigInteger#bitLength() */
-    static int bitLength(BigInteger val) {
-        val.prepareJavaRepresentation();
-        if (val.sign == 0) {
-            return 0;
-        }
-        int bLength = (val.numberLength << 5);
-        int highDigit = val.digits[val.numberLength - 1];
-
-        if (val.sign < 0) {
-            int i = val.getFirstNonzeroDigit();
-            // We reduce the problem to the positive case.
-            if (i == val.numberLength - 1) {
-                highDigit--;
-            }
-        }
-        // Subtracting all sign bits
-        bLength -= Integer.numberOfLeadingZeros(highDigit);
-        return bLength;
-    }
-
-    /** @see BigInteger#bitCount() */
-    static int bitCount(BigInteger val) {
-        val.prepareJavaRepresentation();
-        int bCount = 0;
-
-        if (val.sign == 0) {
-            return 0;
-        }
-
-        int i = val.getFirstNonzeroDigit();
-        if (val.sign > 0) {
-            for ( ; i < val.numberLength; i++) {
-                bCount += Integer.bitCount(val.digits[i]);
-            }
-        } else {// (sign < 0)
-            // this digit absorbs the carry
-            bCount += Integer.bitCount(-val.digits[i]);
-            for (i++; i < val.numberLength; i++) {
-                bCount += Integer.bitCount(~val.digits[i]);
-            }
-            // We take the complement sum:
-            bCount = (val.numberLength << 5) - bCount;
-        }
-        return bCount;
-    }
-
-    /**
-     * Performs a fast bit testing for positive numbers. The bit to to be tested
-     * must be in the range {@code [0, val.bitLength()-1]}
-     */
-    static boolean testBit(BigInteger val, int n) {
-        val.prepareJavaRepresentation();
-        // PRE: 0 <= n < val.bitLength()
-        return ((val.digits[n >> 5] & (1 << (n & 31))) != 0);
-    }
-
-    /**
-     * Check if there are 1s in the lowest bits of this BigInteger
-     *
-     * @param numberOfBits the number of the lowest bits to check
-     * @return false if all bits are 0s, true otherwise
-     */
-    static boolean nonZeroDroppedBits(int numberOfBits, int[] digits) {
-        int intCount = numberOfBits >> 5;
-        int bitCount = numberOfBits & 31;
-        int i;
-
-        for (i = 0; (i < intCount) && (digits[i] == 0); i++) {
-            ;
-        }
-        return ((i != intCount) || (digits[i] << (32 - bitCount) != 0));
-    }
-
-    static void shiftLeftOneBit(int[] result, int[] source, int srcLen) {
-        int carry = 0;
-        for (int i = 0; i < srcLen; i++) {
-            int val = source[i];
-            result[i] = (val << 1) | carry;
-            carry = val >>> 31;
-        }
-        if(carry != 0) {
-            result[srcLen] = carry;
-        }
-    }
-
-    static BigInteger shiftLeftOneBit(BigInteger source) {
-        source.prepareJavaRepresentation();
-        int srcLen = source.numberLength;
-        int resLen = srcLen + 1;
-        int[] resDigits = new int[resLen];
-        shiftLeftOneBit(resDigits, source.digits, srcLen);
-        return new BigInteger(source.sign, resLen, resDigits);
-    }
-
-    /** @see BigInteger#shiftRight(int) */
-    static BigInteger shiftRight(BigInteger source, int count) {
-        source.prepareJavaRepresentation();
-        int intCount = count >> 5; // count of integers
-        count &= 31; // count of remaining bits
-        if (intCount >= source.numberLength) {
-            return ((source.sign < 0) ? BigInteger.MINUS_ONE : BigInteger.ZERO);
-        }
-        int i;
-        int resLength = source.numberLength - intCount;
-        int[] resDigits = new int[resLength + 1];
-
-        shiftRight(resDigits, resLength, source.digits, intCount, count);
-        if (source.sign < 0) {
-            // Checking if the dropped bits are zeros (the remainder equals to
-            // 0)
-            for (i = 0; (i < intCount) && (source.digits[i] == 0); i++) {
-                ;
-            }
-            // If the remainder is not zero, add 1 to the result
-            if ((i < intCount)
-                    || ((count > 0) && ((source.digits[i] << (32 - count)) != 0))) {
-                for (i = 0; (i < resLength) && (resDigits[i] == -1); i++) {
-                    resDigits[i] = 0;
-                }
-                if (i == resLength) {
-                    resLength++;
-                }
-                resDigits[i]++;
-            }
-        }
-        return new BigInteger(source.sign, resLength, resDigits);
-    }
-
-    /**
-     * Shifts right an array of integers. Total shift distance in bits is
-     * intCount * 32 + count.
-     *
-     * @param result
-     *            the destination array
-     * @param resultLen
-     *            the destination array's length
-     * @param source
-     *            the source array
-     * @param intCount
-     *            the number of elements to be shifted
-     * @param count
-     *            the number of bits to be shifted
-     * @return dropped bit's are all zero (i.e. remaider is zero)
-     */
-    static boolean shiftRight(int[] result, int resultLen, int[] source, int intCount, int count) {
-        int i;
-        boolean allZero = true;
-        for (i = 0; i < intCount; i++)
-            allZero &= source[i] == 0;
-        if (count == 0) {
-            System.arraycopy(source, intCount, result, 0, resultLen);
-            i = resultLen;
-        } else {
-            int leftShiftCount = 32 - count;
-
-            allZero &= ( source[i] << leftShiftCount ) == 0;
-            for (i = 0; i < resultLen - 1; i++) {
-                result[i] = ( source[i + intCount] >>> count )
-                | ( source[i + intCount + 1] << leftShiftCount );
-            }
-            result[i] = ( source[i + intCount] >>> count );
-            i++;
-        }
-
-        return allZero;
-    }
-
-
-    /**
-     * Performs a flipBit on the BigInteger, returning a BigInteger with the the
-     * specified bit flipped.
-     */
-    static BigInteger flipBit(BigInteger val, int n){
-        val.prepareJavaRepresentation();
-        int resSign = (val.sign == 0) ? 1 : val.sign;
-        int intCount = n >> 5;
-        int bitN = n & 31;
-        int resLength = Math.max(intCount + 1, val.numberLength) + 1;
-        int[] resDigits = new int[resLength];
-        int i;
-
-        int bitNumber = 1 << bitN;
-        System.arraycopy(val.digits, 0, resDigits, 0, val.numberLength);
-
-        if (val.sign < 0) {
-            if (intCount >= val.numberLength) {
-                resDigits[intCount] = bitNumber;
-            } else {
-                //val.sign<0 y intCount < val.numberLength
-                int firstNonZeroDigit = val.getFirstNonzeroDigit();
-                if (intCount > firstNonZeroDigit) {
-                    resDigits[intCount] ^= bitNumber;
-                } else if (intCount < firstNonZeroDigit) {
-                    resDigits[intCount] = -bitNumber;
-                    for (i=intCount + 1; i < firstNonZeroDigit; i++) {
-                        resDigits[i]=-1;
-                    }
-                    resDigits[i] = resDigits[i]--;
-                } else {
-                    i = intCount;
-                    resDigits[i] = -((-resDigits[intCount]) ^ bitNumber);
-                    if (resDigits[i] == 0) {
-                        for (i++; resDigits[i] == -1 ; i++) {
-                            resDigits[i] = 0;
-                        }
-                        resDigits[i]++;
-                    }
-                }
-            }
-        } else {//case where val is positive
-            resDigits[intCount] ^= bitNumber;
-        }
-        return new BigInteger(resSign, resLength, resDigits);
-    }
-}
diff --git a/luni/src/main/java/java/math/Conversion.java b/luni/src/main/java/java/math/Conversion.java
deleted file mode 100644
index 585fff4..0000000
--- a/luni/src/main/java/java/math/Conversion.java
+++ /dev/null
@@ -1,461 +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 java.math;
-
-/**
- * Static library that provides {@link BigInteger} base conversion from/to any
- * integer represented in an {@link java.lang.String} Object.
- */
-class Conversion {
-
-    /** Just to denote that this class can't be instantiated */
-    private Conversion() {}
-
-    /**
-     * Holds the maximal exponent for each radix, so that radix<sup>digitFitInInt[radix]</sup>
-     * fit in an {@code int} (32 bits).
-     */
-    static final int[] digitFitInInt = { -1, -1, 31, 19, 15, 13, 11,
-            11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
-            6, 6, 6, 6, 6, 6, 6, 5 };
-
-    /**
-     * bigRadices values are precomputed maximal powers of radices (integer
-     * numbers from 2 to 36) that fit into unsigned int (32 bits). bigRadices[0] =
-     * 2 ^ 31, bigRadices[8] = 10 ^ 9, etc.
-     */
-
-    static final int[] bigRadices = { -2147483648, 1162261467,
-            1073741824, 1220703125, 362797056, 1977326743, 1073741824,
-            387420489, 1000000000, 214358881, 429981696, 815730721, 1475789056,
-            170859375, 268435456, 410338673, 612220032, 893871739, 1280000000,
-            1801088541, 113379904, 148035889, 191102976, 244140625, 308915776,
-            387420489, 481890304, 594823321, 729000000, 887503681, 1073741824,
-            1291467969, 1544804416, 1838265625, 60466176 };
-
-
-    /** @see BigInteger#toString(int) */
-    static String bigInteger2String(BigInteger val, int radix) {
-        val.prepareJavaRepresentation();
-        int sign = val.sign;
-        int numberLength = val.numberLength;
-        int[] digits = val.digits;
-
-        if (sign == 0) {
-            return "0";
-        }
-        if (numberLength == 1) {
-            int highDigit = digits[numberLength - 1];
-            long v = highDigit & 0xFFFFFFFFL;
-            if (sign < 0) {
-                v = -v;
-            }
-            return Long.toString(v, radix);
-        }
-        if ((radix == 10) || (radix < Character.MIN_RADIX)
-                || (radix > Character.MAX_RADIX)) {
-            return val.toString();
-        }
-        double bitsForRadixDigit;
-        bitsForRadixDigit = Math.log(radix) / Math.log(2);
-        int resLengthInChars = (int) (val.abs().bitLength() / bitsForRadixDigit + ((sign < 0) ? 1
-                : 0)) + 1;
-
-        char[] result = new char[resLengthInChars];
-        int currentChar = resLengthInChars;
-        int resDigit;
-        if (radix != 16) {
-            int[] temp = new int[numberLength];
-            System.arraycopy(digits, 0, temp, 0, numberLength);
-            int tempLen = numberLength;
-            int charsPerInt = digitFitInInt[radix];
-            int i;
-            // get the maximal power of radix that fits in int
-            int bigRadix = bigRadices[radix - 2];
-            while (true) {
-                // divide the array of digits by bigRadix and convert remainders
-                // to characters collecting them in the char array
-                resDigit = Division.divideArrayByInt(temp, temp, tempLen,
-                        bigRadix);
-                int previous = currentChar;
-                do {
-                    result[--currentChar] = Character.forDigit(
-                            resDigit % radix, radix);
-                } while (((resDigit /= radix) != 0) && (currentChar != 0));
-                int delta = charsPerInt - previous + currentChar;
-                for (i = 0; i < delta && currentChar > 0; i++) {
-                    result[--currentChar] = '0';
-                }
-                for (i = tempLen - 1; (i > 0) && (temp[i] == 0); i--) {
-                    ;
-                }
-                tempLen = i + 1;
-                if ((tempLen == 1) && (temp[0] == 0)) { // the quotient is 0
-                    break;
-                }
-            }
-        } else {
-            // radix == 16
-            for (int i = 0; i < numberLength; i++) {
-                for (int j = 0; (j < 8) && (currentChar > 0); j++) {
-                    resDigit = digits[i] >> (j << 2) & 0xf;
-                    result[--currentChar] = Character.forDigit(resDigit, 16);
-                }
-            }
-        }
-        while (result[currentChar] == '0') {
-            currentChar++;
-        }
-        if (sign == -1) {
-            result[--currentChar] = '-';
-        }
-        return new String(result, currentChar, resLengthInChars - currentChar);
-    }
-
-    /**
-     * Builds the correspondent {@code String} representation of {@code val}
-     * being scaled by {@code scale}.
-     *
-     * @see BigInteger#toString()
-     * @see BigDecimal#toString()
-     */
-    static String toDecimalScaledString(BigInteger val, int scale) {
-        val.prepareJavaRepresentation();
-        int sign = val.sign;
-        int numberLength = val.numberLength;
-        int[] digits = val.digits;
-        int resLengthInChars;
-        int currentChar;
-        char[] result;
-
-        if (sign == 0) {
-            switch (scale) {
-                case 0:
-                    return "0";
-                case 1:
-                    return "0.0";
-                case 2:
-                    return "0.00";
-                case 3:
-                    return "0.000";
-                case 4:
-                    return "0.0000";
-                case 5:
-                    return "0.00000";
-                case 6:
-                    return "0.000000";
-                default:
-                    StringBuilder result1 = new StringBuilder();
-                    if (scale < 0) {
-                        result1.append("0E+");
-                    } else {
-                        result1.append("0E");
-                    }
-                    result1.append(-scale);
-                    return result1.toString();
-            }
-        }
-        // one 32-bit unsigned value may contains 10 decimal digits
-        resLengthInChars = numberLength * 10 + 1 + 7;
-        // Explanation why +1+7:
-        // +1 - one char for sign if needed.
-        // +7 - For "special case 2" (see below) we have 7 free chars for
-        // inserting necessary scaled digits.
-        result = new char[resLengthInChars + 1];
-        // allocated [resLengthInChars+1] characters.
-        // a free latest character may be used for "special case 1" (see
-        // below)
-        currentChar = resLengthInChars;
-        if (numberLength == 1) {
-            int highDigit = digits[0];
-            if (highDigit < 0) {
-                long v = highDigit & 0xFFFFFFFFL;
-                do {
-                    long prev = v;
-                    v /= 10;
-                    result[--currentChar] = (char) (0x0030 + ((int) (prev - v * 10)));
-                } while (v != 0);
-            } else {
-                int v = highDigit;
-                do {
-                    int prev = v;
-                    v /= 10;
-                    result[--currentChar] = (char) (0x0030 + (prev - v * 10));
-                } while (v != 0);
-            }
-        } else {
-            int[] temp = new int[numberLength];
-            int tempLen = numberLength;
-            System.arraycopy(digits, 0, temp, 0, tempLen);
-            BIG_LOOP: while (true) {
-                // divide the array of digits by bigRadix and convert
-                // remainders
-                // to characters collecting them in the char array
-                long result11 = 0;
-                for (int i1 = tempLen - 1; i1 >= 0; i1--) {
-                    long temp1 = (result11 << 32)
-                            + (temp[i1] & 0xFFFFFFFFL);
-                    long res = divideLongByBillion(temp1);
-                    temp[i1] = (int) res;
-                    result11 = (int) (res >> 32);
-                }
-                int resDigit = (int) result11;
-                int previous = currentChar;
-                do {
-                    result[--currentChar] = (char) (0x0030 + (resDigit % 10));
-                } while (((resDigit /= 10) != 0) && (currentChar != 0));
-                int delta = 9 - previous + currentChar;
-                for (int i = 0; (i < delta) && (currentChar > 0); i++) {
-                    result[--currentChar] = '0';
-                }
-                int j = tempLen - 1;
-                for (; temp[j] == 0; j--) {
-                    if (j == 0) { // means temp[0] == 0
-                        break BIG_LOOP;
-                    }
-                }
-                tempLen = j + 1;
-            }
-            while (result[currentChar] == '0') {
-                currentChar++;
-            }
-        }
-        boolean negNumber = (sign < 0);
-        int exponent = resLengthInChars - currentChar - scale - 1;
-        if (scale == 0) {
-            if (negNumber) {
-                result[--currentChar] = '-';
-            }
-            return new String(result, currentChar, resLengthInChars
-                    - currentChar);
-        }
-        if ((scale > 0) && (exponent >= -6)) {
-            if (exponent >= 0) {
-                // special case 1
-                int insertPoint = currentChar + exponent;
-                for (int j = resLengthInChars - 1; j >= insertPoint; j--) {
-                    result[j + 1] = result[j];
-                }
-                result[++insertPoint] = '.';
-                if (negNumber) {
-                    result[--currentChar] = '-';
-                }
-                return new String(result, currentChar, resLengthInChars
-                        - currentChar + 1);
-            }
-            // special case 2
-            for (int j = 2; j < -exponent + 1; j++) {
-                result[--currentChar] = '0';
-            }
-            result[--currentChar] = '.';
-            result[--currentChar] = '0';
-            if (negNumber) {
-                result[--currentChar] = '-';
-            }
-            return new String(result, currentChar, resLengthInChars
-                    - currentChar);
-        }
-        int startPoint = currentChar + 1;
-        int endPoint = resLengthInChars;
-        StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
-        if (negNumber) {
-            result1.append('-');
-        }
-        if (endPoint - startPoint >= 1) {
-            result1.append(result[currentChar]);
-            result1.append('.');
-            result1.append(result, currentChar + 1, resLengthInChars
-                    - currentChar - 1);
-        } else {
-            result1.append(result, currentChar, resLengthInChars
-                    - currentChar);
-        }
-        result1.append('E');
-        if (exponent > 0) {
-            result1.append('+');
-        }
-        result1.append(Integer.toString(exponent));
-        return result1.toString();
-    }
-
-    /* can process only 32-bit numbers */
-    static String toDecimalScaledString(long value, int scale) {
-        int resLengthInChars;
-        int currentChar;
-        char[] result;
-        boolean negNumber = value < 0;
-        if(negNumber) {
-            value = -value;
-        }
-        if (value == 0) {
-            switch (scale) {
-                case 0: return "0";
-                case 1: return "0.0";
-                case 2: return "0.00";
-                case 3: return "0.000";
-                case 4: return "0.0000";
-                case 5: return "0.00000";
-                case 6: return "0.000000";
-                default:
-                    StringBuilder result1 = new StringBuilder();
-                    if (scale  < 0) {
-                        result1.append("0E+");
-                    } else {
-                        result1.append("0E");
-                    }
-                    result1.append( (scale == Integer.MIN_VALUE) ? "2147483648" : Integer.toString(-scale));
-                    return result1.toString();
-            }
-        }
-        // one 32-bit unsigned value may contains 10 decimal digits
-        resLengthInChars = 18;
-        // Explanation why +1+7:
-        // +1 - one char for sign if needed.
-        // +7 - For "special case 2" (see below) we have 7 free chars for
-        //  inserting necessary scaled digits.
-        result = new char[resLengthInChars+1];
-        //  Allocated [resLengthInChars+1] characters.
-        // a free latest character may be used for "special case 1" (see below)
-        currentChar = resLengthInChars;
-        long v = value;
-        do {
-            long prev = v;
-            v /= 10;
-            result[--currentChar] = (char) (0x0030 + (prev - v * 10));
-        } while (v != 0);
-
-        long exponent = (long)resLengthInChars - (long)currentChar - scale - 1L;
-        if (scale == 0) {
-            if (negNumber) {
-                result[--currentChar] = '-';
-            }
-            return new String(result, currentChar, resLengthInChars - currentChar);
-        }
-        if (scale > 0 && exponent >= -6) {
-            if (exponent >= 0) {
-                // special case 1
-                int insertPoint = currentChar + (int) exponent ;
-                for (int j=resLengthInChars-1; j>=insertPoint; j--) {
-                    result[j+1] = result[j];
-                }
-                result[++insertPoint]='.';
-                if (negNumber) {
-                    result[--currentChar] = '-';
-                }
-                return new String(result, currentChar, resLengthInChars - currentChar + 1);
-            }
-            // special case 2
-            for (int j = 2; j < -exponent + 1; j++) {
-                result[--currentChar] = '0';
-            }
-            result[--currentChar] = '.';
-            result[--currentChar] = '0';
-            if (negNumber) {
-                result[--currentChar] = '-';
-            }
-            return new String(result, currentChar, resLengthInChars - currentChar);
-        }
-        int startPoint = currentChar + 1;
-        int endPoint = resLengthInChars;
-        StringBuilder result1 = new StringBuilder(16 + endPoint - startPoint);
-        if (negNumber) {
-            result1.append('-');
-        }
-        if (endPoint - startPoint >= 1) {
-            result1.append(result[currentChar]);
-            result1.append('.');
-            result1.append(result,currentChar+1,resLengthInChars - currentChar-1);
-        } else {
-            result1.append(result,currentChar,resLengthInChars - currentChar);
-        }
-        result1.append('E');
-        if (exponent > 0) {
-            result1.append('+');
-        }
-        result1.append(Long.toString(exponent));
-        return result1.toString();
-    }
-
-    static long divideLongByBillion(long a) {
-        long quot;
-        long rem;
-
-        if (a >= 0) {
-            long bLong = 1000000000L;
-            quot = (a / bLong);
-            rem = (a % bLong);
-        } else {
-            /*
-             * Make the dividend positive shifting it right by 1 bit then get
-             * the quotient an remainder and correct them properly
-             */
-            long aPos = a >>> 1;
-            long bPos = 1000000000L >>> 1;
-            quot = aPos / bPos;
-            rem = aPos % bPos;
-            // double the remainder and add 1 if 'a' is odd
-            rem = (rem << 1) + (a & 1);
-        }
-        return ((rem << 32) | (quot & 0xFFFFFFFFL));
-    }
-
-    /** @see BigInteger#doubleValue() */
-    static double bigInteger2Double(BigInteger val) {
-        val.prepareJavaRepresentation();
-        // val.bitLength() < 64
-        if ((val.numberLength < 2)
-                || ((val.numberLength == 2) && (val.digits[1] > 0))) {
-            return val.longValue();
-        }
-        // val.bitLength() >= 33 * 32 > 1024
-        if (val.numberLength > 32) {
-            return ((val.sign > 0) ? Double.POSITIVE_INFINITY
-                    : Double.NEGATIVE_INFINITY);
-        }
-        int bitLen = val.abs().bitLength();
-        long exponent = bitLen - 1;
-        int delta = bitLen - 54;
-        // We need 54 top bits from this, the 53th bit is always 1 in lVal.
-        long lVal = val.abs().shiftRight(delta).longValue();
-        /*
-         * Take 53 bits from lVal to mantissa. The least significant bit is
-         * needed for rounding.
-         */
-        long mantissa = lVal & 0x1FFFFFFFFFFFFFL;
-        if (exponent == 1023) {
-            if (mantissa == 0X1FFFFFFFFFFFFFL) {
-                return ((val.sign > 0) ? Double.POSITIVE_INFINITY
-                        : Double.NEGATIVE_INFINITY);
-            }
-            if (mantissa == 0x1FFFFFFFFFFFFEL) {
-                return ((val.sign > 0) ? Double.MAX_VALUE : -Double.MAX_VALUE);
-            }
-        }
-        // Round the mantissa
-        if (((mantissa & 1) == 1)
-                && (((mantissa & 2) == 2) || BitLevel.nonZeroDroppedBits(delta,
-                        val.digits))) {
-            mantissa += 2;
-        }
-        mantissa >>= 1; // drop the rounding bit
-        long resSign = (val.sign < 0) ? 0x8000000000000000L : 0;
-        exponent = ((1023 + exponent) << 52) & 0x7FF0000000000000L;
-        long result = resSign | exponent | mantissa;
-        return Double.longBitsToDouble(result);
-    }
-}
diff --git a/luni/src/main/java/java/math/Division.java b/luni/src/main/java/java/math/Division.java
deleted file mode 100644
index d642783..0000000
--- a/luni/src/main/java/java/math/Division.java
+++ /dev/null
@@ -1,91 +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 java.math;
-
-/**
- * Static library that provides all operations related with division and modular
- * arithmetic to {@link BigInteger}. Some methods are provided in both mutable
- * and immutable way. There are several variants provided listed below:
- *
- * <ul type="circle">
- * <li> <b>Division</b>
- * <ul type="circle">
- * <li>{@link BigInteger} division and remainder by {@link BigInteger}.</li>
- * <li>{@link BigInteger} division and remainder by {@code int}.</li>
- * <li><i>gcd</i> between {@link BigInteger} numbers.</li>
- * </ul>
- * </li>
- * <li> <b>Modular arithmetic </b>
- * <ul type="circle">
- * <li>Modular exponentiation between {@link BigInteger} numbers.</li>
- * <li>Modular inverse of a {@link BigInteger} numbers.</li>
- * </ul>
- * </li>
- *</ul>
- */
-class Division {
-
-    /**
-     * Divides an array by an integer value. Implements the Knuth's division
-     * algorithm. See D. Knuth, The Art of Computer Programming, vol. 2.
-     *
-     * @return remainder
-     */
-    static int divideArrayByInt(int[] quotient, int[] dividend, final int dividendLength,
-            final int divisor) {
-
-        long rem = 0;
-        long bLong = divisor & 0xffffffffL;
-
-        for (int i = dividendLength - 1; i >= 0; i--) {
-            long temp = (rem << 32) | (dividend[i] & 0xffffffffL);
-            long quot;
-            if (temp >= 0) {
-                quot = (temp / bLong);
-                rem = (temp % bLong);
-            } else {
-                /*
-                 * make the dividend positive shifting it right by 1 bit then
-                 * get the quotient an remainder and correct them properly
-                 */
-                long aPos = temp >>> 1;
-                long bPos = divisor >>> 1;
-                quot = aPos / bPos;
-                rem = aPos % bPos;
-                // double the remainder and add 1 if a is odd
-                rem = (rem << 1) + (temp & 1);
-                if ((divisor & 1) != 0) {
-                    // the divisor is odd
-                    if (quot <= rem) {
-                        rem -= quot;
-                    } else {
-                        if (quot - rem <= bLong) {
-                            rem += bLong - quot;
-                            quot -= 1;
-                        } else {
-                            rem += (bLong << 1) - quot;
-                            quot -= 2;
-                        }
-                    }
-                }
-            }
-            quotient[i] = (int) (quot & 0xffffffffL);
-        }
-        return (int) rem;
-    }
-}
diff --git a/luni/src/main/java/java/math/Logical.java b/luni/src/main/java/java/math/Logical.java
deleted file mode 100644
index 9de0924..0000000
--- a/luni/src/main/java/java/math/Logical.java
+++ /dev/null
@@ -1,773 +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 java.math;
-
-/**
- * The library implements some logical operations over {@code BigInteger}. The
- * operations provided are listed below.
- * <ul type="circle">
- * <li>not</li>
- * <li>and</li>
- * <li>andNot</li>
- * <li>or</li>
- * <li>xor</li>
- * </ul>
- */
-class Logical {
-
-    /** Just to denote that this class can't be instantiated. */
-
-    private Logical() {}
-
-
-    /** @see BigInteger#not() */
-    static BigInteger not(BigInteger val) {
-        if (val.sign == 0) {
-            return BigInteger.MINUS_ONE;
-        }
-        if (val.equals(BigInteger.MINUS_ONE)) {
-            return BigInteger.ZERO;
-        }
-        int[] resDigits = new int[val.numberLength + 1];
-        int i;
-
-        if (val.sign > 0) {
-            // ~val = -val + 1
-            if (val.digits[val.numberLength - 1] != -1) {
-                for (i = 0; val.digits[i] == -1; i++) {
-                    ;
-                }
-            } else {
-                for (i = 0; (i < val.numberLength) && (val.digits[i] == -1); i++) {
-                    ;
-                }
-                if (i == val.numberLength) {
-                    resDigits[i] = 1;
-                    return new BigInteger(-val.sign, i + 1, resDigits);
-                }
-            }
-            // Here a carry 1 was generated
-        } else {// (val.sign < 0)
-            // ~val = -val - 1
-            for (i = 0; val.digits[i] == 0; i++) {
-                resDigits[i] = -1;
-            }
-            // Here a borrow -1 was generated
-        }
-        // Now, the carry/borrow can be absorbed
-        resDigits[i] = val.digits[i] + val.sign;
-        // Copying the remaining unchanged digit
-        for (i++; i < val.numberLength; i++) {
-            resDigits[i] = val.digits[i];
-        }
-        return new BigInteger(-val.sign, i, resDigits);
-    }
-
-    /** @see BigInteger#and(BigInteger) */
-    static BigInteger and(BigInteger val, BigInteger that) {
-        if (that.sign == 0 || val.sign == 0) {
-            return BigInteger.ZERO;
-        }
-        if (that.equals(BigInteger.MINUS_ONE)){
-            return val;
-        }
-        if (val.equals(BigInteger.MINUS_ONE)) {
-            return that;
-        }
-
-        if (val.sign > 0) {
-            if (that.sign > 0) {
-                return andPositive(val, that);
-            } else {
-                return andDiffSigns(val, that);
-            }
-        } else {
-            if (that.sign > 0) {
-                return andDiffSigns(that, val);
-            } else if (val.numberLength > that.numberLength) {
-                return andNegative(val, that);
-            } else {
-                return andNegative(that, val);
-            }
-        }
-    }
-
-    /** @return sign = 1, magnitude = val.magnitude & that.magnitude*/
-    static BigInteger andPositive(BigInteger val, BigInteger that) {
-        // PRE: both arguments are positive
-        int resLength = Math.min(val.numberLength, that.numberLength);
-        int i = Math.max(val.getFirstNonzeroDigit(), that.getFirstNonzeroDigit());
-
-        if (i >= resLength) {
-            return BigInteger.ZERO;
-        }
-
-        int[] resDigits = new int[resLength];
-        for ( ; i < resLength; i++) {
-            resDigits[i] = val.digits[i] & that.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = positive.magnitude & magnitude = -negative.magnitude */
-    static BigInteger andDiffSigns(BigInteger positive, BigInteger negative) {
-        // PRE: positive is positive and negative is negative
-        int iPos = positive.getFirstNonzeroDigit();
-        int iNeg = negative.getFirstNonzeroDigit();
-
-        // Look if the trailing zeros of the negative will "blank" all
-        // the positive digits
-        if (iNeg >= positive.numberLength) {
-            return BigInteger.ZERO;
-        }
-        int resLength = positive.numberLength;
-        int[] resDigits = new int[resLength];
-
-        // Must start from max(iPos, iNeg)
-        int i = Math.max(iPos, iNeg);
-        if (i == iNeg) {
-            resDigits[i] = -negative.digits[i] & positive.digits[i];
-            i++;
-        }
-        int limit = Math.min(negative.numberLength, positive.numberLength);
-        for ( ; i < limit; i++) {
-            resDigits[i] = ~negative.digits[i] & positive.digits[i];
-        }
-        // if the negative was shorter must copy the remaining digits
-        // from positive
-        if (i >= negative.numberLength) {
-            for ( ; i < positive.numberLength; i++) {
-                resDigits[i] = positive.digits[i];
-            }
-        } // else positive ended and must "copy" virtual 0's, do nothing then
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = -1, magnitude = -(-longer.magnitude & -shorter.magnitude)*/
-    static BigInteger andNegative(BigInteger longer, BigInteger shorter) {
-        // PRE: longer and shorter are negative
-        // PRE: longer has at least as many digits as shorter
-        int iLonger = longer.getFirstNonzeroDigit();
-        int iShorter = shorter.getFirstNonzeroDigit();
-
-        // Does shorter matter?
-        if (iLonger >= shorter.numberLength) {
-            return longer;
-        }
-
-        int resLength;
-        int[] resDigits;
-        int i = Math.max(iShorter, iLonger);
-        int digit;
-        if (iShorter > iLonger) {
-            digit = -shorter.digits[i] & ~longer.digits[i];
-        } else if (iShorter < iLonger) {
-            digit = ~shorter.digits[i] & -longer.digits[i];
-        } else {
-            digit = -shorter.digits[i] & -longer.digits[i];
-        }
-        if (digit == 0) {
-            for (i++; i < shorter.numberLength && (digit = ~(longer.digits[i] | shorter.digits[i])) == 0; i++)
-                ;  // digit = ~longer.digits[i] & ~shorter.digits[i]
-            if (digit == 0) {
-                // shorter has only the remaining virtual sign bits
-                for ( ; i < longer.numberLength && (digit = ~longer.digits[i]) == 0; i++)
-                    ;
-                if (digit == 0) {
-                    resLength = longer.numberLength + 1;
-                    resDigits = new int[resLength];
-                    resDigits[resLength - 1] = 1;
-
-                    return new BigInteger(-1, resLength, resDigits);
-                }
-            }
-        }
-        resLength = longer.numberLength;
-                resDigits = new int[resLength];
-        resDigits[i] = -digit;
-        for (i++; i < shorter.numberLength; i++){
-            // resDigits[i] = ~(~longer.digits[i] & ~shorter.digits[i];)
-            resDigits[i] = longer.digits[i] | shorter.digits[i];
-        }
-        // shorter has only the remaining virtual sign bits
-        for ( ; i < longer.numberLength; i++){
-            resDigits[i] = longer.digits[i];
-        }
-
-        return new BigInteger(-1, resLength, resDigits);
-    }
-
-    /** @see BigInteger#andNot(BigInteger) */
-    static BigInteger andNot(BigInteger val, BigInteger that) {
-        if (that.sign == 0 ) {
-            return val;
-        }
-        if (val.sign == 0) {
-            return BigInteger.ZERO;
-        }
-        if (val.equals(BigInteger.MINUS_ONE)) {
-            return that.not();
-        }
-        if (that.equals(BigInteger.MINUS_ONE)){
-            return BigInteger.ZERO;
-        }
-
-        //if val == that, return 0
-
-       if (val.sign > 0) {
-            if (that.sign > 0) {
-                return andNotPositive(val, that);
-            } else {
-                return andNotPositiveNegative(val, that);
-                    }
-                } else {
-            if (that.sign > 0) {
-                return andNotNegativePositive(val, that);
-            } else  {
-                return andNotNegative(val, that);
-            }
-        }
-    }
-
-    /** @return sign = 1, magnitude = val.magnitude & ~that.magnitude*/
-    static BigInteger andNotPositive(BigInteger val, BigInteger that) {
-        // PRE: both arguments are positive
-        int[] resDigits = new int[val.numberLength];
-
-        int limit = Math.min(val.numberLength, that.numberLength);
-        int i;
-        for (i = val.getFirstNonzeroDigit(); i < limit; i++) {
-            resDigits[i] = val.digits[i] & ~that.digits[i];
-        }
-        for ( ; i < val.numberLength; i++) {
-            resDigits[i] = val.digits[i];
-        }
-
-        return new BigInteger(1, val.numberLength, resDigits);
-    }
-
-    /** @return sign = 1, magnitude = positive.magnitude & ~(-negative.magnitude)*/
-    static BigInteger andNotPositiveNegative(BigInteger positive, BigInteger negative) {
-        // PRE: positive > 0 && negative < 0
-        int iNeg = negative.getFirstNonzeroDigit();
-        int iPos = positive.getFirstNonzeroDigit();
-
-        if (iNeg >= positive.numberLength) {
-            return positive;
-        }
-
-        int resLength = Math.min(positive.numberLength, negative.numberLength);
-        int[] resDigits = new int[resLength];
-
-        // Always start from first non zero of positive
-        int i = iPos;
-        for ( ; i < iNeg; i++) {
-            // resDigits[i] = positive.digits[i] & -1 (~0)
-            resDigits[i] = positive.digits[i];
-        }
-        if (i == iNeg) {
-            resDigits[i] = positive.digits[i] & (negative.digits[i] - 1);
-            i++;
-        }
-        for ( ; i < resLength; i++) {
-            // resDigits[i] = positive.digits[i] & ~(~negative.digits[i]);
-            resDigits[i] = positive.digits[i] & negative.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = -1, magnitude = -(-negative.magnitude & ~positive.magnitude)*/
-    static BigInteger andNotNegativePositive(BigInteger negative, BigInteger positive) {
-        // PRE: negative < 0 && positive > 0
-        int resLength;
-        int[] resDigits;
-        int limit;
-        int digit;
-
-        int iNeg = negative.getFirstNonzeroDigit();
-        int iPos = positive.getFirstNonzeroDigit();
-
-        if (iNeg >= positive.numberLength) {
-            return negative;
-        }
-
-        resLength = Math.max(negative.numberLength, positive.numberLength);
-        int i = iNeg;
-        if (iPos > iNeg) {
-            resDigits = new int[resLength];
-            limit = Math.min(negative.numberLength, iPos);
-            for ( ; i < limit; i++) {
-                // 1st case:  resDigits [i] = -(-negative.digits[i] & (~0))
-                // otherwise: resDigits[i] = ~(~negative.digits[i] & ~0)  ;
-                resDigits[i] = negative.digits[i];
-            }
-            if (i == negative.numberLength) {
-                for (i = iPos; i < positive.numberLength; i++) {
-                    // resDigits[i] = ~(~positive.digits[i] & -1);
-                    resDigits[i] = positive.digits[i];
-                }
-            }
-        } else {
-            digit = -negative.digits[i] & ~positive.digits[i];
-            if (digit == 0) {
-                limit = Math.min(positive.numberLength, negative.numberLength);
-                for (i++; i < limit && (digit = ~(negative.digits[i] | positive.digits[i])) == 0; i++)
-                    ; // digit = ~negative.digits[i] & ~positive.digits[i]
-                if (digit == 0) {
-                    // the shorter has only the remaining virtual sign bits
-                    for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++)
-                        ; // digit = -1 & ~positive.digits[i]
-                    for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++)
-                        ; // digit = ~negative.digits[i] & ~0
-                    if (digit == 0) {
-                        resLength++;
-                        resDigits = new int[resLength];
-                        resDigits[resLength - 1] = 1;
-
-                        return new BigInteger(-1, resLength, resDigits);
-                    }
-                }
-            }
-                        resDigits = new int[resLength];
-            resDigits[i] = -digit;
-            i++;
-                    }
-
-        limit = Math.min(positive.numberLength, negative.numberLength);
-        for ( ; i < limit; i++) {
-            //resDigits[i] = ~(~negative.digits[i] & ~positive.digits[i]);
-            resDigits[i] = negative.digits[i] | positive.digits[i];
-        }
-        // Actually one of the next two cycles will be executed
-        for ( ; i < negative.numberLength; i++) {
-            resDigits[i] = negative.digits[i];
-                }
-        for ( ; i < positive.numberLength; i++) {
-            resDigits[i] = positive.digits[i];
-        }
-
-        return new BigInteger(-1, resLength, resDigits);
-    }
-
-    /** @return sign = 1, magnitude = -val.magnitude & ~(-that.magnitude)*/
-    static BigInteger andNotNegative(BigInteger val, BigInteger that) {
-        // PRE: val < 0 && that < 0
-        int iVal = val.getFirstNonzeroDigit();
-        int iThat = that.getFirstNonzeroDigit();
-
-        if (iVal >= that.numberLength) {
-            return BigInteger.ZERO;
-        }
-
-        int resLength = that.numberLength;
-        int[] resDigits = new int[resLength];
-        int limit;
-        int i = iVal;
-        if (iVal < iThat) {
-            // resDigits[i] = -val.digits[i] & -1;
-            resDigits[i] = -val.digits[i];
-            limit = Math.min(val.numberLength, iThat);
-            for (i++; i < limit; i++) {
-                // resDigits[i] = ~val.digits[i] & -1;
-                resDigits[i] = ~val.digits[i];
-            }
-            if (i == val.numberLength) {
-                for ( ; i < iThat; i++) {
-                    // resDigits[i] = -1 & -1;
-                    resDigits[i] = -1;
-                }
-                // resDigits[i] = -1 & ~-that.digits[i];
-                resDigits[i] = that.digits[i] - 1;
-        } else {
-                // resDigits[i] = ~val.digits[i] & ~-that.digits[i];
-                resDigits[i] = ~val.digits[i] & (that.digits[i] - 1);
-            }
-        } else if (iThat < iVal ) {
-            // resDigits[i] = -val.digits[i] & ~~that.digits[i];
-            resDigits[i] = -val.digits[i] & that.digits[i];
-        } else {
-            // resDigits[i] = -val.digits[i] & ~-that.digits[i];
-            resDigits[i] = -val.digits[i] & (that.digits[i] - 1);
-            }
-
-        limit = Math.min(val.numberLength, that.numberLength);
-        for (i++; i < limit; i++) {
-            // resDigits[i] = ~val.digits[i] & ~~that.digits[i];
-            resDigits[i] = ~val.digits[i] & that.digits[i];
-        }
-        for ( ; i < that.numberLength; i++) {
-            // resDigits[i] = -1 & ~~that.digits[i];
-            resDigits[i] = that.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @see BigInteger#or(BigInteger) */
-    static BigInteger or(BigInteger val, BigInteger that) {
-        if (that.equals(BigInteger.MINUS_ONE) || val.equals(BigInteger.MINUS_ONE)) {
-            return BigInteger.MINUS_ONE;
-        }
-        if (that.sign == 0) {
-            return val;
-        }
-        if (val.sign == 0) {
-            return that;
-        }
-
-        if (val.sign > 0) {
-            if (that.sign > 0) {
-                if (val.numberLength > that.numberLength) {
-                    return orPositive(val, that);
-                } else {
-                    return orPositive(that, val);
-                }
-            } else {
-                return orDiffSigns(val, that);
-            }
-        } else {
-            if (that.sign > 0) {
-                return orDiffSigns(that, val);
-            } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
-                return orNegative(that, val);
-            } else {
-                return orNegative(val, that);
-            }
-        }
-    }
-
-    /** @return sign = 1, magnitude = longer.magnitude | shorter.magnitude*/
-    static BigInteger orPositive(BigInteger longer, BigInteger shorter) {
-        // PRE: longer and shorter are positive;
-        // PRE: longer has at least as many digits as shorter
-        int resLength = longer.numberLength;
-        int[] resDigits = new int[resLength];
-
-        int i;
-        for (i = 0; i < shorter.numberLength; i++) {
-            resDigits[i] = longer.digits[i] | shorter.digits[i];
-        }
-        for ( ; i < resLength; i++) {
-            resDigits[i] = longer.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = -1, magnitude = -(-val.magnitude | -that.magnitude) */
-    static BigInteger orNegative(BigInteger val, BigInteger that){
-        // PRE: val and that are negative;
-        // PRE: val has at least as many trailing zeros digits as that
-        int iThat = that.getFirstNonzeroDigit();
-        int iVal = val.getFirstNonzeroDigit();
-        int i;
-
-        if (iVal >= that.numberLength) {
-            return that;
-        }else if (iThat >= val.numberLength) {
-            return val;
-        }
-
-        int resLength = Math.min(val.numberLength, that.numberLength);
-        int[] resDigits = new int[resLength];
-
-        //Looking for the first non-zero digit of the result
-        if (iThat == iVal) {
-            resDigits[iVal] = -(-val.digits[iVal] | -that.digits[iVal]);
-            i = iVal;
-        } else {
-            for (i = iThat; i < iVal; i++) {
-                resDigits[i] = that.digits[i];
-            }
-            resDigits[i] = that.digits[i] & (val.digits[i] - 1);
-        }
-
-        for (i++; i < resLength; i++) {
-            resDigits[i] = val.digits[i] & that.digits[i];
-        }
-
-        return new BigInteger(-1, resLength, resDigits);
-    }
-
-    /** @return sign = -1, magnitude = -(positive.magnitude | -negative.magnitude) */
-    static BigInteger orDiffSigns(BigInteger positive, BigInteger negative){
-        // Jumping over the least significant zero bits
-        int iNeg = negative.getFirstNonzeroDigit();
-        int iPos = positive.getFirstNonzeroDigit();
-        int i;
-        int limit;
-
-        // Look if the trailing zeros of the positive will "copy" all
-        // the negative digits
-        if (iPos >= negative.numberLength) {
-            return negative;
-        }
-        int resLength = negative.numberLength;
-        int[] resDigits = new int[resLength];
-
-        if (iNeg < iPos ) {
-            // We know for sure that this will
-            // be the first non zero digit in the result
-            for (i = iNeg; i < iPos; i++) {
-            resDigits[i] = negative.digits[i];
-            }
-        } else if (iPos < iNeg) {
-            i = iPos;
-            resDigits[i] = -positive.digits[i];
-            limit = Math.min(positive.numberLength, iNeg);
-            for (i++; i < limit; i++ ) {
-                resDigits[i] = ~positive.digits[i];
-            }
-            if (i != positive.numberLength) {
-                resDigits[i] = ~(-negative.digits[i] | positive.digits[i]);
-            } else{
-                  for (; i<iNeg; i++) {
-                      resDigits[i] = -1;
-                  }
-                  // resDigits[i] = ~(-negative.digits[i] | 0);
-                  resDigits[i] = negative.digits[i] - 1;
-            }
-            i++;
-        } else {// iNeg == iPos
-            // Applying two complement to negative and to result
-            i = iPos;
-            resDigits[i] = -(-negative.digits[i] | positive.digits[i]);
-            i++;
-        }
-        limit = Math.min(negative.numberLength, positive.numberLength);
-        for (; i < limit; i++) {
-            // Applying two complement to negative and to result
-            // resDigits[i] = ~(~negative.digits[i] | positive.digits[i] );
-            resDigits[i] = negative.digits[i] & ~positive.digits[i];
-        }
-        for ( ; i < negative.numberLength; i++) {
-            resDigits[i] = negative.digits[i];
-        }
-
-        return new BigInteger(-1, resLength, resDigits);
-    }
-
-    /** @see BigInteger#xor(BigInteger) */
-    static BigInteger xor(BigInteger val, BigInteger that) {
-        if (that.sign == 0) {
-            return val;
-        }
-        if (val.sign == 0) {
-            return that;
-        }
-        if (that.equals(BigInteger.MINUS_ONE)) {
-            return val.not();
-        }
-        if (val.equals(BigInteger.MINUS_ONE)) {
-            return that.not();
-        }
-
-        if (val.sign > 0) {
-            if (that.sign > 0) {
-                if (val.numberLength > that.numberLength) {
-                    return xorPositive(val, that);
-                } else {
-                    return xorPositive(that, val);
-                }
-            } else {
-                return xorDiffSigns(val, that);
-            }
-        } else {
-            if (that.sign > 0) {
-                return xorDiffSigns(that, val);
-            } else if (that.getFirstNonzeroDigit() > val.getFirstNonzeroDigit()) {
-                return xorNegative(that, val);
-            } else {
-                return xorNegative(val, that);
-            }
-        }
-    }
-
-    /** @return sign = 0, magnitude = longer.magnitude | shorter.magnitude */
-    static BigInteger xorPositive(BigInteger longer, BigInteger shorter) {
-        // PRE: longer and shorter are positive;
-        // PRE: longer has at least as many digits as shorter
-        int resLength = longer.numberLength;
-        int[] resDigits = new int[resLength];
-        int i = Math.min(longer.getFirstNonzeroDigit(), shorter.getFirstNonzeroDigit());
-        for ( ; i < shorter.numberLength; i++) {
-            resDigits[i] = longer.digits[i] ^ shorter.digits[i];
-        }
-        for ( ; i < longer.numberLength; i++ ){
-            resDigits[i] = longer.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = 0, magnitude = -val.magnitude ^ -that.magnitude */
-    static BigInteger xorNegative(BigInteger val, BigInteger that){
-        // PRE: val and that are negative
-        // PRE: val has at least as many trailing zero digits as that
-        int resLength = Math.max(val.numberLength, that.numberLength);
-        int[] resDigits = new int[resLength];
-        int iVal = val.getFirstNonzeroDigit();
-        int iThat = that.getFirstNonzeroDigit();
-        int i = iThat;
-        int limit;
-
-
-        if (iVal == iThat) {
-            resDigits[i] = -val.digits[i] ^ -that.digits[i];
-        } else {
-            resDigits[i] = -that.digits[i];
-            limit = Math.min(that.numberLength, iVal);
-            for (i++; i < limit; i++) {
-                resDigits[i] = ~that.digits[i];
-            }
-            // Remains digits in that?
-            if (i == that.numberLength) {
-                //Jumping over the remaining zero to the first non one
-                for ( ;i < iVal; i++) {
-                    //resDigits[i] = 0 ^ -1;
-                    resDigits[i] = -1;
-                }
-                //resDigits[i] = -val.digits[i] ^ -1;
-                resDigits[i] = val.digits[i] - 1;
-            } else {
-                resDigits[i] = -val.digits[i] ^ ~that.digits[i];
-            }
-        }
-
-        limit = Math.min(val.numberLength, that.numberLength);
-        //Perform ^ between that al val until that ends
-        for (i++; i < limit; i++) {
-            //resDigits[i] = ~val.digits[i] ^ ~that.digits[i];
-            resDigits[i] = val.digits[i] ^ that.digits[i];
-        }
-        //Perform ^ between val digits and -1 until val ends
-        for ( ; i < val.numberLength; i++) {
-            //resDigits[i] = ~val.digits[i] ^ -1  ;
-            resDigits[i] = val.digits[i] ;
-        }
-        for ( ; i < that.numberLength; i++) {
-            //resDigits[i] = -1 ^ ~that.digits[i] ;
-            resDigits[i] = that.digits[i];
-        }
-
-        return new BigInteger(1, resLength, resDigits);
-    }
-
-    /** @return sign = 1, magnitude = -(positive.magnitude ^ -negative.magnitude)*/
-    static BigInteger xorDiffSigns(BigInteger positive, BigInteger negative){
-        int resLength = Math.max(negative.numberLength, positive.numberLength);
-        int[] resDigits;
-        int iNeg = negative.getFirstNonzeroDigit();
-        int iPos = positive.getFirstNonzeroDigit();
-        int i;
-        int limit;
-
-        //The first
-        if (iNeg < iPos) {
-            resDigits = new int[resLength];
-            i = iNeg;
-            //resDigits[i] = -(-negative.digits[i]);
-            resDigits[i] = negative.digits[i];
-            limit = Math.min(negative.numberLength, iPos);
-            //Skip the positive digits while they are zeros
-            for (i++; i < limit; i++) {
-                //resDigits[i] = ~(~negative.digits[i]);
-                resDigits[i] = negative.digits[i];
-            }
-            //if the negative has no more elements, must fill the
-            //result with the remaining digits of the positive
-            if (i == negative.numberLength) {
-                for ( ; i < positive.numberLength; i++) {
-                    //resDigits[i] = ~(positive.digits[i] ^ -1) -> ~(~positive.digits[i])
-                    resDigits[i] = positive.digits[i];
-                }
-            }
-        } else if (iPos < iNeg) {
-            resDigits = new int[resLength];
-            i = iPos;
-            //Applying two complement to the first non-zero digit of the result
-            resDigits[i] = -positive.digits[i];
-            limit = Math.min(positive.numberLength, iNeg);
-            for (i++; i < limit; i++) {
-                //Continue applying two complement the result
-                resDigits[i] = ~positive.digits[i];
-            }
-            //When the first non-zero digit of the negative is reached, must apply
-            //two complement (arithmetic negation) to it, and then operate
-            if (i == iNeg) {
-                resDigits[i] = ~(positive.digits[i] ^ -negative.digits[i]);
-                i++;
-            } else {
-                //if the positive has no more elements must fill the remaining digits with
-                //the negative ones
-                for ( ; i < iNeg; i++) {
-                    // resDigits[i] = ~(0 ^ 0)
-                    resDigits[i] = -1;
-                }
-                for ( ; i < negative.numberLength; i++) {
-                    //resDigits[i] = ~(~negative.digits[i] ^ 0)
-                    resDigits[i] = negative.digits[i];
-                }
-            }
-                } else {
-            //The first non-zero digit of the positive and negative are the same
-            i = iNeg;
-            int digit = positive.digits[i] ^ -negative.digits[i];
-            if (digit == 0) {
-                limit = Math.min(positive.numberLength, negative.numberLength);
-                for (i++; i < limit && (digit = positive.digits[i] ^ ~negative.digits[i]) == 0; i++)
-                    ;
-                if (digit == 0) {
-                    // shorter has only the remaining virtual sign bits
-                    for ( ; i < positive.numberLength && (digit = ~positive.digits[i]) == 0; i++)
-                        ;
-                    for ( ; i < negative.numberLength && (digit = ~negative.digits[i]) == 0; i++)
-                        ;
-                    if (digit == 0) {
-                        resLength = resLength + 1;
-                        resDigits = new int[resLength];
-                        resDigits[resLength - 1] = 1;
-
-                        return new BigInteger(-1, resLength, resDigits);
-                }
-            }
-        }
-            resDigits = new int[resLength];
-            resDigits[i] = -digit;
-            i++;
-        }
-
-        limit = Math.min(negative.numberLength, positive.numberLength);
-        for ( ; i < limit; i++) {
-            resDigits[i] = ~(~negative.digits[i] ^ positive.digits[i]);
-        }
-        for ( ; i < positive.numberLength; i++) {
-            // resDigits[i] = ~(positive.digits[i] ^ -1)
-            resDigits[i] = positive.digits[i];
-        }
-        for ( ; i < negative.numberLength; i++) {
-            // resDigits[i] = ~(0 ^ ~negative.digits[i])
-            resDigits[i] = negative.digits[i];
-        }
-
-        return new BigInteger(-1, resLength, resDigits);
-    }
-}
diff --git a/luni/src/main/java/java/math/MathContext.java b/luni/src/main/java/java/math/MathContext.java
deleted file mode 100644
index 6f3f1ed..0000000
--- a/luni/src/main/java/java/math/MathContext.java
+++ /dev/null
@@ -1,249 +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 java.math;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.io.StreamCorruptedException;
-
-/**
- * Immutable objects describing settings such as rounding mode and digit
- * precision for the numerical operations provided by class {@link BigDecimal}.
- */
-public final class MathContext implements Serializable {
-    private static final long serialVersionUID = 5579720004786848255L;
-
-    /**
-     * A {@code MathContext} which corresponds to the <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> quadruple
-     * decimal precision format: 34 digit precision and
-     * {@link RoundingMode#HALF_EVEN} rounding.
-     */
-    public static final MathContext DECIMAL128 = new MathContext(34, RoundingMode.HALF_EVEN);
-
-    /**
-     * A {@code MathContext} which corresponds to the <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> single decimal
-     * precision format: 7 digit precision and {@link RoundingMode#HALF_EVEN}
-     * rounding.
-     */
-    public static final MathContext DECIMAL32 = new MathContext(7, RoundingMode.HALF_EVEN);
-
-    /**
-     * A {@code MathContext} which corresponds to the <a href="http://en.wikipedia.org/wiki/IEEE_754-1985">IEEE 754</a> double decimal
-     * precision format: 16 digit precision and {@link RoundingMode#HALF_EVEN}
-     * rounding.
-     */
-    public static final MathContext DECIMAL64 = new MathContext(16, RoundingMode.HALF_EVEN);
-
-    /**
-     * A {@code MathContext} for unlimited precision with
-     * {@link RoundingMode#HALF_UP} rounding.
-     */
-    public static final MathContext UNLIMITED = new MathContext(0, RoundingMode.HALF_UP);
-
-    /**
-     * The number of digits to be used for an operation; results are rounded to
-     * this precision.
-     */
-    private final int precision;
-
-    /**
-     * A {@code RoundingMode} object which specifies the algorithm to be used
-     * for rounding.
-     */
-    private final RoundingMode roundingMode;
-
-    /**
-     * Constructs a new {@code MathContext} with the specified precision and
-     * with the rounding mode {@link RoundingMode#HALF_UP HALF_UP}. If the
-     * precision passed is zero, then this implies that the computations have to
-     * be performed exact, the rounding mode in this case is irrelevant.
-     *
-     * @param precision
-     *            the precision for the new {@code MathContext}.
-     * @throws IllegalArgumentException
-     *             if {@code precision < 0}.
-     */
-    public MathContext(int precision) {
-        this(precision, RoundingMode.HALF_UP);
-    }
-
-    /**
-     * Constructs a new {@code MathContext} with the specified precision and
-     * with the specified rounding mode. If the precision passed is zero, then
-     * this implies that the computations have to be performed exact, the
-     * rounding mode in this case is irrelevant.
-     *
-     * @param precision
-     *            the precision for the new {@code MathContext}.
-     * @param roundingMode
-     *            the rounding mode for the new {@code MathContext}.
-     * @throws IllegalArgumentException
-     *             if {@code precision < 0}.
-     * @throws NullPointerException
-     *             if {@code roundingMode} is {@code null}.
-     */
-    public MathContext(int precision, RoundingMode roundingMode) {
-        this.precision = precision;
-        this.roundingMode = roundingMode;
-        checkValid();
-    }
-
-    /**
-     * Constructs a new {@code MathContext} from a string. The string has to
-     * specify the precision and the rounding mode to be used and has to follow
-     * the following syntax: "precision=&lt;precision&gt; roundingMode=&lt;roundingMode&gt;"
-     * This is the same form as the one returned by the {@link #toString}
-     * method.
-     *
-     * @throws IllegalArgumentException
-     *             if the string is not in the correct format or if the
-     *             precision specified is < 0.
-     */
-    public MathContext(String s) {
-        int precisionLength = "precision=".length();
-        int roundingModeLength = "roundingMode=".length();
-
-        int spaceIndex;
-        if (!s.startsWith("precision=") || (spaceIndex = s.indexOf(' ', precisionLength)) == -1) {
-            throw invalidMathContext("Missing precision", s);
-        }
-        String precisionString = s.substring(precisionLength, spaceIndex);
-        try {
-            this.precision = Integer.parseInt(precisionString);
-        } catch (NumberFormatException nfe) {
-            throw invalidMathContext("Bad precision", s);
-        }
-
-        int roundingModeStart = spaceIndex + 1;
-        if (!s.regionMatches(roundingModeStart, "roundingMode=", 0, roundingModeLength)) {
-            throw invalidMathContext("Missing rounding mode", s);
-        }
-        roundingModeStart += roundingModeLength;
-        this.roundingMode = RoundingMode.valueOf(s.substring(roundingModeStart));
-
-        checkValid();
-    }
-
-    private IllegalArgumentException invalidMathContext(String reason, String s) {
-        throw new IllegalArgumentException(reason + ": " + s);
-    }
-
-    private void checkValid() {
-        if (precision < 0) {
-            throw new IllegalArgumentException("Negative precision: " + precision);
-        }
-        if (roundingMode == null) {
-            throw new NullPointerException("roundingMode == null");
-        }
-    }
-
-    /**
-     * Returns the precision. The precision is the number of digits used for an
-     * operation. Results are rounded to this precision. The precision is
-     * guaranteed to be non negative. If the precision is zero, then the
-     * computations have to be performed exact, results are not rounded in this
-     * case.
-     *
-     * @return the precision.
-     */
-    public int getPrecision() {
-        return precision;
-    }
-
-    /**
-     * Returns the rounding mode. The rounding mode is the strategy to be used
-     * to round results.
-     * <p>
-     * The rounding mode is one of
-     * {@link RoundingMode#UP},
-     * {@link RoundingMode#DOWN},
-     * {@link RoundingMode#CEILING},
-     * {@link RoundingMode#FLOOR},
-     * {@link RoundingMode#HALF_UP},
-     * {@link RoundingMode#HALF_DOWN},
-     * {@link RoundingMode#HALF_EVEN}, or
-     * {@link RoundingMode#UNNECESSARY}.
-     *
-     * @return the rounding mode.
-     */
-    public RoundingMode getRoundingMode() {
-        return roundingMode;
-    }
-
-    /**
-     * Returns true if x is a {@code MathContext} with the same precision
-     * setting and the same rounding mode as this {@code MathContext} instance.
-     *
-     * @param x
-     *            object to be compared.
-     * @return {@code true} if this {@code MathContext} instance is equal to the
-     *         {@code x} argument; {@code false} otherwise.
-     */
-    @Override
-    public boolean equals(Object x) {
-        return ((x instanceof MathContext)
-                && (((MathContext) x).getPrecision() == precision) && (((MathContext) x)
-                .getRoundingMode() == roundingMode));
-    }
-
-    /**
-     * Returns the hash code for this {@code MathContext} instance.
-     *
-     * @return the hash code for this {@code MathContext}.
-     */
-    @Override
-    public int hashCode() {
-        // Make place for the necessary bits to represent 8 rounding modes
-        return ((precision << 3) | roundingMode.ordinal());
-    }
-
-    /**
-     * Returns the string representation for this {@code MathContext} instance.
-     * The string has the form
-     * {@code
-     * "precision=<precision> roundingMode=<roundingMode>"
-     * } where {@code <precision>} is an integer describing the number
-     * of digits used for operations and {@code <roundingMode>} is the
-     * string representation of the rounding mode.
-     *
-     * @return a string representation for this {@code MathContext} instance
-     */
-    @Override
-    public String toString() {
-        return "precision=" + precision + " roundingMode=" + roundingMode;
-    }
-
-    /**
-     * Makes checks upon deserialization of a {@code MathContext} instance.
-     * Checks whether {@code precision >= 0} and {@code roundingMode != null}
-     *
-     * @throws StreamCorruptedException
-     *             if {@code precision < 0}
-     * @throws StreamCorruptedException
-     *             if {@code roundingMode == null}
-     */
-    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
-        try {
-            checkValid();
-        } catch (Exception ex) {
-            throw new StreamCorruptedException(ex.getMessage());
-        }
-    }
-}
diff --git a/luni/src/main/java/java/math/Multiplication.java b/luni/src/main/java/java/math/Multiplication.java
deleted file mode 100644
index 2a4285b..0000000
--- a/luni/src/main/java/java/math/Multiplication.java
+++ /dev/null
@@ -1,187 +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 java.math;
-
-/**
- * Static library that provides all multiplication of {@link BigInteger} methods.
- */
-class Multiplication {
-
-    /** Just to denote that this class can't be instantiated. */
-    private Multiplication() {}
-
-    // BEGIN Android-removed
-    // /**
-    //  * Break point in digits (number of {@code int} elements)
-    //  * between Karatsuba and Pencil and Paper multiply.
-    //  */
-    // static final int whenUseKaratsuba = 63; // an heuristic value
-    // END Android-removed
-
-    /**
-     * An array with powers of ten that fit in the type {@code int}.
-     * ({@code 10^0,10^1,...,10^9})
-     */
-    static final int[] tenPows = {
-        1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
-    };
-
-    /**
-     * An array with powers of five that fit in the type {@code int}.
-     * ({@code 5^0,5^1,...,5^13})
-     */
-    static final int[] fivePows = {
-        1, 5, 25, 125, 625, 3125, 15625, 78125, 390625,
-        1953125, 9765625, 48828125, 244140625, 1220703125
-    };
-
-    /**
-     * An array with the first powers of ten in {@code BigInteger} version.
-     * ({@code 10^0,10^1,...,10^31})
-     */
-    static final BigInteger[] bigTenPows = new BigInteger[32];
-
-    /**
-     * An array with the first powers of five in {@code BigInteger} version.
-     * ({@code 5^0,5^1,...,5^31})
-     */
-    static final BigInteger bigFivePows[] = new BigInteger[32];
-
-
-
-    static {
-        int i;
-        long fivePow = 1L;
-
-        for (i = 0; i <= 18; i++) {
-            bigFivePows[i] = BigInteger.valueOf(fivePow);
-            bigTenPows[i] = BigInteger.valueOf(fivePow << i);
-            fivePow *= 5;
-        }
-        for (; i < bigTenPows.length; i++) {
-            bigFivePows[i] = bigFivePows[i - 1].multiply(bigFivePows[1]);
-            bigTenPows[i] = bigTenPows[i - 1].multiply(BigInteger.TEN);
-        }
-    }
-
-    // BEGIN android-note: multiply has been removed in favor of using OpenSSL BIGNUM
-    // END android-note
-
-    /**
-     * Multiplies a number by a positive integer.
-     * @param val an arbitrary {@code BigInteger}
-     * @param factor a positive {@code int} number
-     * @return {@code val * factor}
-     */
-    static BigInteger multiplyByPositiveInt(BigInteger val, int factor) {
-        BigInt bi = val.getBigInt().copy();
-        bi.multiplyByPositiveInt(factor);
-        return new BigInteger(bi);
-    }
-
-    /**
-     * Multiplies a number by a power of ten.
-     * This method is used in {@code BigDecimal} class.
-     * @param val the number to be multiplied
-     * @param exp a positive {@code long} exponent
-     * @return {@code val * 10<sup>exp</sup>}
-     */
-    static BigInteger multiplyByTenPow(BigInteger val, long exp) {
-        // PRE: exp >= 0
-        return ((exp < tenPows.length)
-        ? multiplyByPositiveInt(val, tenPows[(int)exp])
-        : val.multiply(powerOf10(exp)));
-    }
-
-    /**
-     * It calculates a power of ten, which exponent could be out of 32-bit range.
-     * Note that internally this method will be used in the worst case with
-     * an exponent equals to: {@code Integer.MAX_VALUE - Integer.MIN_VALUE}.
-     * @param exp the exponent of power of ten, it must be positive.
-     * @return a {@code BigInteger} with value {@code 10<sup>exp</sup>}.
-     */
-    static BigInteger powerOf10(long exp) {
-        // PRE: exp >= 0
-        int intExp = (int)exp;
-        // "SMALL POWERS"
-        if (exp < bigTenPows.length) {
-            // The largest power that fit in 'long' type
-            return bigTenPows[intExp];
-        } else if (exp <= 50) {
-            // To calculate:    10^exp
-            return BigInteger.TEN.pow(intExp);
-        }
-
-        BigInteger res = null;
-        try {
-            // "LARGE POWERS"
-            if (exp <= Integer.MAX_VALUE) {
-                // To calculate:    5^exp * 2^exp
-                res = bigFivePows[1].pow(intExp).shiftLeft(intExp);
-            } else {
-                /*
-                 * "HUGE POWERS"
-                 *
-                 * This branch probably won't be executed since the power of ten is too
-                 * big.
-                 */
-                // To calculate:    5^exp
-                BigInteger powerOfFive = bigFivePows[1].pow(Integer.MAX_VALUE);
-                res = powerOfFive;
-                long longExp = exp - Integer.MAX_VALUE;
-
-                intExp = (int) (exp % Integer.MAX_VALUE);
-                while (longExp > Integer.MAX_VALUE) {
-                    res = res.multiply(powerOfFive);
-                    longExp -= Integer.MAX_VALUE;
-                }
-                res = res.multiply(bigFivePows[1].pow(intExp));
-                // To calculate:    5^exp << exp
-                res = res.shiftLeft(Integer.MAX_VALUE);
-                longExp = exp - Integer.MAX_VALUE;
-                while (longExp > Integer.MAX_VALUE) {
-                    res = res.shiftLeft(Integer.MAX_VALUE);
-                    longExp -= Integer.MAX_VALUE;
-                }
-                res = res.shiftLeft(intExp);
-            }
-        } catch (OutOfMemoryError error) {
-            throw new ArithmeticException(error.getMessage());
-        }
-
-        return res;
-    }
-
-    /**
-     * Multiplies a number by a power of five.
-     * This method is used in {@code BigDecimal} class.
-     * @param val the number to be multiplied
-     * @param exp a positive {@code int} exponent
-     * @return {@code val * 5<sup>exp</sup>}
-     */
-    static BigInteger multiplyByFivePow(BigInteger val, int exp) {
-        // PRE: exp >= 0
-        if (exp < fivePows.length) {
-            return multiplyByPositiveInt(val, fivePows[exp]);
-        } else if (exp < bigFivePows.length) {
-            return val.multiply(bigFivePows[exp]);
-        } else {// Large powers of five
-            return val.multiply(bigFivePows[1].pow(exp));
-        }
-    }
-}
diff --git a/luni/src/main/java/java/math/NativeBN.java b/luni/src/main/java/java/math/NativeBN.java
deleted file mode 100644
index ab9b2e0..0000000
--- a/luni/src/main/java/java/math/NativeBN.java
+++ /dev/null
@@ -1,136 +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 java.math;
-
-final class NativeBN {
-
-    public static native long BN_new();
-    // BIGNUM *BN_new(void);
-
-    public static native void BN_free(long a);
-    // void BN_free(BIGNUM *a);
-
-    public static native int BN_cmp(long a, long b);
-    // int BN_cmp(const BIGNUM *a, const BIGNUM *b);
-
-    public static native void BN_copy(long to, long from);
-    // BIGNUM *BN_copy(BIGNUM *to, const BIGNUM *from);
-
-    public static native void putLongInt(long a, long dw);
-    public static native void putULongInt(long a, long dw, boolean neg);
-
-    public static native int BN_dec2bn(long a, String str);
-    // int BN_dec2bn(BIGNUM **a, const char *str);
-
-    public static native int BN_hex2bn(long a, String str);
-    // int BN_hex2bn(BIGNUM **a, const char *str);
-
-    public static native void BN_bin2bn(byte[] s, int len, boolean neg, long ret);
-    // BIGNUM * BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret);
-    // BN-Docu: s is taken as unsigned big endian;
-    // Additional parameter: neg.
-
-    public static native void litEndInts2bn(int[] ints, int len, boolean neg, long ret);
-
-    public static native void twosComp2bn(byte[] s, int len, long ret);
-
-
-    public static native long longInt(long a);
-    // unsigned long BN_get_word(BIGNUM *a);
-
-    public static native String BN_bn2dec(long a);
-    // char * BN_bn2dec(const BIGNUM *a);
-
-    public static native String BN_bn2hex(long a);
-    // char * BN_bn2hex(const BIGNUM *a);
-
-    public static native byte[] BN_bn2bin(long a);
-    // Returns result byte[] AND NOT length.
-    // int BN_bn2bin(const BIGNUM *a, unsigned char *to);
-
-    public static native int[] bn2litEndInts(long a);
-
-    public static native int sign(long a);
-    // Returns -1, 0, 1 AND NOT boolean.
-    // #define BN_is_negative(a) ((a)->neg != 0)
-
-    public static native void BN_set_negative(long b, int n);
-    // void BN_set_negative(BIGNUM *b, int n);
-
-    public static native int bitLength(long a);
-
-    public static native boolean BN_is_bit_set(long a, int n);
-    // int BN_is_bit_set(const BIGNUM *a, int n);
-
-    public static native void BN_shift(long r, long a, int n);
-    // int BN_shift(BIGNUM *r, const BIGNUM *a, int n);
-
-    public static native void BN_add_word(long a, int w);
-    // ATTENTION: w is treated as unsigned.
-    // int BN_add_word(BIGNUM *a, BN_ULONG w);
-
-    public static native void BN_mul_word(long a, int w);
-    // ATTENTION: w is treated as unsigned.
-    // int BN_mul_word(BIGNUM *a, BN_ULONG w);
-
-    public static native int BN_mod_word(long a, int w);
-    // ATTENTION: w is treated as unsigned.
-    // BN_ULONG BN_mod_word(BIGNUM *a, BN_ULONG w);
-
-    public static native void BN_add(long r, long a, long b);
-    // int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
-
-    public static native void BN_sub(long r, long a, long b);
-    // int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
-
-    public static native void BN_gcd(long r, long a, long b);
-    // int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
-    public static native void BN_mul(long r, long a, long b);
-    // int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
-
-    public static native void BN_exp(long r, long a, long p);
-    // int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx);
-
-    public static native void BN_div(long dv, long rem, long m, long d);
-    // int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx);
-
-    public static native void BN_nnmod(long r, long a, long m);
-    // int BN_nnmod(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx);
-
-    public static native void BN_mod_exp(long r, long a, long p, long m);
-    // int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx);
-
-    public static native void BN_mod_inverse(long ret, long a, long n);
-    // BIGNUM * BN_mod_inverse(BIGNUM *ret, const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx);
-
-
-    public static native void BN_generate_prime_ex(long ret, int bits, boolean safe,
-                                                   long add, long rem);
-    // int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
-    //         const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb);
-
-    public static native boolean BN_primality_test(long candidate, int checks,
-                                                   boolean do_trial_division);
-    // int BN_primality_test(int *is_probably_prime, const BIGNUM *candidate, int checks,
-    //                       BN_CTX *ctx, int do_trial_division, BN_GENCB *cb);
-    // Returns *is_probably_prime on success and throws an exception on error.
-
-    public static native long getNativeFinalizer();
-    // &BN_free
-
-}
diff --git a/luni/src/main/java/java/math/Primality.java b/luni/src/main/java/java/math/Primality.java
deleted file mode 100644
index eacc893..0000000
--- a/luni/src/main/java/java/math/Primality.java
+++ /dev/null
@@ -1,145 +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 java.math;
-
-import java.util.Arrays;
-
-/**
- * Provides primality probabilistic methods.
- */
-class Primality {
-
-    /** Just to denote that this class can't be instantiated. */
-    private Primality() {}
-
-    /** All prime numbers with bit length lesser than 10 bits. */
-    private static final int[] primes = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
-            31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
-            103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167,
-            173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239,
-            241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313,
-            317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397,
-            401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467,
-            479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569,
-            571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643,
-            647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733,
-            739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823,
-            827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
-            919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009,
-            1013, 1019, 1021 };
-
-    /** All {@code BigInteger} prime numbers with bit length lesser than 10 bits. */
-    private static final BigInteger BIprimes[] = new BigInteger[primes.length];
-
-//    /**
-//     * It encodes how many iterations of Miller-Rabin test are need to get an
-//     * error bound not greater than {@code 2<sup>(-100)</sup>}. For example:
-//     * for a {@code 1000}-bit number we need {@code 4} iterations, since
-//     * {@code BITS[3] < 1000 <= BITS[4]}.
-//     */
-//    private static final int[] BITS = { 0, 0, 1854, 1233, 927, 747, 627, 543,
-//            480, 431, 393, 361, 335, 314, 295, 279, 265, 253, 242, 232, 223,
-//            216, 181, 169, 158, 150, 145, 140, 136, 132, 127, 123, 119, 114,
-//            110, 105, 101, 96, 92, 87, 83, 78, 73, 69, 64, 59, 54, 49, 44, 38,
-//            32, 26, 1 };
-//
-//    /**
-//     * It encodes how many i-bit primes there are in the table for
-//     * {@code i=2,...,10}. For example {@code offsetPrimes[6]} says that from
-//     * index {@code 11} exists {@code 7} consecutive {@code 6}-bit prime
-//     * numbers in the array.
-//     */
-//    private static final int[][] offsetPrimes = { null, null, { 0, 2 },
-//            { 2, 2 }, { 4, 2 }, { 6, 5 }, { 11, 7 }, { 18, 13 }, { 31, 23 },
-//            { 54, 43 }, { 97, 75 } };
-
-    static {// To initialize the dual table of BigInteger primes
-        for (int i = 0; i < primes.length; i++) {
-            BIprimes[i] = BigInteger.valueOf(primes[i]);
-        }
-    }
-
-    /**
-     * It uses the sieve of Eratosthenes to discard several composite numbers in
-     * some appropriate range (at the moment {@code [this, this + 1024]}). After
-     * this process it applies the Miller-Rabin test to the numbers that were
-     * not discarded in the sieve.
-     *
-     * @see BigInteger#nextProbablePrime()
-     */
-    static BigInteger nextProbablePrime(BigInteger n) {
-        // PRE: n >= 0
-        int i, j;
-//        int certainty;
-        int gapSize = 1024; // for searching of the next probable prime number
-        int[] modules = new int[primes.length];
-        boolean isDivisible[] = new boolean[gapSize];
-        BigInt ni = n.getBigInt();
-        // If n < "last prime of table" searches next prime in the table
-        if (ni.bitLength() <= 10) {
-            int l = (int)ni.longInt();
-            if (l < primes[primes.length - 1]) {
-                for (i = 0; l >= primes[i]; i++) {}
-                return BIprimes[i];
-            }
-        }
-
-        BigInt startPoint = ni.copy();
-        BigInt probPrime = new BigInt();
-
-        // Fix startPoint to "next odd number":
-        startPoint.addPositiveInt(BigInt.remainderByPositiveInt(ni, 2) + 1);
-
-//        // To set the improved certainty of Miller-Rabin
-//        j = startPoint.bitLength();
-//        for (certainty = 2; j < BITS[certainty]; certainty++) {
-//            ;
-//        }
-
-        // To calculate modules: N mod p1, N mod p2, ... for first primes.
-        for (i = 0; i < primes.length; i++) {
-            modules[i] = BigInt.remainderByPositiveInt(startPoint, primes[i]) - gapSize;
-        }
-        while (true) {
-            // At this point, all numbers in the gap are initialized as
-            // probably primes
-            Arrays.fill(isDivisible, false);
-            // To discard multiples of first primes
-            for (i = 0; i < primes.length; i++) {
-                modules[i] = (modules[i] + gapSize) % primes[i];
-                j = (modules[i] == 0) ? 0 : (primes[i] - modules[i]);
-                for (; j < gapSize; j += primes[i]) {
-                    isDivisible[j] = true;
-                }
-            }
-            // To execute Miller-Rabin for non-divisible numbers by all first
-            // primes
-            for (j = 0; j < gapSize; j++) {
-                if (!isDivisible[j]) {
-                    probPrime.putCopy(startPoint);
-                    probPrime.addPositiveInt(j);
-                    if (probPrime.isPrime(100)) {
-                        return new BigInteger(probPrime);
-                    }
-                }
-            }
-            startPoint.addPositiveInt(gapSize);
-        }
-    }
-
-}
diff --git a/luni/src/main/java/java/math/RoundingMode.java b/luni/src/main/java/java/math/RoundingMode.java
deleted file mode 100644
index f4c181e..0000000
--- a/luni/src/main/java/java/math/RoundingMode.java
+++ /dev/null
@@ -1,122 +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 java.math;
-
-/**
- * Specifies the rounding behavior for operations whose results cannot be
- * represented exactly.
- */
-public enum RoundingMode {
-
-    /**
-     * Rounding mode where positive values are rounded towards positive infinity
-     * and negative values towards negative infinity.
-     * <br>
-     * Rule: {@code x.round().abs() >= x.abs()}
-     */
-    UP(BigDecimal.ROUND_UP),
-
-    /**
-     * Rounding mode where the values are rounded towards zero.
-     * <br>
-     * Rule: {@code x.round().abs() <= x.abs()}
-     */
-    DOWN(BigDecimal.ROUND_DOWN),
-
-    /**
-     * Rounding mode to round towards positive infinity. For positive values
-     * this rounding mode behaves as {@link #UP}, for negative values as
-     * {@link #DOWN}.
-     * <br>
-     * Rule: {@code x.round() >= x}
-     */
-    CEILING(BigDecimal.ROUND_CEILING),
-
-    /**
-     * Rounding mode to round towards negative infinity. For positive values
-     * this rounding mode behaves as {@link #DOWN}, for negative values as
-     * {@link #UP}.
-     * <br>
-     * Rule: {@code x.round() <= x}
-     */
-    FLOOR(BigDecimal.ROUND_FLOOR),
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor. Ties
-     * are broken by rounding up.
-     */
-    HALF_UP(BigDecimal.ROUND_HALF_UP),
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor. Ties
-     * are broken by rounding down.
-     */
-    HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
-
-    /**
-     * Rounding mode where values are rounded towards the nearest neighbor. Ties
-     * are broken by rounding to the even neighbor.
-     */
-    HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
-
-    /**
-     * Rounding mode where the rounding operations throws an ArithmeticException
-     * for the case that rounding is necessary, i.e. for the case that the value
-     * cannot be represented exactly.
-     */
-    UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
-
-    /** The old constant of <code>BigDecimal</code>. */
-    private final int bigDecimalRM;
-
-    /** It sets the old constant. */
-    RoundingMode(int rm) {
-        bigDecimalRM = rm;
-    }
-
-    /**
-     * Converts rounding mode constants from class {@code BigDecimal} into
-     * {@code RoundingMode} values.
-     *
-     * @param mode
-     *            rounding mode constant as defined in class {@code BigDecimal}
-     * @return corresponding rounding mode object
-     */
-    public static RoundingMode valueOf(int mode) {
-        switch (mode) {
-            case BigDecimal.ROUND_CEILING:
-                return CEILING;
-            case BigDecimal.ROUND_DOWN:
-                return DOWN;
-            case BigDecimal.ROUND_FLOOR:
-                return FLOOR;
-            case BigDecimal.ROUND_HALF_DOWN:
-                return HALF_DOWN;
-            case BigDecimal.ROUND_HALF_EVEN:
-                return HALF_EVEN;
-            case BigDecimal.ROUND_HALF_UP:
-                return HALF_UP;
-            case BigDecimal.ROUND_UNNECESSARY:
-                return UNNECESSARY;
-            case BigDecimal.ROUND_UP:
-                return UP;
-            default:
-                throw new IllegalArgumentException("Invalid rounding mode");
-        }
-    }
-}
diff --git a/luni/src/main/java/java/nio/NIOAccess.java b/luni/src/main/java/java/nio/NIOAccess.java
index 7345379..185a6bc 100644
--- a/luni/src/main/java/java/nio/NIOAccess.java
+++ b/luni/src/main/java/java/nio/NIOAccess.java
@@ -24,7 +24,7 @@
  * @hide
  */
 // @VisibleForTesting : was default
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class NIOAccess {
 
     /**
@@ -46,9 +46,12 @@
     /**
      * Returns the underlying Java array containing the data of the
      * given Buffer, or null if the Buffer is not backed by a Java array.
+     *
+     * @param b  {@code Buffer} to get its underlying data array
+     * @return   underlying Java array
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static Object getBaseArray(Buffer b) {
         return b.hasArray() ? b.array() : null;
     }
@@ -58,10 +61,13 @@
      * Java array object containing the data of the given Buffer to
      * the actual start of the data. The start of the data takes into
      * account the Buffer's current position. This method is only
-     * meaningful if getBaseArray() returns non-null.
+     * meaningful if {@link #getBaseArray(Buffer)} returns non-null.
+     *
+     * @param b {@code Buffer} to get its underlying data array's base offset
+     * @return  underlying Java array's base offset
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public 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 aca91b0..453c5c2 100644
--- a/luni/src/main/java/java/nio/NioUtils.java
+++ b/luni/src/main/java/java/nio/NioUtils.java
@@ -32,13 +32,18 @@
 /**
  * @hide internal use only
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class NioUtils {
     private NioUtils() {
     }
 
+    /**
+     * Frees {@link DirectByteBuffer} running associated {@link sun.misc.Cleaner Cleaner}.
+     *
+     * @param buffer to free with associated {@code Cleaner}
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void freeDirectBuffer(ByteBuffer buffer) {
         if (buffer == null) {
             return;
@@ -71,21 +76,28 @@
     }
 
     /**
-     * Exposes the array backing a non-direct ByteBuffer, even if the ByteBuffer is read-only.
+     * Exposes the array backing a non-direct {@link java.nio.ByteBuffer ByteBuffer}, even if
+     * the {@link java.nio.ByteBuffer ByteBuffer} is read-only.
      * Normally, attempting to access the array backing a read-only buffer throws.
+     *
+     * @param b  {@link java.nio.ByteBuffer ByteBuffer} to access its backing array.
+     * @return   buffer's underlying array.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static byte[] unsafeArray(ByteBuffer b) {
         return b.array();
     }
 
     /**
-     * Exposes the array offset for the array backing a non-direct ByteBuffer,
-     * even if the ByteBuffer is read-only.
+     * Exposes the array offset for the array backing a non-direct {@link java.nio.ByteBuffer ByteBuffer},
+     * even if the {@link java.nio.ByteBuffer ByteBuffer} is read-only.
+     *
+     * @param b  {@link java.nio.ByteBuffer ByteBuffer} to access its backing array offset.
+     * @return   buffer's underlying array data offset.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     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
index 99f1679..d1fc685 100644
--- a/luni/src/main/java/libcore/api/CorePlatformApi.java
+++ b/luni/src/main/java/libcore/api/CorePlatformApi.java
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2018 The Android Open Source Project
  *
@@ -42,4 +43,27 @@
 @Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE})
 @Retention(RetentionPolicy.SOURCE)
 public @interface CorePlatformApi {
+
+    /** Enumeration of the possible statuses of the API in the core/platform API surface. */
+    @IntraCoreApi
+    enum Status {
+
+        /**
+         * This API is considered stable, and so present in both the stable and legacy version of
+         * the API surface.
+        */
+        @IntraCoreApi
+        STABLE,
+
+        /**
+         * This API is not (yet) considered stable, and so only present in the legacy version of
+         * the API surface.
+         */
+        @IntraCoreApi
+        LEGACY_ONLY
+    }
+
+    /** The status of the API in the core/platform API surface. */
+    @IntraCoreApi
+    Status status() default libcore.api.CorePlatformApi.Status.LEGACY_ONLY;
 }
diff --git a/luni/src/main/java/libcore/content/type/MimeMap.java b/luni/src/main/java/libcore/content/type/MimeMap.java
index 51e792f..8931524 100644
--- a/luni/src/main/java/libcore/content/type/MimeMap.java
+++ b/luni/src/main/java/libcore/content/type/MimeMap.java
@@ -34,16 +34,31 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = CorePlatformApi.Status.STABLE)
 public final class MimeMap {
 
-    @CorePlatformApi
-    public static Builder builder() {
+    /**
+     * Creates a MIME type map builder.
+     *
+     * @return builder
+     *
+     * @see MimeMap.Builder
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public static @NonNull Builder builder() {
         return new Builder();
     }
 
-    @CorePlatformApi
-    public Builder buildUpon() {
+    /**
+     * Creates a MIME type map builder with values based on {@code this} instance.
+     * This builder will contain all previously added MIMEs and extensions.
+     *
+     * @return builder
+     *
+     * @see MimeMap.Builder
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public @NonNull Builder buildUpon() {
         return new Builder(mimeToExt, extToMime);
     }
 
@@ -60,12 +75,12 @@
     private static volatile MemoizingSupplier<@NonNull MimeMap> instanceSupplier =
             new MemoizingSupplier<>(
                     () -> builder()
-                            .put("application/pdf", "pdf")
-                            .put("image/jpeg", "jpg")
-                            .put("image/x-ms-bmp", "bmp")
-                            .put("text/html", Arrays.asList("htm", "html"))
-                            .put("text/plain", Arrays.asList("text", "txt"))
-                            .put("text/x-java", "java")
+                            .addMimeMapping("application/pdf", "pdf")
+                            .addMimeMapping("image/jpeg", "jpg")
+                            .addMimeMapping("image/x-ms-bmp", "bmp")
+                            .addMimeMapping("text/html", Arrays.asList("htm", "html"))
+                            .addMimeMapping("text/plain", Arrays.asList("text", "txt"))
+                            .addMimeMapping("text/x-java", "java")
                             .build());
 
     private MimeMap(Map<String, String> mimeToExt, Map<String, String> extToMime) {
@@ -82,9 +97,11 @@
     }
 
     /**
+     * Gets system's current default {@link MimeMap}
+     *
      * @return The system's current default {@link MimeMap}.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public static @NonNull MimeMap getDefault() {
         return Objects.requireNonNull(instanceSupplier.get());
     }
@@ -100,7 +117,7 @@
      * {@link #setDefaultSupplier(Supplier)} will return that same instance
      * without consulting {@code mimeMapSupplier} a second time.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public static void setDefaultSupplier(@NonNull Supplier<@NonNull MimeMap> mimeMapSupplier) {
         instanceSupplier = new MemoizingSupplier<>(Objects.requireNonNull(mimeMapSupplier));
     }
@@ -112,7 +129,7 @@
      * @return Whether a MIME type has been registered for the given case insensitive file
      *         extension.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public final boolean hasExtension(@Nullable String extension) {
         return guessMimeTypeFromExtension(extension) != null;
     }
@@ -125,7 +142,7 @@
      * @return The lower-case MIME type registered for the given case insensitive file extension,
      *         or null if there is none.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public final @Nullable String guessMimeTypeFromExtension(@Nullable String extension) {
         if (extension == null) {
             return null;
@@ -135,11 +152,13 @@
     }
 
     /**
+     * Returns whether given case insensetive MIME type is mapped to a file extension.
+     *
      * @param mimeType A MIME type (i.e. {@code "text/plain")
      * @return Whether the given case insensitive MIME type is
      *         {@link #guessMimeTypeFromExtension(String) mapped} to a file extension.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public final boolean hasMimeType(@Nullable String mimeType) {
         return guessExtensionFromMimeType(mimeType) != null;
     }
@@ -152,7 +171,7 @@
      * @return The lower-case file extension (without the leading "." that has been registered for
      *         the given case insensitive MIME type, or null if there is none.
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public final @Nullable String guessExtensionFromMimeType(@Nullable String mimeType) {
         if (mimeType == null) {
             return null;
@@ -166,9 +185,11 @@
      * {@link #hasMimeType(String) maps to some extension}. Note that the
      * reverse mapping might not exist.
      *
+     * @return unmodifiable {@link Set} of MIME types mapped to some extension
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public @NonNull Set<String> mimeTypes() {
         return Collections.unmodifiableSet(mimeToExt.keySet());
     }
@@ -178,9 +199,12 @@
      * {@link #hasExtension(String) maps to some MIME type}. Note that the
      * reverse mapping might not exist.
      *
+     * @return unmodifiable {@link Set} of extensions that this {@link MimeMap}
+     *         maps to some MIME type
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public @NonNull Set<String> extensions() {
         return Collections.unmodifiableSet(extToMime.keySet());
     }
@@ -220,9 +244,13 @@
     }
 
     /**
+     * A builder for mapping of MIME types to extensions and back.
+     * Use {@link #addMimeMapping(String, List)} and {@link #addMimeMapping(String, String)} to add
+     * mapping entries and build final {@link MimeMap} with {@link #build()}.
+     *
      * @hide
      */
-    @libcore.api.CorePlatformApi
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
     public static final class Builder {
         private final Map<String, String> mimeToExt;
         private final Map<String, String> extToMime;
@@ -324,8 +352,8 @@
          *                 been stripped off).
          * @return This builder.
          */
-        @CorePlatformApi
-        public Builder put(@NonNull String mimeSpec, @NonNull List<@NonNull String> extensionSpecs)
+        @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+        public @NonNull Builder addMimeMapping(@NonNull String mimeSpec, @NonNull List<@NonNull String> extensionSpecs)
         {
             Element mimeElement = Element.ofMimeSpec(mimeSpec); // validate mimeSpec unconditionally
             if (extensionSpecs.isEmpty()) {
@@ -346,12 +374,17 @@
          *
          * @hide
          */
-        public Builder put(@NonNull String mimeSpec, @NonNull String extensionSpec) {
-            return put(mimeSpec, Collections.singletonList(extensionSpec));
+        public @NonNull Builder addMimeMapping(@NonNull String mimeSpec, @NonNull String extensionSpec) {
+            return addMimeMapping(mimeSpec, Collections.singletonList(extensionSpec));
         }
 
-        @CorePlatformApi
-        public MimeMap build() {
+        /**
+         * Builds {@link MimeMap} containing all added MIME mappings.
+         *
+         * @return {@link MimeMap} containing previously added MIME mapping entries
+         */
+        @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+        public @NonNull MimeMap build() {
             return new MimeMap(mimeToExt, extToMime);
         }
 
diff --git a/luni/src/main/java/libcore/icu/DateIntervalFormat.java b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
index 74aca08..3ab077f 100644
--- a/luni/src/main/java/libcore/icu/DateIntervalFormat.java
+++ b/luni/src/main/java/libcore/icu/DateIntervalFormat.java
@@ -22,27 +22,20 @@
 
 import java.text.FieldPosition;
 import java.util.TimeZone;
-import libcore.util.BasicLruCache;
 
 import static libcore.icu.DateUtilsBridge.FORMAT_UTC;
 
 /**
- * Exposes icu4j's DateIntervalFormat.
+ * This class is only kept for @UnsupportedAppUsage, and should not used by libcore/frameworks.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
 public final class DateIntervalFormat {
 
-  private static final BasicLruCache<String, android.icu.text.DateIntervalFormat> CACHED_FORMATTERS
-          = new BasicLruCache<>(8);
-
   private DateIntervalFormat() {
   }
 
-  // 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";
@@ -55,7 +48,7 @@
     return formatDateRange(icuLocale, icuTimeZone, startMs, endMs, flags);
   }
 
-  // This is our slightly more sensible internal API. (A truly sane replacement would take a
+  // This is our slightly more sensible internal API. (A better replacement would take a
   // skeleton instead of int flags.)
   public static String formatDateRange(ULocale icuLocale, android.icu.util.TimeZone icuTimeZone,
       long startMs, long endMs, int flags) {
@@ -88,25 +81,11 @@
     }
 
     String skeleton = DateUtilsBridge.toSkeleton(startCalendar, endCalendar, flags);
-    synchronized (CACHED_FORMATTERS) {
-      android.icu.text.DateIntervalFormat formatter =
-          getFormatter(skeleton, icuLocale, icuTimeZone);
-      return formatter.format(startCalendar, endCalendar, new StringBuffer(),
-          new FieldPosition(0)).toString();
-    }
-  }
-
-  private static android.icu.text.DateIntervalFormat getFormatter(String skeleton, ULocale locale,
-      android.icu.util.TimeZone icuTimeZone) {
-    String key = skeleton + "\t" + locale + "\t" + icuTimeZone;
-    android.icu.text.DateIntervalFormat formatter = CACHED_FORMATTERS.get(key);
-    if (formatter != null) {
-      return formatter;
-    }
-    formatter = android.icu.text.DateIntervalFormat.getInstance(skeleton, locale);
+    android.icu.text.DateIntervalFormat formatter =
+            android.icu.text.DateIntervalFormat.getInstance(skeleton, icuLocale);
     formatter.setTimeZone(icuTimeZone);
-    CACHED_FORMATTERS.put(key, formatter);
-    return formatter;
+    return formatter.format(startCalendar, endCalendar, new StringBuffer(),
+        new FieldPosition(0)).toString();
   }
 
   private static boolean isExactlyMidnight(Calendar c) {
diff --git a/luni/src/main/java/libcore/icu/DateTimeFormat.java b/luni/src/main/java/libcore/icu/DateTimeFormat.java
deleted file mode 100644
index 2809625..0000000
--- a/luni/src/main/java/libcore/icu/DateTimeFormat.java
+++ /dev/null
@@ -1,58 +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.icu;
-
-import android.icu.text.DateFormat;
-import android.icu.text.DateTimePatternGenerator;
-import android.icu.text.DisplayContext;
-import android.icu.text.SimpleDateFormat;
-import android.icu.util.Calendar;
-import android.icu.util.ULocale;
-
-import libcore.util.BasicLruCache;
-
-/**
- * A formatter that outputs a single date/time.
- */
-public class DateTimeFormat {
-  private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
-
-  static class FormatterCache extends BasicLruCache<String, DateFormat> {
-    FormatterCache() {
-      super(8);
-    }
-  }
-
-  private DateTimeFormat() {
-  }
-
-  public static String format(ULocale icuLocale, Calendar time, int flags,
-      DisplayContext displayContext) {
-    String skeleton = DateUtilsBridge.toSkeleton(time, flags);
-    String key = skeleton + "\t" + icuLocale + "\t" + time.getTimeZone();
-    synchronized(CACHED_FORMATTERS) {
-      DateFormat formatter = CACHED_FORMATTERS.get(key);
-      if (formatter == null) {
-        DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(icuLocale);
-        formatter = new SimpleDateFormat(generator.getBestPattern(skeleton), icuLocale);
-        CACHED_FORMATTERS.put(key, formatter);
-      }
-      formatter.setContext(displayContext);
-      return formatter.format(time);
-    }
-  }
-}
diff --git a/luni/src/main/java/libcore/icu/DateUtilsBridge.java b/luni/src/main/java/libcore/icu/DateUtilsBridge.java
index ac7a036..3b90a1f 100644
--- a/luni/src/main/java/libcore/icu/DateUtilsBridge.java
+++ b/luni/src/main/java/libcore/icu/DateUtilsBridge.java
@@ -16,14 +16,14 @@
 
 package libcore.icu;
 
-import android.icu.impl.JavaTimeZone;
 import android.icu.util.Calendar;
 import android.icu.util.GregorianCalendar;
+import android.icu.util.TimeZone;
 import android.icu.util.ULocale;
 
 /**
- * Common methods and constants for the various ICU formatters used to support
- * android.text.format.DateUtils.
+ * This class is no longer used by android.text.format.DateUtils, but kept only for
+ * @UnsupportedAppUsage in {@link DateIntervalFormat}.
  */
 public final class DateUtilsBridge {
   // These are all public API in DateUtils. There are others, but they're either for use with
@@ -50,24 +50,24 @@
    * writing the libcore implementation is faster but restricted to 1902 - 2038.
    * Callers must not modify the {@code tz} after calling this method.
    */
-  public static android.icu.util.TimeZone icuTimeZone(java.util.TimeZone tz) {
-    JavaTimeZone javaTimeZone = new JavaTimeZone(tz, null);
-    javaTimeZone.freeze(); // Optimization - allows the timezone to be copied cheaply.
-    return javaTimeZone;
+  /* package */ static android.icu.util.TimeZone icuTimeZone(java.util.TimeZone tz) {
+    android.icu.util.TimeZone icuTimeZone = TimeZone.getTimeZone(tz.getID());
+    icuTimeZone.freeze(); // Optimization - allows the timezone to be copied cheaply.
+    return icuTimeZone;
   }
 
-  public static Calendar createIcuCalendar(android.icu.util.TimeZone icuTimeZone, ULocale icuLocale,
+  /* package */ static Calendar createIcuCalendar(android.icu.util.TimeZone icuTimeZone, ULocale icuLocale,
       long timeInMillis) {
     Calendar calendar = new GregorianCalendar(icuTimeZone, icuLocale);
     calendar.setTimeInMillis(timeInMillis);
     return calendar;
   }
 
-  public static String toSkeleton(Calendar calendar, int flags) {
+  /* package */ static String toSkeleton(Calendar calendar, int flags) {
     return toSkeleton(calendar, calendar, flags);
   }
 
-  public static String toSkeleton(Calendar startCalendar, Calendar endCalendar, int flags) {
+  /* package */ static String toSkeleton(Calendar startCalendar, Calendar endCalendar, int flags) {
     if ((flags & FORMAT_ABBREV_ALL) != 0) {
       flags |= FORMAT_ABBREV_MONTH | FORMAT_ABBREV_TIME | FORMAT_ABBREV_WEEKDAY;
     }
@@ -147,7 +147,7 @@
     return builder.toString();
   }
 
-  public static int dayDistance(Calendar c1, Calendar c2) {
+  /* package */ static int dayDistance(Calendar c1, Calendar c2) {
     return c2.get(Calendar.JULIAN_DAY) - c1.get(Calendar.JULIAN_DAY);
   }
 
@@ -155,7 +155,7 @@
    * Returns whether the argument will be displayed as if it were midnight, using any of the
    * skeletons provided by {@link #toSkeleton}.
    */
-  public static boolean isDisplayMidnightUsingSkeleton(Calendar c) {
+  /* package */ static boolean isDisplayMidnightUsingSkeleton(Calendar c) {
     // All the skeletons returned by toSkeleton have minute precision (they may abbreviate 4:00 PM
     // to 4 PM but will still show the following minute as 4:01 PM).
     return c.get(Calendar.HOUR_OF_DAY) == 0 && c.get(Calendar.MINUTE) == 0;
diff --git a/luni/src/main/java/libcore/icu/ICU.java b/luni/src/main/java/libcore/icu/ICU.java
index f6e5fed..e72d707 100644
--- a/luni/src/main/java/libcore/icu/ICU.java
+++ b/luni/src/main/java/libcore/icu/ICU.java
@@ -17,9 +17,16 @@
 package libcore.icu;
 
 import android.compat.annotation.UnsupportedAppUsage;
+import android.icu.text.DateTimePatternGenerator;
+import android.icu.util.Currency;
+import android.icu.util.IllformedLocaleException;
 import android.icu.util.ULocale;
 
+import com.android.icu.util.ExtendedCalendar;
+import com.android.icu.util.LocaleNative;
+
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
@@ -33,7 +40,6 @@
  * Makes ICU data accessible to Java.
  * @hide
  */
-@libcore.api.CorePlatformApi
 public final class ICU {
 
   @UnsupportedAppUsage
@@ -43,12 +49,36 @@
   private static Locale[] availableLocalesCache;
 
   private static String[] isoCountries;
+  private static Set<String> isoCountriesSet;
 
   private static String[] isoLanguages;
 
+  /**
+   * Avoid initialization with many dependencies here, because when this is called,
+   * lower-level classes, e.g. java.lang.System, are not initialized and java.lang.System
+   * relies on getIcuVersion().
+   */
+  static {
+
+  }
+
   private ICU() {
   }
 
+  public static void initializeCacheInZygote() {
+    // Fill CACHED_PATTERNS with the patterns from default locale and en-US initially.
+    // This should be called in Zygote pre-fork process and the initial values in the cache
+    // can be shared among app. The cache was filled by LocaleData in the older Android platform,
+    // but moved here, due to an performance issue http://b/161846393.
+    // It initializes 2 x 4 = 8 values in the CACHED_PATTERNS whose max size should be >= 8.
+    for (Locale locale : new Locale[] {Locale.US, Locale.getDefault()}) {
+      getTimePattern(locale, false, false);
+      getTimePattern(locale, false, true);
+      getTimePattern(locale, true, false);
+      getTimePattern(locale, true, true);
+    }
+  }
+
   /**
    * Returns an array of two-letter ISO 639-1 language codes, either from ICU or our cache.
    */
@@ -63,12 +93,33 @@
    * Returns an array of two-letter ISO 3166 country codes, either from ICU or our cache.
    */
   public static String[] getISOCountries() {
+    return getISOCountriesInternal().clone();
+  }
+
+  /**
+   * Returns true if the string is a 2-letter ISO 3166 country code.
+   */
+  public static boolean isIsoCountry(String country) {
+    if (isoCountriesSet == null) {
+      String[] isoCountries = getISOCountriesInternal();
+      Set<String> newSet = new HashSet<>(isoCountries.length);
+      for (String isoCountry : isoCountries) {
+        newSet.add(isoCountry);
+      }
+      isoCountriesSet = newSet;
+    }
+    return country != null && isoCountriesSet.contains(country);
+  }
+
+  private static String[] getISOCountriesInternal() {
     if (isoCountries == null) {
       isoCountries = getISOCountriesNative();
     }
-    return isoCountries.clone();
+    return isoCountries;
   }
 
+
+
   private static final int IDX_LANGUAGE = 0;
   private static final int IDX_SCRIPT = 1;
   private static final int IDX_REGION = 2;
@@ -268,26 +319,41 @@
     return availableLocalesCache.clone();
   }
 
+  /* package */ static String getTimePattern(Locale locale, boolean is24Hour, boolean withSecond) {
+    final String skeleton;
+    if (withSecond) {
+      skeleton = is24Hour ? "Hms" : "hms";
+    } else {
+      skeleton = is24Hour ? "Hm" : "hm";
+    }
+    return getBestDateTimePattern(skeleton, locale);
+  }
+
   @UnsupportedAppUsage
-  @libcore.api.CorePlatformApi
   public static String getBestDateTimePattern(String skeleton, Locale locale) {
     String languageTag = locale.toLanguageTag();
     String key = skeleton + "\t" + languageTag;
     synchronized (CACHED_PATTERNS) {
       String pattern = CACHED_PATTERNS.get(key);
       if (pattern == null) {
-        pattern = getBestDateTimePatternNative(skeleton, languageTag);
+        pattern = getBestDateTimePattern0(skeleton, locale);
         CACHED_PATTERNS.put(key, pattern);
       }
       return pattern;
     }
   }
 
-  @UnsupportedAppUsage
-  private static native String getBestDateTimePatternNative(String skeleton, String languageTag);
+  private static String getBestDateTimePattern0(String skeleton, Locale locale) {
+      DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance(locale);
+      return dtpg.getBestPattern(skeleton);
+  }
 
   @UnsupportedAppUsage
-  @libcore.api.CorePlatformApi
+  private static String getBestDateTimePatternNative(String skeleton, String languageTag) {
+    return getBestDateTimePattern0(skeleton, Locale.forLanguageTag(languageTag));
+  }
+
+  @UnsupportedAppUsage
   public static char[] getDateFormatOrder(String pattern) {
     char[] result = new char[3];
     int resultIndex = 0;
@@ -329,13 +395,152 @@
     return result;
   }
 
+  /**
+   * {@link java.time.format.DateTimeFormatter} does not handle some date symbols, e.g. 'B' / 'b',
+   * and thus we use a heuristic algorithm to remove the symbol. See http://b/174804526.
+   * See {@link #transformIcuDateTimePattern(String)} for documentation about the implementation.
+   */
+  public static String transformIcuDateTimePattern_forJavaTime(String pattern) {
+    return transformIcuDateTimePattern(pattern);
+  }
+
+  /**
+   * {@link java.text.SimpleDateFormat} does not handle some date symbols, e.g. 'B' / 'b',
+   * and simply ignore the symbol in formatting. Instead, we should avoid exposing the symbol
+   * entirely in all public APIs, e.g. {@link java.text.SimpleDateFormat#toPattern()},
+   * and thus we use a heuristic algorithm to remove the symbol. See http://b/174804526.
+   * See {@link #transformIcuDateTimePattern(String)} for documentation about the implementation.
+   */
+  public static String transformIcuDateTimePattern_forJavaText(String pattern) {
+    return transformIcuDateTimePattern(pattern);
+  }
+
+  /**
+   * Rewrite the date/time pattern coming ICU to be consumed by libcore classes.
+   * It's an ideal place to rewrite the pattern entirely when multiple symbols not digested
+   * by libcore need to be removed/processed. Rewriting in single place could be more efficient
+   * in a small or constant number of scans instead of scanning for every symbol.
+   *
+   * {@link LocaleData#initLocaleData(Locale)} also rewrites time format, but only a subset of
+   * patterns. In the future, that should migrate to this function in order to handle the symbols
+   * in one place, but now separate because java.text and java.time handles different sets of
+   * symbols.
+   */
+  private static String transformIcuDateTimePattern(String pattern) {
+    if (pattern == null) {
+      return null;
+    }
+
+    // For details about the different symbols, see
+    // http://cldr.unicode.org/translation/date-time-1/date-time-patterns#TOC-Day-period-patterns
+    // The symbols B means "Day periods with locale-specific ranges".
+    // English example: 2:00 at night, 10:00 in the morning, 12:00 in the afternoon.
+    boolean contains_B = pattern.indexOf('B') != -1;
+    // AM, PM, noon and midnight. English example: 10:00 AM, 12:00 noon, 7:00 PM
+    boolean contains_b = pattern.indexOf('b') != -1;
+
+    // Simply remove the symbol 'B' and 'b' if 24-hour 'H' exists because the 24-hour format
+    // provides enough information and the day periods are optional. See http://b/174804526.
+    // Don't handle symbol 'B'/'b' with 12-hour 'h' because it's much more complicated because
+    // we likely need to replace 'B'/'b' with 'a' inserted into a new right position or use other
+    // ways.
+    boolean remove_B_and_b = (contains_B || contains_b) && (pattern.indexOf('H') != -1);
+
+    if (remove_B_and_b) {
+      pattern = rewriteIcuDateTimePattern(pattern);
+    }
+    return pattern;
+  }
+
+  /**
+   * Rewrite pattern with heuristics. It's known to
+   *   - Remove 'b' and 'B' from simple patterns, e.g. "B H:mm" and "dd-MM-yy B HH:mm:ss" only.
+   *   - (Append the new heuristics)
+   */
+  private static String rewriteIcuDateTimePattern(String pattern) {
+    // The below implementation can likely be replaced by a regular expression via
+    // String.replaceAll(). However, it's known that libcore's regex implementation is more
+    // memory-intensive, and the below implementation is likely cheaper, but it's not yet measured.
+    StringBuilder sb = new StringBuilder(pattern.length());
+    char prev = ' '; // the initial value is not used.
+    for (int i = 0; i < pattern.length(); i++) {
+      char curr = pattern.charAt(i);
+      switch(curr) {
+        case 'B':
+        case 'b':
+          // Ignore 'B' and 'b'
+          break;
+        case ' ': // Ascii whitespace
+          // caveat: Ideally it's a case for all Unicode whitespaces by UCharacter.isUWhiteSpace(c)
+          // but checking ascii whitespace only is enough for the CLDR data when this is written.
+          if (i != 0 && (prev == 'B' || prev == 'b')) {
+            // Ignore the whitespace behind the symbol 'B'/'b' because it's likely a whitespace to
+            // separate the day period with the next text.
+          } else {
+            sb.append(curr);
+          }
+          break;
+        default:
+          sb.append(curr);
+          break;
+      }
+      prev = curr;
+    }
+
+    // Remove the trailing whitespace which is likely following the symbol 'B'/'b' in the original
+    // pattern, e.g. "hh:mm B" (12:00 in the afternoon).
+    int lastIndex = sb.length() - 1;
+    if (lastIndex >= 0 && sb.charAt(lastIndex) == ' ') {
+      sb.deleteCharAt(lastIndex);
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Returns the version of the CLDR data in use, such as "22.1.1".
+   *
+   */
+  public static native String getCldrVersion();
+
+  /**
+   * Returns the icu4c version in use, such as "50.1.1".
+   */
+  public static native String getIcuVersion();
+
+  /**
+   * Returns the Unicode version our ICU supports, such as "6.2".
+   */
+  public static native String getUnicodeVersion();
+
   // --- Errors.
 
   // --- Native methods accessing ICU's database.
 
   private static native String[] getAvailableLocalesNative();
 
-  public static native String getCurrencyCode(String countryCode);
+    /**
+     * Query ICU for the currency being used in the country right now.
+     * @param countryCode ISO 3166 two-letter country code
+     * @return ISO 4217 3-letter currency code if found, otherwise null.
+     */
+  public static String getCurrencyCode(String countryCode) {
+      // Fail fast when country code is not valid.
+      if (countryCode == null || countryCode.length() == 0) {
+          return null;
+      }
+      final ULocale countryLocale;
+      try {
+          countryLocale = new ULocale.Builder().setRegion(countryCode).build();
+      } catch (IllformedLocaleException e) {
+          return null; // Return null on invalid country code.
+      }
+      String[] isoCodes = Currency.getAvailableCurrencyCodes(countryLocale, new Date());
+      if (isoCodes == null || isoCodes.length == 0) {
+        return null;
+      }
+      return isoCodes[0];
+  }
+
 
   public static native String getISO3Country(String languageTag);
 
@@ -373,15 +578,25 @@
   private static native String[] getISOLanguagesNative();
   private static native String[] getISOCountriesNative();
 
-  static native boolean initLocaleDataNative(String languageTag, LocaleData result);
-
   /**
    * Takes a BCP-47 language tag (Locale.toLanguageTag()). e.g. en-US, not en_US
    */
-  public static native void setDefaultLocale(String languageTag);
+  public static void setDefaultLocale(String languageTag) {
+    LocaleNative.setDefault(languageTag);
+  }
 
   /**
    * Returns a locale name, not a BCP-47 language tag. e.g. en_US not en-US.
    */
   public static native String getDefaultLocale();
+
+
+  /**
+   * @param calendarType LDML-defined legacy calendar type. See keyTypeData.txt in ICU.
+   */
+  public static ExtendedCalendar getExtendedCalendar(Locale locale, String calendarType) {
+      ULocale uLocale = ULocale.forLocale(locale)
+              .setKeywordValue("calendar", calendarType);
+      return ExtendedCalendar.getInstance(uLocale);
+  }
 }
diff --git a/luni/src/main/java/libcore/icu/LocaleData.java b/luni/src/main/java/libcore/icu/LocaleData.java
index 12b978de..04170a6 100644
--- a/luni/src/main/java/libcore/icu/LocaleData.java
+++ b/luni/src/main/java/libcore/icu/LocaleData.java
@@ -20,17 +20,23 @@
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.compat.Compatibility;
-import android.icu.impl.ICUData;
-import android.icu.impl.ICUResourceBundle;
+import android.icu.text.DateFormatSymbols;
+import android.icu.text.DecimalFormat;
+import android.icu.text.DecimalFormatSymbols;
+import android.icu.text.NumberFormat;
 import android.icu.text.NumberingSystem;
-import android.icu.util.UResourceBundle;
+import android.icu.util.Calendar;
+import android.icu.util.GregorianCalendar;
+import android.icu.util.ULocale;
+
+import com.android.icu.text.ExtendedDecimalFormatSymbols;
+import com.android.icu.util.ExtendedCalendar;
 
 import dalvik.system.VMRuntime;
 
 import java.text.DateFormat;
 import java.util.HashMap;
 import java.util.Locale;
-import java.util.MissingResourceException;
 import libcore.util.Objects;
 
 /**
@@ -41,7 +47,6 @@
  * them a clone rather than the original.
  * @hide
  */
-@libcore.api.CorePlatformApi
 public final class LocaleData {
 
     /**
@@ -49,6 +54,7 @@
      */
     private static final Locale LOCALE_EN_US_POSIX = new Locale("en", "US", "POSIX");
 
+
     // In Android Q or before, when this class tries to load {@link Locale#ROOT} data, en_US_POSIX
     // locale data is incorrectly loaded due to a bug b/159514442 (public bug b/159047832).
     //
@@ -95,51 +101,35 @@
 
     // 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".
+    // today and tomorrow is only kept for @UnsupportedAppUsage.
+    // Their value is hard-coded, not localized.
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
     public String today; // "Today".
     @UnsupportedAppUsage
     public String tomorrow; // "Tomorrow".
@@ -154,28 +144,15 @@
     public String mediumDateFormat;
     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.
-    // They are also used directly by frameworks code.
+    // timeFormat_hm and timeFormat_Hm are only kept for @UnsupportedAppUsage.
+    // Their value is hard-coded, not localized.
     @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;
@@ -187,9 +164,6 @@
     public String exponentSeparator;
     public String infinity;
     public String NaN;
-    // Also used by Currency.
-    public String currencySymbol;
-    public String internationalCurrencySymbol;
 
     // Used by DecimalFormat and NumberFormat.
     public String numberPattern;
@@ -197,7 +171,14 @@
     public String currencyPattern;
     public String percentPattern;
 
-    private LocaleData() {
+    private final Locale mLocale;
+
+    private LocaleData(Locale locale) {
+        mLocale = locale;
+        today = "Today";
+        tomorrow = "Tomorrow";
+        timeFormat_hm = "h:mm a";
+        timeFormat_Hm = "HH:mm";
     }
 
     @UnsupportedAppUsage
@@ -236,7 +217,6 @@
      * 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");
@@ -266,7 +246,6 @@
         return Objects.toString(this);
     }
 
-    @libcore.api.CorePlatformApi
     public String getDateFormat(int style) {
         switch (style) {
         case DateFormat.SHORT:
@@ -282,18 +261,22 @@
     }
 
     public String getTimeFormat(int style) {
+        // Do not cache ICU.getTimePattern() return value in the LocaleData instance
+        // because most users do not enable this setting, hurts performance in critical path,
+        // e.g. b/161846393, and ICU.getBestDateTimePattern will cache it in  ICU.CACHED_PATTERNS
+        // on demand.
         switch (style) {
         case DateFormat.SHORT:
             if (DateFormat.is24Hour == null) {
                 return shortTimeFormat;
             } else {
-                return DateFormat.is24Hour ? timeFormat_Hm : timeFormat_hm;
+                return ICU.getTimePattern(mLocale, DateFormat.is24Hour, false);
             }
         case DateFormat.MEDIUM:
             if (DateFormat.is24Hour == null) {
                 return mediumTimeFormat;
             } else {
-                return DateFormat.is24Hour ? timeFormat_Hms : timeFormat_hms;
+                return ICU.getTimePattern(mLocale, DateFormat.is24Hour, true);
             }
         case DateFormat.LONG:
             // CLDR doesn't really have anything we can use to obey the 12-/24-hour preference.
@@ -305,21 +288,20 @@
         throw new AssertionError();
     }
 
-    private static LocaleData initLocaleData(Locale locale) {
-        LocaleData localeData = new LocaleData();
-        if (!ICU.initLocaleDataNative(locale.toLanguageTag(), localeData)) {
-            throw new AssertionError("couldn't initialize LocaleData for locale " + locale);
-        }
+    /*
+     * This method is made public for testing
+     */
+    public static LocaleData initLocaleData(Locale locale) {
+        LocaleData localeData = new LocaleData(locale);
+
+        localeData.initializeDateTimePatterns(locale);
+        localeData.initializeDateFormatData(locale);
+        localeData.initializeDecimalFormatData(locale);
+        localeData.initializeCalendarData(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);
-        localeData.timeFormat_hms = ICU.getBestDateTimePattern("hms", locale);
-        localeData.timeFormat_Hms = ICU.getBestDateTimePattern("Hms", locale);
-
         // Fix up a couple of patterns.
         if (localeData.fullTimeFormat != null) {
             // There are some full time format patterns in ICU that use the pattern character 'v'.
@@ -343,36 +325,18 @@
 
     // Libcore localizes pattern separator while ICU doesn't. http://b/112080617
     private static void initializePatternSeparator(LocaleData localeData, Locale locale) {
-        NumberingSystem ns = NumberingSystem.getInstance(locale);
+        ULocale uLocale = ULocale.forLocale(locale);
+        NumberingSystem ns = NumberingSystem.getInstance(uLocale);
         // 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 (ns == null || ns.getRadix() != 10 || ns.isAlgorithmic()) {
+            ns = NumberingSystem.LATIN;
         }
-
-        if (patternSeparator == null) {
-            try {
-                patternSeparator = rb.getStringWithFallback("NumberElements/latn/symbols/list");
-            } catch (MissingResourceException e) {
-                // Fallback to the default separator ';'.
-            }
-        }
+        String patternSeparator = ExtendedDecimalFormatSymbols.getInstance(uLocale, ns)
+                .getLocalizedPatternSeparator();
 
         if (patternSeparator == null || patternSeparator.isEmpty()) {
             patternSeparator = ";";
@@ -381,4 +345,95 @@
         // Pattern separator in libcore supports single java character only.
         localeData.patternSeparator = patternSeparator.charAt(0);
     }
+
+    private void initializeDateFormatData(Locale locale) {
+        DateFormatSymbols dfs = new DateFormatSymbols(GregorianCalendar.class, locale);
+
+        longMonthNames = dfs.getMonths(DateFormatSymbols.FORMAT, DateFormatSymbols.WIDE);
+        shortMonthNames = dfs.getMonths(DateFormatSymbols.FORMAT, DateFormatSymbols.ABBREVIATED);
+        tinyMonthNames = dfs.getMonths(DateFormatSymbols.FORMAT, DateFormatSymbols.NARROW);
+        longWeekdayNames = dfs.getWeekdays(DateFormatSymbols.FORMAT, DateFormatSymbols.WIDE);
+        shortWeekdayNames = dfs
+            .getWeekdays(DateFormatSymbols.FORMAT, DateFormatSymbols.ABBREVIATED);
+        tinyWeekdayNames = dfs.getWeekdays(DateFormatSymbols.FORMAT, DateFormatSymbols.NARROW);
+
+        longStandAloneMonthNames = dfs
+            .getMonths(DateFormatSymbols.STANDALONE, DateFormatSymbols.WIDE);
+        shortStandAloneMonthNames = dfs
+            .getMonths(DateFormatSymbols.STANDALONE, DateFormatSymbols.ABBREVIATED);
+        tinyStandAloneMonthNames = dfs
+            .getMonths(DateFormatSymbols.STANDALONE, DateFormatSymbols.NARROW);
+        longStandAloneWeekdayNames = dfs
+            .getWeekdays(DateFormatSymbols.STANDALONE, DateFormatSymbols.WIDE);
+        shortStandAloneWeekdayNames = dfs
+            .getWeekdays(DateFormatSymbols.STANDALONE, DateFormatSymbols.ABBREVIATED);
+        tinyStandAloneWeekdayNames = dfs
+            .getWeekdays(DateFormatSymbols.STANDALONE, DateFormatSymbols.NARROW);
+
+        amPm = dfs.getAmPmStrings();
+        eras = dfs.getEras();
+
+    }
+
+    private void initializeDecimalFormatData(Locale locale) {
+        DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(locale);
+
+        decimalSeparator = dfs.getDecimalSeparator();
+        groupingSeparator = dfs.getGroupingSeparator();
+        patternSeparator = dfs.getPatternSeparator();
+        percent = dfs.getPercentString();
+        perMill = dfs.getPerMillString();
+        monetarySeparator = dfs.getMonetaryDecimalSeparator();
+        minusSign = dfs.getMinusSignString();
+        exponentSeparator = dfs.getExponentSeparator();
+        infinity = dfs.getInfinity();
+        NaN = dfs.getNaN();
+        zeroDigit = dfs.getZeroDigit();
+
+        DecimalFormat df = (DecimalFormat) NumberFormat
+            .getInstance(locale, NumberFormat.NUMBERSTYLE);
+        numberPattern = df.toPattern();
+
+        df = (DecimalFormat) NumberFormat.getInstance(locale, NumberFormat.CURRENCYSTYLE);
+        currencyPattern = df.toPattern();
+
+        df = (DecimalFormat) NumberFormat.getInstance(locale, NumberFormat.PERCENTSTYLE);
+        percentPattern = df.toPattern();
+
+    }
+
+    private void initializeCalendarData(Locale locale) {
+        Calendar calendar = Calendar.getInstance(locale);
+
+        firstDayOfWeek = calendar.getFirstDayOfWeek();
+        minimalDaysInFirstWeek = calendar.getMinimalDaysInFirstWeek();
+    }
+
+    private void initializeDateTimePatterns(Locale locale) {
+        // libcore's java.text supports Gregorian calendar only.
+        ExtendedCalendar extendedCalendar = ICU.getExtendedCalendar(locale, "gregorian");
+
+        fullTimeFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.FULL);
+        longTimeFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.LONG);
+        mediumTimeFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.NONE, android.icu.text.DateFormat. MEDIUM);
+        shortTimeFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.NONE, android.icu.text.DateFormat.SHORT);
+        fullDateFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.FULL, android.icu.text.DateFormat.NONE);
+        longDateFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.LONG, android.icu.text.DateFormat.NONE);
+        mediumDateFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.MEDIUM, android.icu.text.DateFormat.NONE);
+        shortDateFormat = getDateTimeFormatString(extendedCalendar,
+            android.icu.text.DateFormat.SHORT, android.icu.text.DateFormat.NONE);
+    }
+
+    private static String getDateTimeFormatString(ExtendedCalendar extendedCalendar,
+            int dateStyle, int timeStyle) {
+        return ICU.transformIcuDateTimePattern_forJavaText(
+                extendedCalendar.getDateTimePattern(dateStyle, timeStyle));
+    }
 }
diff --git a/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java b/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
deleted file mode 100644
index 0a53ef3..0000000
--- a/luni/src/main/java/libcore/icu/RelativeDateTimeFormatter.java
+++ /dev/null
@@ -1,365 +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.icu;
-
-import java.util.Locale;
-import libcore.util.BasicLruCache;
-
-import android.icu.text.DisplayContext;
-import android.icu.util.Calendar;
-import android.icu.util.ULocale;
-
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_ALL;
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_MONTH;
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_RELATIVE;
-import static libcore.icu.DateUtilsBridge.FORMAT_NO_YEAR;
-import static libcore.icu.DateUtilsBridge.FORMAT_NUMERIC_DATE;
-import static libcore.icu.DateUtilsBridge.FORMAT_SHOW_DATE;
-import static libcore.icu.DateUtilsBridge.FORMAT_SHOW_TIME;
-import static libcore.icu.DateUtilsBridge.FORMAT_SHOW_YEAR;
-
-/**
- * Exposes icu4j's RelativeDateTimeFormatter.
- *
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class RelativeDateTimeFormatter {
-
-  public static final long SECOND_IN_MILLIS = 1000;
-  public static final long MINUTE_IN_MILLIS = SECOND_IN_MILLIS * 60;
-  public static final long HOUR_IN_MILLIS = MINUTE_IN_MILLIS * 60;
-  public static final long DAY_IN_MILLIS = HOUR_IN_MILLIS * 24;
-  public static final long WEEK_IN_MILLIS = DAY_IN_MILLIS * 7;
-  // YEAR_IN_MILLIS considers 364 days as a year. However, since this
-  // constant comes from public API in DateUtils, it cannot be fixed here.
-  public static final long YEAR_IN_MILLIS = WEEK_IN_MILLIS * 52;
-
-  private static final int DAY_IN_MS = 24 * 60 * 60 * 1000;
-  private static final int EPOCH_JULIAN_DAY = 2440588;
-
-  private static final FormatterCache CACHED_FORMATTERS = new FormatterCache();
-
-  static class FormatterCache
-      extends BasicLruCache<String, android.icu.text.RelativeDateTimeFormatter> {
-    FormatterCache() {
-      super(8);
-    }
-  }
-
-  private RelativeDateTimeFormatter() {
-  }
-
-  /**
-   * This is the internal API that implements the functionality of
-   * DateUtils.getRelativeTimeSpanString(long, long, long, int), which is to
-   * return a string describing 'time' as a time relative to 'now' such as
-   * '5 minutes ago', or 'In 2 days'. More examples can be found in DateUtils'
-   * doc.
-   *
-   * In the implementation below, it selects the appropriate time unit based on
-   * the elapsed time between time' and 'now', e.g. minutes, days and etc.
-   * Callers may also specify the desired minimum resolution to show in the
-   * result. For example, '45 minutes ago' will become '0 hours ago' when
-   * minResolution is HOUR_IN_MILLIS. Once getting the quantity and unit to
-   * display, it calls icu4j's RelativeDateTimeFormatter to format the actual
-   * string according to the given locale.
-   *
-   * Note that when minResolution is set to DAY_IN_MILLIS, it returns the
-   * result depending on the actual date difference. For example, it will
-   * return 'Yesterday' even if 'time' was less than 24 hours ago but falling
-   * onto a different calendar day.
-   *
-   * It takes two additional parameters of Locale and TimeZone than the
-   * DateUtils' API. Caller must specify the locale and timezone.
-   * FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set in 'flags' to get
-   * the abbreviated forms when available. When 'time' equals to 'now', it
-   * 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.
-    // Now we capitalize everything consistently.
-    final DisplayContext displayContext = DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE;
-    return getRelativeTimeSpanString(locale, tz, time, now, minResolution, flags, displayContext);
-  }
-
-  public static String getRelativeTimeSpanString(Locale locale, java.util.TimeZone tz, long time,
-      long now, long minResolution, int flags, DisplayContext displayContext) {
-    if (locale == null) {
-      throw new NullPointerException("locale == null");
-    }
-    if (tz == null) {
-      throw new NullPointerException("tz == null");
-    }
-    ULocale icuLocale = ULocale.forLocale(locale);
-    android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
-    return getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution, flags,
-        displayContext);
-  }
-
-  private static String getRelativeTimeSpanString(ULocale icuLocale,
-      android.icu.util.TimeZone icuTimeZone, long time, long now, long minResolution, int flags,
-      DisplayContext displayContext) {
-
-    long duration = Math.abs(now - time);
-    boolean past = (now >= time);
-
-    android.icu.text.RelativeDateTimeFormatter.Style style;
-    if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) {
-      style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT;
-    } else {
-      style = android.icu.text.RelativeDateTimeFormatter.Style.LONG;
-    }
-
-    android.icu.text.RelativeDateTimeFormatter.Direction direction;
-    if (past) {
-      direction = android.icu.text.RelativeDateTimeFormatter.Direction.LAST;
-    } else {
-      direction = android.icu.text.RelativeDateTimeFormatter.Direction.NEXT;
-    }
-
-    // 'relative' defaults to true as we are generating relative time span
-    // string. It will be set to false when we try to display strings without
-    // a quantity, such as 'Yesterday', etc.
-    boolean relative = true;
-    int count;
-    android.icu.text.RelativeDateTimeFormatter.RelativeUnit unit;
-    android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit aunit = null;
-
-    if (duration < MINUTE_IN_MILLIS && minResolution < MINUTE_IN_MILLIS) {
-      count = (int)(duration / SECOND_IN_MILLIS);
-      unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.SECONDS;
-    } else if (duration < HOUR_IN_MILLIS && minResolution < HOUR_IN_MILLIS) {
-      count = (int)(duration / MINUTE_IN_MILLIS);
-      unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.MINUTES;
-    } else if (duration < DAY_IN_MILLIS && minResolution < DAY_IN_MILLIS) {
-      // Even if 'time' actually happened yesterday, we don't format it as
-      // "Yesterday" in this case. Unless the duration is longer than a day,
-      // or minResolution is specified as DAY_IN_MILLIS by user.
-      count = (int)(duration / HOUR_IN_MILLIS);
-      unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.HOURS;
-    } else if (duration < WEEK_IN_MILLIS && minResolution < WEEK_IN_MILLIS) {
-      count = Math.abs(dayDistance(icuTimeZone, time, now));
-      unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.DAYS;
-
-      if (count == 2) {
-        // Some locales have special terms for "2 days ago". Return them if
-        // available. Note that we cannot set up direction and unit here and
-        // make it fall through to use the call near the end of the function,
-        // because for locales that don't have special terms for "2 days ago",
-        // icu4j returns an empty string instead of falling back to strings
-        // like "2 days ago".
-        String str;
-        if (past) {
-          synchronized (CACHED_FORMATTERS) {
-            str = getFormatter(icuLocale, style, displayContext)
-                .format(
-                    android.icu.text.RelativeDateTimeFormatter.Direction.LAST_2,
-                    android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
-          }
-        } else {
-          synchronized (CACHED_FORMATTERS) {
-            str = getFormatter(icuLocale, style, displayContext)
-                .format(
-                    android.icu.text.RelativeDateTimeFormatter.Direction.NEXT_2,
-                    android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY);
-          }
-        }
-        if (str != null && !str.isEmpty()) {
-          return str;
-        }
-        // Fall back to show something like "2 days ago".
-      } else if (count == 1) {
-        // Show "Yesterday / Tomorrow" instead of "1 day ago / In 1 day".
-        aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY;
-        relative = false;
-      } else if (count == 0) {
-        // Show "Today" if time and now are on the same day.
-        aunit = android.icu.text.RelativeDateTimeFormatter.AbsoluteUnit.DAY;
-        direction = android.icu.text.RelativeDateTimeFormatter.Direction.THIS;
-        relative = false;
-      }
-    } else if (minResolution == WEEK_IN_MILLIS) {
-      count = (int)(duration / WEEK_IN_MILLIS);
-      unit = android.icu.text.RelativeDateTimeFormatter.RelativeUnit.WEEKS;
-    } else {
-      Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time);
-      // The duration is longer than a week and minResolution is not
-      // WEEK_IN_MILLIS. Return the absolute date instead of relative time.
-
-      // Bug 19822016:
-      // If user doesn't supply the year display flag, we need to explicitly
-      // set that to show / hide the year based on time and now. Otherwise
-      // formatDateRange() would determine that based on the current system
-      // time and may give wrong results.
-      if ((flags & (FORMAT_NO_YEAR | FORMAT_SHOW_YEAR)) == 0) {
-        Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, now);
-
-        if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
-          flags |= FORMAT_SHOW_YEAR;
-        } else {
-          flags |= FORMAT_NO_YEAR;
-        }
-      }
-      return DateTimeFormat.format(icuLocale, timeCalendar, flags, displayContext);
-    }
-
-    synchronized (CACHED_FORMATTERS) {
-      android.icu.text.RelativeDateTimeFormatter formatter =
-          getFormatter(icuLocale, style, displayContext);
-      if (relative) {
-        return formatter.format(count, direction, unit);
-      } else {
-        return formatter.format(direction, aunit);
-      }
-    }
-  }
-
-  /**
-   * This is the internal API that implements
-   * DateUtils.getRelativeDateTimeString(long, long, long, long, int), which is
-   * to return a string describing 'time' as a time relative to 'now', formatted
-   * like '[relative time/date], [time]'. More examples can be found in
-   * DateUtils' doc.
-   *
-   * The function is similar to getRelativeTimeSpanString, but it always
-   * appends the absolute time to the relative time string to return
-   * '[relative time/date clause], [absolute time clause]'. It also takes an
-   * extra parameter transitionResolution to determine the format of the date
-   * clause. When the elapsed time is less than the transition resolution, it
-   * displays the relative time string. Otherwise, it gives the absolute
-   * numeric date string as the date clause. With the date and time clauses, it
-   * relies on icu4j's RelativeDateTimeFormatter::combineDateAndTime() to
-   * concatenate the two.
-   *
-   * It takes two additional parameters of Locale and TimeZone than the
-   * DateUtils' API. Caller must specify the locale and timezone.
-   * FORMAT_ABBREV_RELATIVE or FORMAT_ABBREV_ALL can be set in 'flags' to get
-   * the abbreviated forms when they are available.
-   *
-   * Bug 5252772: Since the absolute time will always be part of the result,
-   * minResolution will be set to at least DAY_IN_MILLIS to correctly indicate
-   * the date difference. For example, when it's 1:30 AM, it will return
-   * 'Yesterday, 11:30 PM' for getRelativeDateTimeString(null, null,
-   * 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) {
-
-    if (locale == null) {
-      throw new NullPointerException("locale == null");
-    }
-    if (tz == null) {
-      throw new NullPointerException("tz == null");
-    }
-    ULocale icuLocale = ULocale.forLocale(locale);
-    android.icu.util.TimeZone icuTimeZone = DateUtilsBridge.icuTimeZone(tz);
-
-    long duration = Math.abs(now - time);
-    // It doesn't make much sense to have results like: "1 week ago, 10:50 AM".
-    if (transitionResolution > WEEK_IN_MILLIS) {
-        transitionResolution = WEEK_IN_MILLIS;
-    }
-    android.icu.text.RelativeDateTimeFormatter.Style style;
-    if ((flags & (FORMAT_ABBREV_RELATIVE | FORMAT_ABBREV_ALL)) != 0) {
-        style = android.icu.text.RelativeDateTimeFormatter.Style.SHORT;
-    } else {
-        style = android.icu.text.RelativeDateTimeFormatter.Style.LONG;
-    }
-
-    Calendar timeCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, time);
-    Calendar nowCalendar = DateUtilsBridge.createIcuCalendar(icuTimeZone, icuLocale, now);
-
-    int days = Math.abs(DateUtilsBridge.dayDistance(timeCalendar, nowCalendar));
-
-    // Now get the date clause, either in relative format or the actual date.
-    String dateClause;
-    if (duration < transitionResolution) {
-      // This is to fix bug 5252772. If there is any date difference, we should
-      // promote the minResolution to DAY_IN_MILLIS so that it can display the
-      // date instead of "x hours/minutes ago, [time]".
-      if (days > 0 && minResolution < DAY_IN_MILLIS) {
-         minResolution = DAY_IN_MILLIS;
-      }
-      dateClause = getRelativeTimeSpanString(icuLocale, icuTimeZone, time, now, minResolution,
-          flags, DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE);
-    } else {
-      // We always use fixed flags to format the date clause. User-supplied
-      // flags are ignored.
-      if (timeCalendar.get(Calendar.YEAR) != nowCalendar.get(Calendar.YEAR)) {
-        // Different years
-        flags = FORMAT_SHOW_DATE | FORMAT_SHOW_YEAR | FORMAT_NUMERIC_DATE;
-      } else {
-        // Default
-        flags = FORMAT_SHOW_DATE | FORMAT_NO_YEAR | FORMAT_ABBREV_MONTH;
-      }
-
-      dateClause = DateTimeFormat.format(icuLocale, timeCalendar, flags,
-          DisplayContext.CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE);
-    }
-
-    String timeClause = DateTimeFormat.format(icuLocale, timeCalendar, FORMAT_SHOW_TIME,
-        DisplayContext.CAPITALIZATION_NONE);
-
-    // icu4j also has other options available to control the capitalization. We are currently using
-    // the _NONE option only.
-    DisplayContext capitalizationContext = DisplayContext.CAPITALIZATION_NONE;
-
-    // Combine the two clauses, such as '5 days ago, 10:50 AM'.
-    synchronized (CACHED_FORMATTERS) {
-      return getFormatter(icuLocale, style, capitalizationContext)
-              .combineDateAndTime(dateClause, timeClause);
-    }
-  }
-
-  /**
-   * getFormatter() caches the RelativeDateTimeFormatter instances based on
-   * the combination of localeName, sytle and capitalizationContext. It
-   * should always be used along with the action of the formatter in a
-   * synchronized block, because otherwise the formatter returned by
-   * getFormatter() may have been evicted by the time of the call to
-   * formatter->action().
-   */
-  private static android.icu.text.RelativeDateTimeFormatter getFormatter(
-      ULocale locale, android.icu.text.RelativeDateTimeFormatter.Style style,
-      DisplayContext displayContext) {
-    String key = locale + "\t" + style + "\t" + displayContext;
-    android.icu.text.RelativeDateTimeFormatter formatter = CACHED_FORMATTERS.get(key);
-    if (formatter == null) {
-      formatter = android.icu.text.RelativeDateTimeFormatter.getInstance(
-          locale, null, style, displayContext);
-      CACHED_FORMATTERS.put(key, formatter);
-    }
-    return formatter;
-  }
-
-  // Return the date difference for the two times in a given timezone.
-  private static int dayDistance(android.icu.util.TimeZone icuTimeZone, long startTime,
-      long endTime) {
-    return julianDay(icuTimeZone, endTime) - julianDay(icuTimeZone, startTime);
-  }
-
-  private static int julianDay(android.icu.util.TimeZone icuTimeZone, long time) {
-    long utcMs = time + icuTimeZone.getOffset(time);
-    return (int) (utcMs / DAY_IN_MS) + EPOCH_JULIAN_DAY;
-  }
-}
diff --git a/luni/src/main/java/libcore/icu/TimeZoneNames.java b/luni/src/main/java/libcore/icu/TimeZoneNames.java
index ec0fb8e..8e27ca9 100644
--- a/luni/src/main/java/libcore/icu/TimeZoneNames.java
+++ b/luni/src/main/java/libcore/icu/TimeZoneNames.java
@@ -16,6 +16,7 @@
 
 package libcore.icu;
 
+import com.android.icu.text.TimeZoneNamesNative;
 import java.util.Arrays;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -51,14 +52,8 @@
         @Override protected String[][] create(Locale locale) {
             long start = System.nanoTime();
 
-            // Set up the 2D array used to hold the names. The first column contains the Olson ids.
-            String[][] result = new String[availableTimeZoneIds.length][5];
-            for (int i = 0; i < availableTimeZoneIds.length; ++i) {
-                result[i][0] = availableTimeZoneIds[i];
-            }
-
             long nativeStart = System.nanoTime();
-            fillZoneStrings(locale.toLanguageTag(), result);
+            String[][] result = TimeZoneNamesNative.getFilledZoneStrings(locale, availableTimeZoneIds);
             long nativeEnd = System.nanoTime();
 
             addOffsetStrings(result);
@@ -151,5 +146,16 @@
         return cachedZoneStrings.get(locale);
     }
 
-    private static native void fillZoneStrings(String locale, String[][] result);
+    /**
+     * A utility method to get display names in various {@param namesTypes} from
+     * ICU4J's {@param timeZoneNames}.
+     */
+    public static void getDisplayNames(android.icu.text.TimeZoneNames timeZoneNames, String tzId,
+            android.icu.text.TimeZoneNames.NameType[] nameTypes, long date, String[] names,
+            int namesOffset) {
+        for (int i = 0; i < nameTypes.length; i++) {
+            android.icu.text.TimeZoneNames.NameType nameType = nameTypes[i];
+            names[namesOffset + i] = timeZoneNames.getDisplayName(tzId, nameType, date);
+        }
+    }
 }
diff --git a/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
index 7e201d0..7942307 100644
--- a/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
+++ b/luni/src/main/java/libcore/internal/Java9LanguageFeatures.java
@@ -27,7 +27,7 @@
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
- * Proof of concept / dummy code whose only purpose is to demonstrate that Java 9
+ * Proof of concept / fake code whose only purpose is to demonstrate that Java 9
  * language features are supported in libcore.
  */
 public class Java9LanguageFeatures {
diff --git a/luni/src/main/java/libcore/internal/StringPool.java b/luni/src/main/java/libcore/internal/StringPool.java
index 546a404..fccc354 100644
--- a/luni/src/main/java/libcore/internal/StringPool.java
+++ b/luni/src/main/java/libcore/internal/StringPool.java
@@ -23,12 +23,10 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
 public final class StringPool {
 
     private final String[] pool = new String[512];
 
-    @libcore.api.CorePlatformApi
     public StringPool() {
     }
 
@@ -47,7 +45,6 @@
     /**
      * 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/BlockGuardOs.java b/luni/src/main/java/libcore/io/BlockGuardOs.java
old mode 100644
new mode 100755
index f3793d6..5b331b1
--- a/luni/src/main/java/libcore/io/BlockGuardOs.java
+++ b/luni/src/main/java/libcore/io/BlockGuardOs.java
@@ -23,6 +23,7 @@
 import android.system.OsConstants;
 import android.system.StructAddrinfo;
 import android.system.StructLinger;
+import android.system.StructMsghdr;
 import android.system.StructPollfd;
 import android.system.StructStat;
 import android.system.StructStatVfs;
@@ -59,9 +60,11 @@
     }
 
     @Override public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException {
-        BlockGuard.getThreadPolicy().onNetwork();
+        if (!(isUnixSocket(fd) && isNonBlockingFile(fd))) {
+            BlockGuard.getThreadPolicy().onNetwork();
+        }
         final FileDescriptor acceptFd = super.accept(fd, peerAddress);
-        if (isInetSocket(acceptFd)) {
+        if (acceptFd != null && isInetSocket(acceptFd)) {
             tagSocket(acceptFd);
         }
         return acceptFd;
@@ -110,6 +113,22 @@
         super.close(fd);
     }
 
+    public static boolean isNonBlockingFile(FileDescriptor fd) throws ErrnoException {
+        int flag = android.system.Os.fcntlInt(fd, F_GETFL, 0);
+        if ((flag & O_NONBLOCK) != 0) {
+            return true;
+        }
+        return false;
+    }
+
+    public static boolean isUnixSocket(FileDescriptor fd) throws ErrnoException {
+        return isUnixDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN));
+    }
+
+    private static boolean isUnixDomain(int domain) {
+        return (domain == AF_UNIX);
+    }
+
     private static boolean isInetSocket(FileDescriptor fd) throws ErrnoException{
         return isInetDomain(Libcore.os.getsockoptInt(fd, SOL_SOCKET, SO_DOMAIN));
     }
@@ -335,6 +354,11 @@
         return super.recvfrom(fd, bytes, byteOffset, byteCount, flags, srcAddress);
     }
 
+    @Override public int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException {
+        BlockGuard.getThreadPolicy().onNetwork();
+        return super.recvmsg(fd, msg, flags);
+    }
+
     @UnsupportedAppUsage
     @Override public void remove(String path) throws ErrnoException {
         BlockGuard.getThreadPolicy().onWriteToDisk();
@@ -355,6 +379,11 @@
         return super.sendfile(outFd, inFd, offset, byteCount);
     }
 
+    @Override public int sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException {
+        BlockGuard.getThreadPolicy().onNetwork();
+        return super.sendmsg(fd, msg, flags);
+    }
+
     @Override public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
         BlockGuard.getThreadPolicy().onNetwork();
         return super.sendto(fd, buffer, flags, inetAddress, port);
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
old mode 100644
new mode 100755
index f9fb2d4..4ae124e
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -26,6 +26,7 @@
 import android.system.StructGroupReq;
 import android.system.StructIfaddrs;
 import android.system.StructLinger;
+import android.system.StructMsghdr;
 import android.system.StructPasswd;
 import android.system.StructPollfd;
 import android.system.StructRlimit;
@@ -45,19 +46,27 @@
 import java.nio.ByteBuffer;
 import java.util.Objects;
 
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
 /**
  * Subclass this if you want to override some {@link Os} methods but otherwise delegate.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class ForwardingOs implements Os {
     @UnsupportedAppUsage
     private final Os os;
 
+    /**
+     * Constructs new {@link ForwardingOs}.
+     *
+     * @param os {@link Os} delegate for not overridden methods
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    protected ForwardingOs(Os os) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    protected ForwardingOs(@NonNull Os os) {
         this.os = Objects.requireNonNull(os);
     }
 
@@ -67,9 +76,37 @@
     }
 
     public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException { return os.accept(fd, peerAddress); }
+
+    /**
+     * Checks whether the calling process can access the file
+     * {@code path}. If {@code path} is a symbolic link, it is dereferenced.
+     *
+     * The mode specifies the accessibility check(s) to be performed,
+     * and is either the value {@link android.system.OsConstants#F_OK},
+     * or a mask consisting of the bitwise OR of one or more of
+     * {@link android.system.OsConstants#R_OK}, {@link android.system.OsConstants#W_OK},
+     * and {@link android.system.OsConstants#X_OK}.
+     *
+     * {@link android.system.OsConstants#F_OK} tests for the
+     * existence of the file. {@link android.system.OsConstants#R_OK},
+     * {@link android.system.OsConstants#W_OK}, and {@link android.system.OsConstants#X_OK}
+     * test whether the file exists and grants read, write, and execute permissions, respectively.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man2/access.2.html">access(2)</a>.
+     *
+     * @param path path of the file to check access for
+     * @param mode accessibility checks mask
+     * @return {@code true} if file is accessible (all requested permissions granted,
+     *         or mode is {@link android.system.OsConstants#F_OK} and the file exists));
+     *         and throws otherwise
+     * @throws ErrnoException if at least one bit in mode asked for a permission that is denied,
+     *                        or mode is {@link android.system.OsConstants#F_OK} and the file
+     *                        does not exist, or some other error occurred. See the full list
+     *                        of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public boolean access(String path, int mode) throws ErrnoException { return os.access(path, mode); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public boolean access(@Nullable 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); }
     public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
@@ -137,7 +174,7 @@
     public InetAddress inet_pton(int family, String address) { return os.inet_pton(family, address); }
     public int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException { return os.ioctlFlags(fd, interfaceName); };
     public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException { return os.ioctlInetAddress(fd, cmd, interfaceName); }
-    public int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException { return os.ioctlInt(fd, cmd, arg); }
+    public int ioctlInt(FileDescriptor fd, int cmd) throws ErrnoException { return os.ioctlInt(fd, cmd); }
     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); }
@@ -161,9 +198,45 @@
     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); }
+
+    /**
+     * Opens the file specified by {@code path}.
+     *
+     * If the specified file does not exist, it may optionally (if
+     * {@link android.system.OsConstants#O_CREAT} is specified in flags)
+     * be created by {@link #open(String, int, int)}.
+     *
+     * The argument flags must include one of the following access
+     * modes: {@link android.system.OsConstants#O_RDONLY},
+     * {@link android.system.OsConstants#O_WRONLY}, or
+     * {@link android.system.OsConstants#O_RDWR}. These request opening the
+     * file read-only, write-only, or read/write, respectively.
+     *
+     * In addition, zero or more file creation flags and file status
+     * flags can be bitwise-or'd in flags. The file creation flags are
+     * {@link android.system.OsConstants#O_CLOEXEC}, {@link android.system.OsConstants#O_CREAT},
+     * {@link android.system.OsConstants#O_DIRECTORY}, {@link android.system.OsConstants#O_EXCL},
+     * {@link android.system.OsConstants#O_NOCTTY}, {@link android.system.OsConstants#O_NOFOLLOW},
+     * {@link android.system.OsConstants#O_TMPFILE}, and {@link android.system.OsConstants#O_TRUNC}.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man2/open.2.html">open(2)</a>.
+     *
+     * @param path  path of the file to be opened
+     * @param flags bitmask of the access, file creation and file status flags
+     * @param mode  specifies the file mode bits to be applied when a new file is
+     *              created. If neither {@link android.system.OsConstants#O_CREAT}
+     *              nor {@link android.system.OsConstants#O_TMPFILE} is specified in
+     *              flags, then mode is ignored (and can thus be specified as 0, or simply omitted).
+     * @return {@link FileDescriptor} of an opened file
+     * @throws ErrnoException if requested access to the file is not allowed, or search
+     *                        permission is denied for one of the directories in the
+     *                        path prefix of {@code path}, or the file did not exist yet and
+     *                        write access to the parent directory is not allowed, or other error.
+     *                        See the full list of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public FileDescriptor open(String path, int flags, int mode) throws ErrnoException { return os.open(path, flags, mode); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public FileDescriptor open(@Nullable 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); }
     public void posix_fallocate(FileDescriptor fd, long offset, long length) throws ErrnoException { os.posix_fallocate(fd, offset, length); }
@@ -180,15 +253,55 @@
     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); }
+    public int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { return os.recvmsg(fd, msg, flags); }
+
+    /**
+     * Deletes a name from the filesystem.
+     *
+     * If the removed name was the last link to a file and no processes
+     * have the file open, the file is deleted and the space it was
+     * using is made available for reuse.
+     *
+     * If the name was the last link to a file, but any processes still
+     * have the file open, the file will remain in existence until the
+     * last file descriptor referring to it is closed.
+     *
+     * If the name referred to a symbolic link, the link is removed.
+     *
+     * If the name referred to a socket, FIFO, or device, the name is
+     * removed, but processes which have the object open may continue to
+     * use it.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man3/remove.3.html">remove(3)</a>.
+     *
+     * @param path file to delete
+     * @throws ErrnoException if access to {@code path} is not allowed, an I/O error occurred.
+     *                        See the full list of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public void remove(String path) throws ErrnoException { os.remove(path); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public void remove(@Nullable String path) throws ErrnoException { os.remove(path); }
     @UnsupportedAppUsage
     public void removexattr(String path, String name) throws ErrnoException { os.removexattr(path, name); }
+
+    /**
+     * Renames a file, moving it between directories if required.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man2/rename.2.html">rename(2)</a>.
+     *
+     * @param oldPath file to be moved to a new location {@code newPath}
+     * @param newPath destination to move file {@code oldPath}
+     * @throws ErrnoException if write permission is denied for the directory containing
+     *                        {@code oldPath} or {@code newPath}, or, search permission is denied for
+     *                        one of the directories in the path prefix of {@code oldPath} or
+     *                        {@code newPath}, or {@code oldPath} is a directory and does not allow
+     *                        write permission. See the full list of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public void rename(String oldPath, String newPath) throws ErrnoException { os.rename(oldPath, newPath); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public void rename(@Nullable String oldPath, @Nullable 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 sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException { return os.sendmsg(fd, msg, flags); }
     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); }
@@ -216,9 +329,19 @@
     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); }
+
+    /**
+     * Returns information about a file.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man2/lstat.2.html">stat(2)</a>.
+     *
+     * @param path path to file to get info about
+     * @return {@link StructStat} containing information about the file
+     * @throws ErrnoException See the full list of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public StructStat stat(String path) throws ErrnoException { return os.stat(path); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public @Nullable StructStat stat(@Nullable 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); }
@@ -231,9 +354,33 @@
     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(); }
+
+    /**
+     * Deletes a name from the filesystem.
+     *
+     * If the removed name was the last link to a file and no processes
+     * have the file open, the file is deleted and the space it was
+     * using is made available for reuse.
+     *
+     * If the name was the last link to a file, but any processes still
+     * have the file open, the file will remain in existence until the
+     * last file descriptor referring to it is closed.
+     *
+     * If the name referred to a symbolic link, the link is removed.
+     *
+     * If the name referred to a socket, FIFO, or device, the name is
+     * removed, but processes which have the object open may continue to
+     * use it.
+     *
+     * @see <a href="https://man7.org/linux/man-pages/man2/unlink.2.html">unlink(2)</a>.
+     *
+     * @param pathname file to unlink
+     * @throws ErrnoException if access to {@code pathname} is not allowed, an I/O error occurred.
+     *                        See the full list of errors in the "See Also" list.
+     */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public void unlink(String pathname) throws ErrnoException { os.unlink(pathname); }
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public void unlink(@Nullable 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); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index 0554d6d..7d4ca81 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -18,7 +18,6 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.system.ErrnoException;
-import android.system.Int32Ref;
 import android.system.StructGroupReq;
 import android.system.StructLinger;
 import android.system.StructPollfd;
@@ -61,18 +60,17 @@
 
     public static int available(FileDescriptor fd) throws IOException {
         try {
-            Int32Ref available = new Int32Ref(0);
-            Libcore.os.ioctlInt(fd, FIONREAD, available);
-            if (available.value < 0) {
+            int available = Libcore.os.ioctlInt(fd, FIONREAD);
+            if (available < 0) {
                 // If the fd refers to a regular file, the result is the difference between
                 // the file size and the file position. This may be negative if the position
                 // is past the end of the file. If the fd refers to a special file masquerading
                 // as a regular file, the result may be negative because the special file
                 // may appear to have zero size and yet a previous read call may have
                 // read some amount of data and caused the file position to be advanced.
-                available.value = 0;
+                available = 0;
             }
-            return available.value;
+            return available;
         } catch (ErrnoException errnoException) {
             if (errnoException.errno == ENOTTY) {
                 // The fd is unwilling to opine about its read buffer.
@@ -242,11 +240,18 @@
      */
     @libcore.api.CorePlatformApi
     public static void closeAndSignalBlockedThreads(FileDescriptor fd) throws IOException {
-        if (fd == null || !fd.valid()) {
+        if (fd == null) {
             return;
         }
-        // fd is invalid after we call release.
+
+        // fd is invalid after we call release$.
+        // If multiple threads reach this point simultaneously, release$ is synchronized, so one
+        // of them will receive the old fd, and the rest will get an empty FileDescriptor.
         FileDescriptor oldFd = fd.release$();
+        if (!oldFd.valid()) {
+            return;
+        }
+
         AsynchronousCloseMonitor.signalBlockedThreads(oldFd);
         try {
             Libcore.os.close(oldFd);
diff --git a/luni/src/main/java/libcore/io/IoUtils.java b/luni/src/main/java/libcore/io/IoUtils.java
index 4b4870b..cb2a152 100644
--- a/luni/src/main/java/libcore/io/IoUtils.java
+++ b/luni/src/main/java/libcore/io/IoUtils.java
@@ -29,7 +29,9 @@
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.Objects;
+
 import libcore.util.NonNull;
+import libcore.util.Nullable;
 
 import static android.system.OsConstants.F_GETFL;
 import static android.system.OsConstants.F_SETFL;
@@ -37,25 +39,26 @@
 import static android.system.OsConstants.O_RDONLY;
 
 /** @hide */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class IoUtils {
     private IoUtils() {
     }
 
     /**
-     * Acquires ownership of an integer file descriptor from a FileDescriptor.
+     * Acquires ownership of an integer file descriptor from a {@link FileDescriptor}.
      *
-     * This method invalidates the FileDescriptor passed in.
+     * This method invalidates the {@link 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.
+     * @param fd {@link FileDescriptor} to take ownership from, must be non-{@code null}.
+     * @return raw file descriptor
      * @throws NullPointerException if fd is null
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int acquireRawFd(@NonNull FileDescriptor fd) {
         Objects.requireNonNull(fd);
 
@@ -113,25 +116,32 @@
         // 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);
+        //
+        // If identityHashCode returns a negative int, it'll be sign-extended, so we need to apply
+        // a mask. fdsan uses bits 48-56 to distinguish between a generic native pointer and a
+        // generic Java type, but since we're only inserting 32-bits of data, we might as well mask
+        // off the entire upper 32 bits.
+        long mask = (1L << 32) - 1;
+        long tagValue = System.identityHashCode(owner) & mask;
         return tagType << 56 | tagValue;
     }
 
     /**
-     * Assigns ownership of an unowned FileDescriptor.
+     * Assigns ownership of an unowned {@link 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
+     * Associates the supplied {@link FileDescriptor} and the underlying Unix file descriptor with an owner
+     * ID derived from the supplied {@code owner} object. If the {@link 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
+     * @param fd    {@link FileDescriptor} to take ownership from, must be non-{@code null}.
+     * @param owner owner object
+     * @throws NullPointerException if {@code fd} or {@code owner} are {@code null}
+     * @throws IllegalStateException if {@code fd} is already owned
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setFdOwner(@NonNull FileDescriptor fd, @NonNull Object owner) {
         Objects.requireNonNull(fd);
         Objects.requireNonNull(owner);
@@ -150,20 +160,25 @@
     }
 
     /**
-     * Calls close(2) on 'fd'. Also resets the internal int to -1. Does nothing if 'fd' is null
-     * or invalid.
+     * Closes a file descriptor, so that it no longer refers to any file and may
+     * be reused. Also resets the internal int to -1.
+     *
+     * @param fd is {@link FileDescriptor} instance, invalid value is ignored.
+     * @throws IOException if an I/O error occurred.
      */
-    @libcore.api.CorePlatformApi
-    public static void close(FileDescriptor fd) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void close(@Nullable FileDescriptor fd) throws IOException {
         IoBridge.closeAndSignalBlockedThreads(fd);
     }
 
     /**
-     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
+     * Closes {@link AutoClosable} instance, ignoring any checked exceptions.
+     *
+     * @param close is AutoClosable instance, null value is ignored.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void closeQuietly(AutoCloseable closeable) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void closeQuietly(@Nullable AutoCloseable closeable) {
         if (closeable != null) {
             try {
                 closeable.close();
@@ -175,11 +190,13 @@
     }
 
     /**
-     * Closes 'fd', ignoring any exceptions. Does nothing if 'fd' is null or invalid.
+     * Calls {@link #close(FileDescriptor)}, ignoring any exceptions.
+     *
+     * @param fd is {@link FileDescriptor} instance, invalid value is ignored.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void closeQuietly(FileDescriptor fd) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void closeQuietly(@Nullable FileDescriptor fd) {
         try {
             IoUtils.close(fd);
         } catch (IOException ignored) {
@@ -187,25 +204,33 @@
     }
 
     /**
-     * Closes 'socket', ignoring any exceptions. Does nothing if 'socket' is null.
+     * Closes socket, ignoring any exceptions.
+     *
+     * @param socket is {@link Socket} instance, {@code null} value is ignored.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void closeQuietly(Socket socket) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void closeQuietly(@Nullable Socket socket) {
         if (socket != null) {
             try {
                 socket.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
             } catch (Exception ignored) {
             }
         }
     }
 
     /**
-     * Sets 'fd' to be blocking or non-blocking, according to the state of 'blocking'.
+     * Sets file descriptor to be blocking or non-blocking.
+     *
+     * @param fd is {@link FileDescriptor} instance
+     * @param blocking is a boolean that defines whether fd should be blocking or non-blocking
+     * @throws IOException if system API call fails
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void setBlocking(FileDescriptor fd, boolean blocking) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void setBlocking(@NonNull FileDescriptor fd, boolean blocking) throws IOException {
         try {
             int flags = Libcore.os.fcntlVoid(fd, F_GETFL);
             if (!blocking) {
@@ -220,20 +245,28 @@
     }
 
     /**
-     * Returns the contents of 'path' as a byte array.
+     * Returns the contents of {@code absolutePath} as a byte array.
+     *
+     * @param absolutePath path to a file to read
+     * @return contents of the file at {@code absolutePath} as byte array
+     * @throws IOException if there was I/O error
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static byte[] readFileAsByteArray(String absolutePath) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull byte[] readFileAsByteArray(@NonNull String absolutePath) throws IOException {
         return new FileReader(absolutePath).readFully().toByteArray();
     }
 
     /**
-     * Returns the contents of 'path' as a string. The contents are assumed to be UTF-8.
+     * Returns the contents of {@code absolutePath} as a {@link String}. The contents are assumed to be UTF-8.
+     *
+     * @param absolutePath path to a file to read
+     * @return contents of the file at {@code absolutePath} as {@link String}
+     * @throws IOException if there was I/O error
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static String readFileAsString(String absolutePath) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull String readFileAsString(@NonNull String absolutePath) throws IOException {
         return new FileReader(absolutePath).readFully().toString(StandardCharsets.UTF_8);
     }
 
diff --git a/luni/src/main/java/libcore/io/Linux.java b/luni/src/main/java/libcore/io/Linux.java
old mode 100644
new mode 100755
index 74608d3..4ecb785
--- a/luni/src/main/java/libcore/io/Linux.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -26,6 +26,7 @@
 import android.system.StructGroupReq;
 import android.system.StructIfaddrs;
 import android.system.StructLinger;
+import android.system.StructMsghdr;
 import android.system.StructPasswd;
 import android.system.StructPollfd;
 import android.system.StructRlimit;
@@ -111,7 +112,7 @@
     public native InetAddress inet_pton(int family, String address);
     public native int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException;
     public native InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
-    public native int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException;
+    public native int ioctlInt(FileDescriptor fd, int cmd) throws ErrnoException;
     public native int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException;
     public native boolean isatty(FileDescriptor fd);
     public native void kill(int pid, int signal) throws ErrnoException;
@@ -210,10 +211,12 @@
         return recvfromBytes(fd, bytes, byteOffset, byteCount, flags, srcAddress);
     }
     private native int recvfromBytes(FileDescriptor fd, Object buffer, int byteOffset, int byteCount, int flags, InetSocketAddress srcAddress) throws ErrnoException, SocketException;
+    public native int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException;
     public native void remove(String path) throws ErrnoException;
     public native void removexattr(String path, String name) throws ErrnoException;
     public native void rename(String oldPath, String newPath) throws ErrnoException;
     public native long sendfile(FileDescriptor outFd, FileDescriptor inFd, Int64Ref offset, long byteCount) throws ErrnoException;
+    public native int sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException;
     public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException {
         final int bytesSent;
         final int position = buffer.position();
diff --git a/luni/src/main/java/libcore/io/Memory.java b/luni/src/main/java/libcore/io/Memory.java
index 9e7f4ea..ac8ccb9 100644
--- a/luni/src/main/java/libcore/io/Memory.java
+++ b/luni/src/main/java/libcore/io/Memory.java
@@ -17,24 +17,33 @@
 
 package libcore.io;
 
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
 import android.compat.annotation.UnsupportedAppUsage;
+import android.annotation.SystemApi;
 
 import java.nio.ByteOrder;
 
 import dalvik.annotation.optimization.FastNative;
 
+import libcore.api.CorePlatformApi;
+import libcore.util.NonNull;
+
 /**
  * Unsafe access to memory.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+@SystemApi(client = MODULE_LIBRARIES)
 public final class Memory {
     private Memory() { }
 
     /**
      * Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array.
      * 'dstOffset' is measured in units of 'sizeofElements' bytes.
+     *
+     * @hide
      */
     public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount,
             byte[] src, int srcOffset, int sizeofElements, boolean swap);
@@ -42,12 +51,25 @@
     /**
      * Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array.
      * 'srcOffset' is measured in units of 'sizeofElements' bytes.
+     * @hide
      */
     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) {
+    /**
+     * Gets int value from a byte buffer {@code src} at offset {@code offset} using
+     * {@code order} byte order.
+     *
+     * @param src    source byte buffer
+     * @param offset offset in {@code src} to get bytes from
+     * @param order  byte order
+     * @return int value
+     *
+     * @hide
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static int peekInt(@NonNull byte[] src, int offset, @NonNull ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             return (((src[offset++] & 0xff) << 24) |
                     ((src[offset++] & 0xff) << 16) |
@@ -61,6 +83,9 @@
         }
     }
 
+    /**
+     * @hide
+     */
     public static long peekLong(byte[] src, int offset, ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             int h = ((src[offset++] & 0xff) << 24) |
@@ -85,8 +110,20 @@
         }
     }
 
-    @libcore.api.CorePlatformApi
-    public static short peekShort(byte[] src, int offset, ByteOrder order) {
+    /**
+     * Gets short value from a byte buffer {@code src} at offset {@code offset} using
+     * {@code order} byte order.
+     *
+     * @param src    source byte buffer
+     * @param offset offset in {@code src} to get bytes from
+     * @param order  byte order
+     * @return short value
+     *
+     * @hide
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static short peekShort(@NonNull byte[] src, int offset, @NonNull ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff));
         } else {
@@ -94,8 +131,20 @@
         }
     }
 
-    @libcore.api.CorePlatformApi
-    public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
+    /**
+     * Writes given int value {@code value} to a byte buffer {@code dst} using
+     * {@code order} byte order.
+     *
+     * @param dst    byte buffer where to write {@code value}
+     * @param offset offset in {@code dst} to put value to
+     * @param value  int value to write
+     * @param order  byte order
+     *
+     * @hide
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void pokeInt(@NonNull byte[] dst, int offset, int value, @NonNull ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             dst[offset++] = (byte) ((value >> 24) & 0xff);
             dst[offset++] = (byte) ((value >> 16) & 0xff);
@@ -109,8 +158,20 @@
         }
     }
 
-    @libcore.api.CorePlatformApi
-    public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) {
+    /**
+     * Writes given long value {@code value} to a byte buffer {@code dst} using
+     * {@code order} byte order.
+     *
+     * @param dst    byte buffer where to write {@code value}
+     * @param offset offset in {@code dst} to put value to
+     * @param value  long value to write
+     * @param order  byte order
+     *
+     * @hide
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void pokeLong(@NonNull byte[] dst, int offset, long value, @NonNull ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             int i = (int) (value >> 32);
             dst[offset++] = (byte) ((i >> 24) & 0xff);
@@ -136,8 +197,20 @@
         }
     }
 
-    @libcore.api.CorePlatformApi
-    public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) {
+    /**
+     * Writes given short value {@code value} to a byte buffer {@code dst} using
+     * {@code order} byte order.
+     *
+     * @param dst    byte buffer where to write {@code value}
+     * @param offset offset in {@code dst} to put value to
+     * @param value  short value to write
+     * @param order  byte order
+     *
+     * @hide
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static void pokeShort(@NonNull byte[] dst, int offset, short value, @NonNull ByteOrder order) {
         if (order == ByteOrder.BIG_ENDIAN) {
             dst[offset++] = (byte) ((value >> 8) & 0xff);
             dst[offset  ] = (byte) ((value >> 0) & 0xff);
@@ -148,22 +221,38 @@
     }
 
     /**
-     * Copies 'byteCount' bytes from the source to the destination. The objects are either
-     * instances of DirectByteBuffer or byte[]. The offsets in the byte[] case must include
-     * the Buffer.arrayOffset if the array came from a Buffer.array call. We could make this
-     * private and provide the four type-safe variants, but then ByteBuffer.put(ByteBuffer)
-     * would need to work out which to call based on whether the source and destination buffers
-     * are direct or not.
+     * Copies {@code byteCount} bytes from the source {@code srcObject} to the
+     * destination {@code dstObject}. The objects are either instances of
+     * {@code DirectByteBuffer} or {@code byte[]}. The offsets in the {@code byte[]}
+     * case must include the {@link Buffer#arrayOffset()} if the array came from a
+     * {@link Buffer#array()} call.
+     *
+     * <p>We could make this private and provide the four type-safe variants, but then
+     * {@link ByteBuffer#put(ByteBuffer)} would need to work out which to call based on
+     * whether the source and destination buffers are direct or not.
+     *
+     * @param dstObject destination buffer
+     * @param dstOffset offset in the destination buffer
+     * @param srcObject source buffer
+     * @param srcOffset offset in the source buffer
+     * @param byteCount number of bytes to copy
      *
      * @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);
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static native void memmove(@NonNull Object dstObject, int dstOffset, @NonNull Object srcObject, int srcOffset, long byteCount);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     @FastNative
     public static native byte peekByte(long address);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static int peekInt(long address, boolean swap) {
         int result = peekIntNative(address);
@@ -175,6 +264,9 @@
     @FastNative
     private static native int peekIntNative(long address);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static long peekLong(long address, boolean swap) {
         long result = peekLongNative(address);
@@ -186,6 +278,9 @@
     @FastNative
     private static native long peekLongNative(long address);
 
+    /**
+     * @hide
+     */
     public static short peekShort(long address, boolean swap) {
         short result = peekShortNative(address);
         if (swap) {
@@ -196,19 +291,52 @@
     @FastNative
     private static native short peekShortNative(long address);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount);
+
+    /**
+     * @hide
+     */
     public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void peekDoubleArray(long address, double[] dst, int dstOffset, int doubleCount, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void peekFloatArray(long address, float[] dst, int dstOffset, int floatCount, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void peekIntArray(long address, int[] dst, int dstOffset, int intCount, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void peekLongArray(long address, long[] dst, int dstOffset, int longCount, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     @FastNative
     public static native void pokeByte(long address, byte value);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static void pokeInt(long address, int value, boolean swap) {
         if (swap) {
@@ -219,6 +347,9 @@
     @FastNative
     private static native void pokeIntNative(long address, int value);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static void pokeLong(long address, long value, boolean swap) {
         if (swap) {
@@ -229,6 +360,9 @@
     @FastNative
     private static native void pokeLongNative(long address, long value);
 
+    /**
+     * @hide
+     */
     public static void pokeShort(long address, short value, boolean swap) {
         if (swap) {
             value = Short.reverseBytes(value);
@@ -238,12 +372,39 @@
     @FastNative
     private static native void pokeShortNative(long address, short value);
 
+    /**
+     * @hide
+     */
     @UnsupportedAppUsage
     public static native void pokeByteArray(long address, byte[] src, int offset, int count);
+
+    /**
+     * @hide
+     */
     public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void pokeDoubleArray(long address, double[] src, int offset, int count, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void pokeFloatArray(long address, float[] src, int offset, int count, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void pokeIntArray(long address, int[] src, int offset, int count, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void pokeLongArray(long address, long[] src, int offset, int count, boolean swap);
+
+    /**
+     * @hide
+     */
     public static native void pokeShortArray(long address, short[] src, int offset, int count, boolean swap);
 }
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
old mode 100644
new mode 100755
index 4953186..fe02877
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -26,6 +26,7 @@
 import android.system.StructGroupReq;
 import android.system.StructIfaddrs;
 import android.system.StructLinger;
+import android.system.StructMsghdr;
 import android.system.StructPasswd;
 import android.system.StructPollfd;
 import android.system.StructRlimit;
@@ -44,8 +45,17 @@
 import java.net.SocketException;
 import java.nio.ByteBuffer;
 
-/** @hide */
-@libcore.api.CorePlatformApi
+/**
+ * Linux-like operating system. The user of this interface has access to various methods
+ * that expose basic operating system functionality, like file and file descriptors operations
+ * (open, close, read, write), socket operations (connect, bind, send*, recv*), process
+ * operations (exec*, getpid), filesystem operations (mkdir, unlink, chmod, chown) and others.
+ *
+ * @see Linux
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public interface Os {
     public FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
     public boolean access(String path, int mode) throws ErrnoException;
@@ -113,7 +123,7 @@
     public InetAddress inet_pton(int family, String address);
     public int ioctlFlags(FileDescriptor fd, String interfaceName) throws ErrnoException;
     public InetAddress ioctlInetAddress(FileDescriptor fd, int cmd, String interfaceName) throws ErrnoException;
-    public int ioctlInt(FileDescriptor fd, int cmd, Int32Ref arg) throws ErrnoException;
+    public int ioctlInt(FileDescriptor fd, int cmd) throws ErrnoException;
     public int ioctlMTU(FileDescriptor fd, String interfaceName) throws ErrnoException;
     public boolean isatty(FileDescriptor fd);
     public void kill(int pid, int signal) throws ErrnoException;
@@ -153,10 +163,12 @@
     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;
+    public int recvmsg(FileDescriptor fd, StructMsghdr msg, int flags) 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;
+    public int sendmsg(FileDescriptor fd, StructMsghdr msg, int flags) throws ErrnoException, SocketException;
     public int sendto(FileDescriptor fd, ByteBuffer buffer, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
     public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, InetAddress inetAddress, int port) throws ErrnoException, SocketException;
     public int sendto(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, SocketAddress address) throws ErrnoException, SocketException;
@@ -212,7 +224,7 @@
      * @param update the new value to set; must not be null.
      * @return whether the update was successful.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean compareAndSetDefault(Os expect, Os update) {
         return Libcore.compareAndSetOs(expect, update);
     }
@@ -220,7 +232,7 @@
     /**
      * @return the system's default {@link Os} implementation currently in use.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static Os getDefault() {
         return Libcore.getOs();
     }
diff --git a/luni/src/main/java/libcore/io/Streams.java b/luni/src/main/java/libcore/io/Streams.java
index f83f5c1..cc4ec44 100644
--- a/luni/src/main/java/libcore/io/Streams.java
+++ b/luni/src/main/java/libcore/io/Streams.java
@@ -27,46 +27,65 @@
 import java.io.StringWriter;
 import java.util.concurrent.atomic.AtomicReference;
 import libcore.util.ArrayUtils;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
 
-/** @hide */
-@libcore.api.CorePlatformApi
+/**
+ * Convenience class for reading and writing streams of bytes.
+ *
+ * @hide
+ */
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final class Streams {
     private static AtomicReference<byte[]> skipBuffer = new AtomicReference<byte[]>();
 
     private Streams() {}
 
     /**
-     * Implements InputStream.read(int) in terms of InputStream.read(byte[], int, int).
-     * InputStream assumes that you implement InputStream.read(int) and provides default
+     * Implements {@link InputStream#read(int)} in terms of {@link InputStream#read(byte[], int, int)}.
+     * {@link InputStream} assumes that you implement {@link InputStream#read(int)} and provides default
      * implementations of the others, but often the opposite is more efficient.
+     *
+     * @param in {@link InputStream} to read byte from
+     * @return singlge byte read from {@code in}
+     * @throws IOException in case of I/O error
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static int readSingleByte(InputStream in) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static int readSingleByte(@NonNull InputStream in) throws IOException {
         byte[] buffer = new byte[1];
         int result = in.read(buffer, 0, 1);
         return (result != -1) ? buffer[0] & 0xff : -1;
     }
 
     /**
-     * Implements OutputStream.write(int) in terms of OutputStream.write(byte[], int, int).
-     * OutputStream assumes that you implement OutputStream.write(int) and provides default
+     * Implements {@link OutputStream#write(int)} in terms of {@link OutputStream#write(byte[], int, int)}.
+     * {@link OutputStream} assumes that you implement {@link OutputStream#write(int)} and provides default
      * implementations of the others, but often the opposite is more efficient.
+     *
+     * @param out {@link OutputStream} to write byte to
+     * @param b byte to write to stream {@code out}
+     * @throws IOException in case of I/O error
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void writeSingleByte(OutputStream out, int b) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void writeSingleByte(@NonNull OutputStream out, int b) throws IOException {
         byte[] buffer = new byte[1];
         buffer[0] = (byte) (b & 0xff);
         out.write(buffer);
     }
 
     /**
-     * Fills 'dst' with bytes from 'in', throwing EOFException if insufficient bytes are available.
+     * Fills byte buffer {@code dst} with bytes from {@link InputStream} {@code in}, throwing
+     * {@link EOFException} if insufficient bytes are available.
+     *
+     * @param in {@link InputStream} to read data from
+     * @param dst byte buffer to write data to
+     * @throws IOException in case of I/O error
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static void readFully(InputStream in, byte[] dst) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void readFully(@NonNull InputStream in, @NonNull byte[] dst) throws IOException {
         readFully(in, dst, 0, dst.length);
     }
 
@@ -98,11 +117,16 @@
     }
 
     /**
-     * Returns a byte[] containing the remainder of 'in', closing it when done.
+     * Returns a {@code byte[]} containing the remainder of {@code in} stream and
+     * closes it. Also see {@link #readFullyNoClose(InputStream)}.
+     *
+     * @param in {@link InputStream} to read data from
+     * @return remaining bytes in {@code in} stream.
+     * @throws IOException thrown by {@link InputStream#read(byte[])}.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static byte[] readFully(InputStream in) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull byte[] readFully(@NonNull InputStream in) throws IOException {
         try {
             return readFullyNoClose(in);
         } finally {
@@ -111,10 +135,15 @@
     }
 
     /**
-     * Returns a byte[] containing the remainder of 'in'.
+     * Returns a {@code byte[]} containing the remainder of {@code in} stream, without
+     * closing it.
+     *
+     * @param in {@link InputStream} to read data from
+     * @return remaining bytes in {@code in} stream.
+     * @throws IOException thrown by {@link InputStream#read(byte[])}.
      */
-    @libcore.api.CorePlatformApi
-    public static byte[] readFullyNoClose(InputStream in) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull byte[] readFullyNoClose(@NonNull InputStream in) throws IOException {
         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
         byte[] buffer = new byte[1024];
         int count;
@@ -125,10 +154,14 @@
     }
 
     /**
-     * Returns the remainder of 'reader' as a string, closing it when done.
+     * Reads the remainder of {@code reader} as a string, closing it when done.
+     *
+     * @param reader {@link Reader} instance.
+     * @return remainder of {@code reader} as {@link String}.
+     * @throws IOException thrown by {@link Reader#read(java.nio.CharBuffer)}.
      */
-    @libcore.api.CorePlatformApi
-    public static String readFully(Reader reader) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull String readFully(@NonNull Reader reader) throws IOException {
         try {
             StringWriter writer = new StringWriter();
             char[] buffer = new char[1024];
@@ -160,9 +193,14 @@
      * other threads. A thread-local buffer is also insufficient because some
      * streams may call other streams in their skip() method, also clobbering the
      * buffer.
+     *
+     * @param in {@link InputStream} to skip data from
+     * @param byteCount number of bytes to skip from {@code in}
+     * @return number of bytes skipped from {@code in}
+     * @throws IOException in case of I/O error
      */
-    @libcore.api.CorePlatformApi
-    public static long skipByReading(InputStream in, long byteCount) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static long skipByReading(@NonNull InputStream in, long byteCount) throws IOException {
         // acquire the shared skip buffer.
         byte[] buffer = skipBuffer.getAndSet(null);
         if (buffer == null) {
@@ -189,12 +227,17 @@
     }
 
     /**
-     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
-     * Returns the total number of bytes transferred.
+     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is
+     * closed.
+     *
+     * @param in {@link InputStream} to copy data from
+     * @param out {@link InputStream} to write copied data to
+     * @return the total number of bytes transferred.
+     * @throws IOException reading from {@link InputStream} or writing to {@link OutputStream}.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
-    public static int copy(InputStream in, OutputStream out) throws IOException {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static int copy(@NonNull InputStream in, @NonNull OutputStream out) throws IOException {
         int total = 0;
         byte[] buffer = new byte[8192];
         int c;
diff --git a/luni/src/main/java/libcore/math/NativeBN.java b/luni/src/main/java/libcore/math/NativeBN.java
new file mode 100644
index 0000000..8b2ea0f
--- /dev/null
+++ b/luni/src/main/java/libcore/math/NativeBN.java
@@ -0,0 +1,44 @@
+/*
+ * 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 libcore.math;
+
+/**
+ * @hide
+ */
+public final class NativeBN {
+
+    public static native long BN_new();
+    // BIGNUM *BN_new(void);
+
+    public static native void BN_free(long a);
+    // void BN_free(BIGNUM *a);
+
+    public static native void litEndInts2bn(int[] ints, int len, boolean neg, long ret);
+
+    // Generates a minimal length representation of |a| in a sequence of integers, least-significant
+    // word at index 0.
+    public static native int[] bn2litEndInts(long a);
+
+    public static native void BN_mul(long r, long a, long b);
+    // int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
+
+    public static native void BN_div(long dv, long rem, long num, long divisor);
+    // int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *num, const BIGNUM *divisor, BN_CTX *ctx);
+
+    public static native void BN_mod_exp(long r, long a, long p, long m);
+    // int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx);
+}
diff --git a/luni/src/main/java/libcore/net/InetAddressUtils.java b/luni/src/main/java/libcore/net/InetAddressUtils.java
index 9da4a70..0f2bfa4 100644
--- a/luni/src/main/java/libcore/net/InetAddressUtils.java
+++ b/luni/src/main/java/libcore/net/InetAddressUtils.java
@@ -30,7 +30,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class InetAddressUtils {
 
     private static final int NETID_UNSET = 0;
@@ -51,7 +51,7 @@
      * @param address the address to parse.
      * @return true if the supplied address is numeric, false otherwise.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean isNumericAddress(String address) {
         return parseNumericAddressNoThrow(address) != null;
     }
@@ -69,7 +69,7 @@
      * @return an {@link InetAddress} instance corresponding to the address.
      * @throws IllegalArgumentException if {@code address} is not a numeric address.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static InetAddress parseNumericAddress(String address) {
         InetAddress result = parseNumericAddressNoThrow(address);
         if (result == null) {
diff --git a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
index 1ce58d9..c7d0efb 100644
--- a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -25,29 +25,45 @@
  * Android framework API should be accessing this policy via the framework's
  * {@code android.security.NetworkSecurityPolicy} instead of via this class.
  *
- * <p>The policy currently consists of a single flag: whether cleartext network traffic is
- * permitted. See {@link #isCleartextTrafficPermitted()}.
+ * <p>The policy can be determined by the {@link #isCleartextTrafficPermitted()},
+ * {@link #isCleartextTrafficPermitted(String)} and
+ * {@link #isCertificateTransparencyVerificationRequired(String)} methods.
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.IntraCoreApi
 public abstract class NetworkSecurityPolicy {
 
     private static volatile NetworkSecurityPolicy instance = new DefaultNetworkSecurityPolicy();
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Constructs a default {@code NetworkSecurityPolicy}.
+     *
+     * @see {@link #DefaultNetworkSecurityPolicy}.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public NetworkSecurityPolicy() {
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Gets current singleton {@code NetworkSecurityPolicy} instance.
+     *
+     * @return the current {@code NetworkSecurityPolicy}.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public static NetworkSecurityPolicy getInstance() {
         return instance;
     }
 
-    @libcore.api.CorePlatformApi
+    /**
+     * Sets current singleton instance
+     *
+     * @param policy new {@code NetworlSecurityPolicy} instance.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static void setInstance(NetworkSecurityPolicy policy) {
         if (policy == null) {
             throw new NullPointerException("policy == null");
@@ -73,9 +89,11 @@
      * can be made to honor this flag. Platform-provided network stacks (e.g. HTTP and FTP) honor
      * this flag from day one, and well-established third-party network stacks will eventually
      * honor it.
+     *
+     * @return {@code true} if cleartext traffic is permitted and {@code false} otherwise.
      */
     @UnsupportedAppUsage
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public abstract boolean isCleartextTrafficPermitted();
 
     /**
@@ -84,8 +102,11 @@
      * process.
      *
      * <p>See {@link #isCleartextTrafficPermitted} for more details.
+     *
+     * @param hostname hostname to check if cleartext traffic is permitted for
+     * @return {@code true} if cleartext traffic is permitted and {@code false} otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public abstract boolean isCleartextTrafficPermitted(String hostname);
 
     /**
@@ -93,11 +114,20 @@
      * the server and verified by the client in TLS connections to {@code hostname}.
      *
      * <p>See RFC6962 section 3.3 for more details.
+     *
+     * @param hostname hostname to check whether certificate transparency verification
+     *                 is required
+     * @return {@code true} if certificate transparency verification is required and
+     *         {@code false} otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public abstract boolean isCertificateTransparencyVerificationRequired(String hostname);
 
+    /**
+     * Default network security policy that allows cleartext traffic and does not require
+     * certificate transparency verification.
+     */
     public static final class DefaultNetworkSecurityPolicy extends NetworkSecurityPolicy {
         @Override
         public boolean isCleartextTrafficPermitted() {
diff --git a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
index 4c2acee..926abbc 100644
--- a/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
+++ b/luni/src/main/java/libcore/net/event/NetworkEventDispatcher.java
@@ -25,8 +25,8 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
-public class NetworkEventDispatcher {
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public final class NetworkEventDispatcher {
 
   private static final NetworkEventDispatcher instance = new NetworkEventDispatcher();
 
@@ -35,15 +35,17 @@
 
   /**
    * Returns the shared {@link NetworkEventDispatcher} instance.
+   *
+   * @return singleton instance of {@link NetworkEventDispatcher}
    */
   @UnsupportedAppUsage
-  @libcore.api.CorePlatformApi
+  @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
   public static NetworkEventDispatcher getInstance() {
     return instance;
   }
 
-  /** Visible for testing. Use {@link #getInstance()} instead. */
-  protected NetworkEventDispatcher() {
+  /** @hide Visible for testing. Use {@link #getInstance()} instead. */
+  public NetworkEventDispatcher() {
   }
 
   /**
@@ -74,8 +76,8 @@
   /**
    * Notifies registered listeners of a network configuration change.
    */
-  @libcore.api.CorePlatformApi
-  public void onNetworkConfigurationChanged() {
+  @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+  public void dispatchNetworkConfigurationChange() {
     for (NetworkEventListener listener : listeners) {
       try {
         listener.onNetworkConfigurationChanged();
diff --git a/luni/src/main/java/libcore/net/http/Dns.java b/luni/src/main/java/libcore/net/http/Dns.java
new file mode 100644
index 0000000..9526211
--- /dev/null
+++ b/luni/src/main/java/libcore/net/http/Dns.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.http;
+
+import libcore.api.CorePlatformApi;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+import libcore.util.NonNull;
+import libcore.util.Nullable;
+
+/**
+ * A domain name service that resolves IP addresses for host names.
+ * @hide
+ */
+@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+public interface Dns extends com.android.okhttp.internalandroidapi.Dns {
+    /**
+     * Returns the IP addresses of {@code hostname}, in the order they should
+     * be attempted. Returns loopback addresses for {@code null} host.
+     *
+     * @param hostname The host name will be looked up.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @NonNull List<@NonNull InetAddress> lookup(@Nullable String hostname) throws UnknownHostException;
+}
\ No newline at end of file
diff --git a/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java b/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java
new file mode 100644
index 0000000..b54f5f8
--- /dev/null
+++ b/luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2021 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.http;
+
+import libcore.api.CorePlatformApi;
+
+import java.io.IOException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.SocketFactory;
+import libcore.util.NonNull;
+
+/**
+ * A HttpURLConnectionFactory that supports some configuration on a per-factory or per-connection
+ * basis. The per-factory configuration is <b>optional</b>; if not set, global configuration or
+ * default behavior is used.
+ *
+ * @hide
+ */
+@CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+public class HttpURLConnectionFactory {
+    private final com.android.okhttp.internalandroidapi.HttpURLConnectionFactory mFactory;
+
+    /**
+     * Create a new {@link HttpURLConnectionFactory} instance.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    @NonNull public static HttpURLConnectionFactory createInstance() {
+        return new HttpURLConnectionFactory();
+    }
+
+    HttpURLConnectionFactory() {
+        mFactory = new com.android.okhttp.internalandroidapi.HttpURLConnectionFactory();
+    }
+
+    /**
+     * Sets a new ConnectionPool, specific to this HttpURLConnectionFactory and for all future
+     * connections created by {@link #openConnection}, with the given configuration.
+     *
+     * @param maxIdleConnections The maximum number of idle connections to each to keep in the pool.
+     * @param keepAliveDuration Time to keep the connection alive in the pool before closing it.
+     * @param timeUnit The time unit of keep alive duration.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public void setNewConnectionPool(int maxIdleConnections, long keepAliveDuration,
+            @NonNull TimeUnit timeUnit) {
+        mFactory.setNewConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
+    }
+
+    /**
+     * Sets a new dns resolver.
+     *
+     * @param dns the dns resolver for looking up.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public void setDns(@NonNull Dns dns) {
+        mFactory.setDns(dns);
+    }
+
+    /**
+     * Opens a connection using the specified SocketFactory and the specified proxy
+     * settings, overriding any system wide configuration.
+     *
+     * @param url The target URL that connection opens on.
+     * @param socketFactory The socket factory used to create connections.
+     * @param proxy The proxy settings used to create connections.
+     *
+     * @return An {@link java.net.URLConnection} using given SocketFactory, proxy settings and
+     *         configuration.
+     */
+    @CorePlatformApi(status = CorePlatformApi.Status.STABLE)
+    public URLConnection openConnection(@NonNull URL url, @NonNull SocketFactory socketFactory,
+            @NonNull Proxy proxy) throws IOException {
+        return mFactory.openConnection(url, socketFactory, proxy);
+    }
+}
diff --git a/luni/src/main/java/libcore/timezone/CountryTimeZones.java b/luni/src/main/java/libcore/timezone/CountryTimeZones.java
deleted file mode 100644
index 4ff8470..0000000
--- a/luni/src/main/java/libcore/timezone/CountryTimeZones.java
+++ /dev/null
@@ -1,501 +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.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 static final class OffsetResult {
-
-        /** A zone that matches the supplied criteria. See also {@link #isOnlyMatch}. */
-        private final TimeZone timeZone;
-
-        /** True if there is one match for the supplied criteria */
-        private final boolean isOnlyMatch;
-
-        public OffsetResult(TimeZone timeZone, boolean isOnlyMatch) {
-            this.timeZone = java.util.Objects.requireNonNull(timeZone);
-            this.isOnlyMatch = isOnlyMatch;
-        }
-
-        @libcore.api.CorePlatformApi
-        public TimeZone getTimeZone() {
-            return timeZone;
-        }
-
-        @libcore.api.CorePlatformApi
-        public boolean isOnlyMatch() {
-            return isOnlyMatch;
-        }
-
-        @Override
-        public String toString() {
-            return "Result{"
-                    + "timeZone='" + timeZone + '\''
-                    + ", isOnlyMatch=" + isOnlyMatch
-                    + '}';
-        }
-    }
-
-    /**
-     * A mapping to a time zone ID with some associated metadata.
-     *
-     * @hide
-     */
-    @libcore.api.CorePlatformApi
-    public static final class TimeZoneMapping {
-        private final String timeZoneId;
-        private final boolean shownInPicker;
-        private final Long notUsedAfter;
-
-        /** Memoized TimeZone object for {@link #timeZoneId}. */
-        private TimeZone timeZone;
-
-        TimeZoneMapping(String timeZoneId, boolean shownInPicker, Long notUsedAfter) {
-            this.timeZoneId = Objects.requireNonNull(timeZoneId);
-            this.shownInPicker = shownInPicker;
-            this.notUsedAfter = notUsedAfter;
-        }
-
-        @libcore.api.CorePlatformApi
-        public String getTimeZoneId() {
-            return timeZoneId;
-        }
-
-        @libcore.api.CorePlatformApi
-        public boolean isShownInPicker() {
-            return shownInPicker;
-        }
-
-        @libcore.api.CorePlatformApi
-        public Long getNotUsedAfter() {
-            return notUsedAfter;
-        }
-
-        /**
-         * Returns a {@link TimeZone} object for this mapping, or {@code null} if the ID is unknown.
-         */
-        @libcore.api.CorePlatformApi
-        public TimeZone getTimeZone() {
-            synchronized (this) {
-                if (timeZone == null) {
-                    TimeZone tz = TimeZone.getFrozenTimeZone(timeZoneId);
-                    timeZone = tz;
-                    if (TimeZone.UNKNOWN_ZONE_ID.equals(timeZone.getID())) {
-                        // This shouldn't happen given the validation that takes place in
-                        // createValidatedCountryTimeZones().
-                        throw new IllegalStateException("Invalid zone in TimeZoneMapping: " + this);
-                    }
-                }
-            }
-
-            return TimeZone.UNKNOWN_ZONE_ID.equals(timeZone.getID()) ? null : timeZone;
-        }
-
-        /**
-         * Returns {@code true} if the mapping is "effective" after {@code whenMillis}, i.e.
-         * it is distinct from other "effective" times zones used in the country at/after that
-         * time. This uses the {@link #notUsedAfter} metadata which ensures there is one time
-         * zone remaining when there are multiple candidate zones with the same rules. The one
-         * kept is based on country specific factors like population covered.
-         */
-        boolean isEffectiveAt(long whenMillis) {
-            return notUsedAfter == null || whenMillis <= 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 shownInPicker == that.shownInPicker &&
-                    Objects.equals(timeZoneId, that.timeZoneId) &&
-                    Objects.equals(notUsedAfter, that.notUsedAfter);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(timeZoneId, shownInPicker, notUsedAfter);
-        }
-
-        @Override
-        public String toString() {
-            return "TimeZoneMapping{"
-                    + "timeZoneId='" + timeZoneId + '\''
-                    + ", shownInPicker=" + shownInPicker
-                    + ", notUsedAfter=" + notUsedAfter
-                    + '}';
-        }
-
-        /**
-         * Returns {@code true} if one of the supplied {@link TimeZoneMapping} objects is for the
-         * specified time zone ID.
-         */
-        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;
-    /**
-     * {@code true} indicates the default time zone for a country is a good choice if a time zone
-     * cannot be determined by other means.
-     */
-    private final boolean defaultTimeZoneBoosted;
-    private final List<TimeZoneMapping> timeZoneMappings;
-    private final boolean everUsesUtc;
-
-    /**
-     * Memoized frozen ICU TimeZone object for the default. Can be {@link TimeZone#UNKNOWN_ZONE} if
-     * the {@link #defaultTimeZoneId} is missing or unrecognized.
-     */
-    private TimeZone defaultTimeZone;
-
-    private CountryTimeZones(String countryIso, String defaultTimeZoneId,
-            boolean defaultTimeZoneBoosted, boolean everUsesUtc,
-            List<TimeZoneMapping> timeZoneMappings) {
-        this.countryIso = java.util.Objects.requireNonNull(countryIso);
-        this.defaultTimeZoneId = defaultTimeZoneId;
-        this.defaultTimeZoneBoosted = defaultTimeZoneBoosted;
-        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 defaultTimeZoneBoosted, 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, defaultTimeZoneBoosted, 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 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, boolean, List, String)} was not recognized.
-     */
-    @libcore.api.CorePlatformApi
-    public synchronized TimeZone getDefaultTimeZone() {
-        if (defaultTimeZone == null) {
-            TimeZone timeZone;
-            if (defaultTimeZoneId == null) {
-                timeZone = TimeZone.UNKNOWN_ZONE;
-            } else {
-                timeZone = TimeZone.getFrozenTimeZone(defaultTimeZoneId);
-            }
-            this.defaultTimeZone = timeZone;
-        }
-        return TimeZone.UNKNOWN_ZONE_ID.equals(defaultTimeZone.getID()) ? null : defaultTimeZone;
-    }
-
-    /**
-     * 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, boolean, List, String)} was not recognized.
-     */
-    @libcore.api.CorePlatformApi
-    public String getDefaultTimeZoneId() {
-        return defaultTimeZoneId;
-    }
-
-    /**
-     * Qualifier for a country's default time zone. {@code true} indicates whether the default
-     * would be a good choice <em>generally</em> when there's no other information available.
-     */
-    @libcore.api.CorePlatformApi
-    public boolean isDefaultTimeZoneBoosted() {
-        return defaultTimeZoneBoosted;
-    }
-
-    /**
-     * 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;
-    }
-
-    /**
-     * Returns an immutable, ordered list of time zone mappings for the country in an undefined but
-     * "priority" order, filtered so that only "effective" time zone IDs are returned. An
-     * "effective" time zone is one that differs from another time zone used in the country after
-     * {@code whenMillis}. 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> getEffectiveTimeZoneMappingsAt(long whenMillis) {
-        ArrayList<TimeZoneMapping> filteredList = new ArrayList<>(timeZoneMappings.size());
-        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-            if (timeZoneMapping.isEffectiveAt(whenMillis)) {
-                filteredList.add(timeZoneMapping);
-            }
-        }
-        return Collections.unmodifiableList(filteredList);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        CountryTimeZones that = (CountryTimeZones) o;
-        return defaultTimeZoneBoosted == that.defaultTimeZoneBoosted
-                && everUsesUtc == that.everUsesUtc
-                && countryIso.equals(that.countryIso)
-                && Objects.equals(defaultTimeZoneId, that.defaultTimeZoneId)
-                && timeZoneMappings.equals(that.timeZoneMappings);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                countryIso, defaultTimeZoneId, defaultTimeZoneBoosted, timeZoneMappings,
-                everUsesUtc);
-    }
-
-    @Override
-    public String toString() {
-        return "CountryTimeZones{"
-                + "countryIso='" + countryIso + '\''
-                + ", defaultTimeZoneId='" + defaultTimeZoneId + '\''
-                + ", defaultTimeZoneBoosted=" + defaultTimeZoneBoosted
-                + ", timeZoneMappings=" + timeZoneMappings
-                + ", everUsesUtc=" + everUsesUtc
-                + '}';
-    }
-
-    /**
-     * 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 (TimeZoneMapping timeZoneMapping : getEffectiveTimeZoneMappingsAt(whenMillis)) {
-            TimeZone timeZone = timeZoneMapping.getTimeZone();
-            if (timeZone != null && timeZone.getOffset(whenMillis) == 0) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns a time zone for the country, if there is one, that matches the supplied 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
-     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
-     *
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
-     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
-     * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
-     *     {@code false} means not DST
-     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
-     *     there is no match
-     */
-    @libcore.api.CorePlatformApi
-    public OffsetResult lookupByOffsetWithBias(long whenMillis, TimeZone bias,
-            int totalOffsetMillis, boolean isDst) {
-        return lookupByOffsetWithBiasInternal(whenMillis, bias, totalOffsetMillis, isDst);
-    }
-
-    /**
-     * Returns a time zone for the country, if there is one, that matches the supplied 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
-     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
-     *
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be {@code null} to indicate there is no preference
-     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
-     * @return an {@link OffsetResult} with information about a matching zone, or {@code null} if
-     *     there is no match
-     */
-    @libcore.api.CorePlatformApi
-    public OffsetResult lookupByOffsetWithBias(long whenMillis, TimeZone bias,
-            int totalOffsetMillis) {
-        final Boolean isDst = null;
-        return lookupByOffsetWithBiasInternal(whenMillis, bias, totalOffsetMillis, isDst);
-    }
-
-    /**
-     * Returns a time zone for the country, if there is one, that matches the supplied 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
-     * #getEffectiveTimeZoneMappingsAt(long)} ordering.
-     *
-     * @param whenMillis the UTC time to match against
-     * @param bias the time zone to prefer, can be {@code null}
-     * @param totalOffsetMillis the offset from UTC at {@code whenMillis}
-     * @param isDst the Daylight Savings Time state at {@code whenMillis}. {@code true} means DST,
-     *     {@code false} means not DST, {@code null} means unknown
-     */
-    private OffsetResult lookupByOffsetWithBiasInternal(long whenMillis, TimeZone bias,
-            int totalOffsetMillis, Boolean isDst) {
-        List<TimeZoneMapping> timeZoneMappings = getEffectiveTimeZoneMappingsAt(whenMillis);
-        if (timeZoneMappings.isEmpty()) {
-            return null;
-        }
-
-        TimeZone firstMatch = null;
-        boolean biasMatched = false;
-        boolean oneMatch = true;
-        for (TimeZoneMapping timeZoneMapping : timeZoneMappings) {
-            TimeZone match = timeZoneMapping.getTimeZone();
-            if (match == null
-                    || !offsetMatchesAtTime(whenMillis, match, totalOffsetMillis, isDst)) {
-                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 {@code totalOffset} and {@code isDst} would be valid in
-     * the {@code timeZone} at time {@code whenMillis}.
-     * {@code totalOffetMillis} is always matched.
-     * If {@code isDst} is {@code null}, this means the DST state is unknown.
-     * If {@code isDst} is {@code false}, this means the zone must not be in DST.
-     * If {@code isDst} is {@code true}, this means the zone must be in DST.
-     */
-    private static boolean offsetMatchesAtTime(long whenMillis, TimeZone timeZone,
-            int totalOffsetMillis, Boolean isDst) {
-        int[] offsets = new int[2];
-        timeZone.getOffset(whenMillis, false /* local */, offsets);
-
-        if (totalOffsetMillis != (offsets[0] + offsets[1])) {
-            return false;
-        }
-
-        return isDst == null || (isDst == (offsets[1] != 0));
-    }
-
-    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
deleted file mode 100644
index 1a9d6a6..0000000
--- a/luni/src/main/java/libcore/timezone/CountryZonesFinder.java
+++ /dev/null
@@ -1,89 +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.timezone;
-
-import static libcore.timezone.XmlUtils.normalizeCountryIso;
-
-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 = normalizeCountryIso(countryIso);
-        for (CountryTimeZones countryTimeZones : countryTimeZonesList) {
-            if (countryTimeZones.getCountryIso().equals(normalizedCountryIso)) {
-                return countryTimeZones;
-            }
-        }
-        return null;
-    }
-}
diff --git a/luni/src/main/java/libcore/timezone/TEST_MAPPING b/luni/src/main/java/libcore/timezone/TEST_MAPPING
deleted file mode 100644
index 7f731bb..0000000
--- a/luni/src/main/java/libcore/timezone/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "CtsLibcoreTestCases",
-      "options": [
-        {
-          "include-filter": "libcore.libcore.timezone"
-        }
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/luni/src/main/java/libcore/timezone/TelephonyLookup.java b/luni/src/main/java/libcore/timezone/TelephonyLookup.java
deleted file mode 100644
index 10d9a35..0000000
--- a/luni/src/main/java/libcore/timezone/TelephonyLookup.java
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * 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.timezone;
-
-import static libcore.timezone.XmlUtils.checkOnEndTag;
-import static libcore.timezone.XmlUtils.consumeUntilEndTag;
-import static libcore.timezone.XmlUtils.findNextStartTagOrEndTagNoRecurse;
-import static libcore.timezone.XmlUtils.findNextStartTagOrThrowNoRecurse;
-import static libcore.timezone.XmlUtils.normalizeCountryIso;
-
-import libcore.timezone.TelephonyNetwork.MccMnc;
-import libcore.timezone.XmlUtils.ReaderSupplier;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A class that can find time zone-related information about telephony networks by loading data from
- * the telephonylookup.xml file.
- *
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class TelephonyLookup {
-
-    // VisibleForTesting
-    public static final String TELEPHONYLOOKUP_FILE_NAME = "telephonylookup.xml";
-
-    // Root element. e.g. <telephony_lookup>
-    private static final String TELEPHONY_LOOKUP_ELEMENT = "telephony_lookup";
-
-    // Networks section. e.g. <networks>
-    private static final String NETWORKS_ELEMENT = "networks";
-
-    // Network data. e.g.
-    // <network mcc="310" mnc="370" country="gu">
-    private static final String NETWORK_ELEMENT = "network";
-    private static final String MOBILE_COUNTRY_CODE_ATTRIBUTE = "mcc";
-    private static final String MOBILE_NETWORK_CODE_ATTRIBUTE = "mnc";
-    // This is the ISO 3166 alpha-2 code (in lower case).
-    private static final String COUNTRY_ISO_CODE_ATTRIBUTE = "country";
-
-    private static TelephonyLookup instance;
-
-    private final ReaderSupplier xmlSource;
-
-    private TelephonyLookup(ReaderSupplier xmlSource) {
-        this.xmlSource = xmlSource;
-    }
-
-    /**
-     * Obtains an instance for use when resolving networks. 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 TelephonyLookup getInstance() {
-        synchronized(TelephonyLookup.class) {
-            if (instance == null) {
-                String[] telephonyLookupFilePaths =
-                        TimeZoneDataFiles.getTimeZoneFilePaths(TELEPHONYLOOKUP_FILE_NAME);
-                instance = createInstanceWithFallback(telephonyLookupFilePaths);
-            }
-        }
-        return instance;
-    }
-
-    // VisibleForTesting
-    public static TelephonyLookup createInstanceWithFallback(String... telephonyLookupFilePaths) {
-        IOException lastException = null;
-        for (String tzLookupFilePath : telephonyLookupFilePaths) {
-            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(telephonyLookupFilePaths)
-                + " Printing exceptions and falling back to empty map.", lastException);
-        return createInstanceForTests("<telephony_lookup><networks /></telephony_lookup>");
-    }
-
-    /**
-     * 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 TelephonyLookup createInstance(String path) throws IOException {
-        ReaderSupplier xmlSupplier = ReaderSupplier.forFile(path, StandardCharsets.UTF_8);
-        return new TelephonyLookup(xmlSupplier);
-    }
-
-    /** Used to create an instance using an in-memory XML String instead of a file. */
-    // VisibleForTesting
-    public static TelephonyLookup createInstanceForTests(String xml) {
-        return new TelephonyLookup(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 TelephonyNetworkValidator());
-        } catch (XmlPullParserException e) {
-            throw new IOException("Parsing error", e);
-        }
-    }
-
-    /**
-     * Loads all the network &lt;-&gt; country 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 TelephonyNetworkFinder getTelephonyNetworkFinder() {
-        TelephonyNetworksExtractor extractor = new TelephonyNetworksExtractor();
-        try {
-            processXml(extractor);
-
-            return extractor.getTelephonyNetworkFinder();
-        } catch (XmlPullParserException | IOException e) {
-            System.logW("Error reading telephony networks", e);
-            return null;
-        }
-    }
-
-    /**
-     * Processes the XML, applying the {@link TelephonyNetworkProcessor} to the &lt;countryzones&gt;
-     * element. Processing can terminate early if {@link TelephonyNetworkProcessor
-     * #processNetwork(int, int, String, String)} it throws an exception.
-     */
-    private void processXml(TelephonyNetworkProcessor 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:
-             * <telephony_lookup>
-             *   <networks>
-             *     <network mcc="123" mnc="456" country="ab"/>
-             *     <network mcc="123" mnc="567" country="cd"/>
-             *   </networks>
-             * </telephony_lookup>
-             */
-
-            findNextStartTagOrThrowNoRecurse(parser, TELEPHONY_LOOKUP_ELEMENT);
-
-            // There is only one expected sub-element <telephony_lookup> in the format currently,
-            // skip over anything before it.
-            findNextStartTagOrThrowNoRecurse(parser, NETWORKS_ELEMENT);
-
-            processNetworks(parser, processor);
-
-            // Make sure we are on the </networks> tag.
-            checkOnEndTag(parser, NETWORKS_ELEMENT);
-
-            // Advance to the next event.
-            parser.next();
-
-            // Skip anything until </telephony_lookup>, and make sure the file is not truncated and
-            // we can find the end.
-            consumeUntilEndTag(parser, TELEPHONY_LOOKUP_ELEMENT);
-
-            // Make sure we are on the </telephony_lookup> tag.
-            checkOnEndTag(parser, TELEPHONY_LOOKUP_ELEMENT);
-        }
-    }
-
-    private static void processNetworks(XmlPullParser parser,
-            TelephonyNetworkProcessor processor) throws IOException, XmlPullParserException {
-
-        // Skip over any unexpected elements and process <network> elements.
-        while (findNextStartTagOrEndTagNoRecurse(parser, NETWORK_ELEMENT)) {
-            String mcc = parser.getAttributeValue(
-                    null /* namespace */, MOBILE_COUNTRY_CODE_ATTRIBUTE);
-            if (mcc == null) {
-                throw new XmlPullParserException(
-                        "Unable to find mcc: " + parser.getPositionDescription());
-            }
-
-            String mnc = parser.getAttributeValue(
-                    null /* namespace */, MOBILE_NETWORK_CODE_ATTRIBUTE);
-            if (mnc == null) {
-                throw new XmlPullParserException(
-                        "Unable to find mnc: " + parser.getPositionDescription());
-            }
-
-            String countryCode =
-                    parser.getAttributeValue(null /* namespace */, COUNTRY_ISO_CODE_ATTRIBUTE);
-            if (countryCode == null) {
-                throw new XmlPullParserException(
-                        "Unable to find country: " + parser.getPositionDescription());
-            }
-
-            String debugInfo = parser.getPositionDescription();
-            processor.processNetwork(mcc, mnc, countryCode, debugInfo);
-            // Advance to the next event.
-            parser.next();
-
-            // Skip anything until </network>.
-            consumeUntilEndTag(parser, NETWORK_ELEMENT);
-        }
-    }
-
-    /**
-     * Processes &lt;network&gt; data.
-     */
-    private interface TelephonyNetworkProcessor {
-
-        boolean CONTINUE = true;
-        boolean HALT = false;
-
-        /**
-         * Process network data. Problems with the data are reported as an exception.
-         */
-        void processNetwork(String mcc, String mnc, String countryIso, String debugInfo)
-                throws XmlPullParserException;
-    }
-
-    /**
-     * Validates &lt;network&gt; elements. Intended to be used before a proposed installation of new
-     * data. To be valid the MCC + MNC combination must generate a unique ID, country ISO code must
-     * be normalized.
-     */
-    private static class TelephonyNetworkValidator implements TelephonyNetworkProcessor {
-
-        private final Set<MccMnc> knownMccMncs = new HashSet<>();
-
-        @Override
-        public void processNetwork(String mcc, String mnc, String countryIso, String debugInfo)
-                throws XmlPullParserException {
-            if (mcc == null || mcc.length() != 3 || !isAsciiNumeric(mcc)) {
-                throw new XmlPullParserException(
-                        "MCC is not valid: mcc=" + mcc + " at " + debugInfo);
-            }
-
-            if (mnc == null || !(mnc.length() == 2 || mnc.length() == 3) || !isAsciiNumeric(mnc)) {
-                throw new XmlPullParserException(
-                        "MNC is not valid: mnc=" + mnc + " at " + debugInfo);
-            }
-
-            if (!normalizeCountryIso(countryIso).equals(countryIso)) {
-                throw new XmlPullParserException("Country code: " + countryIso
-                        + " is not normalized at " + debugInfo);
-            }
-
-            MccMnc mccMnc = new MccMnc(mcc, mnc);
-            if (knownMccMncs.contains(mccMnc)) {
-                throw new XmlPullParserException("Second entry for MCC + MNC: " + mccMnc
-                        + " at " + debugInfo);
-            }
-            knownMccMncs.add(mccMnc);
-        }
-
-        private static boolean isAsciiNumeric(String string) {
-            for (int i = 0; i < string.length(); i++) {
-                char character = string.charAt(i);
-                if (character < '0' || character > '9') {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    /**
-     * Reads all telephony network time zone information into memory and makes it available as a
-     * {@link TelephonyNetworkFinder}.
-     */
-    private static class TelephonyNetworksExtractor implements TelephonyNetworkProcessor {
-        private List<TelephonyNetwork> networksList = new ArrayList<>(10 /* default */);
-
-        @Override
-        public void processNetwork(String mcc, String mnc, String countryIso, String debugInfo)
-                throws XmlPullParserException {
-            TelephonyNetwork network = TelephonyNetwork.create(mcc, mnc, countryIso);
-            networksList.add(network);
-        }
-
-        TelephonyNetworkFinder getTelephonyNetworkFinder() {
-            return TelephonyNetworkFinder.create(networksList);
-        }
-    }
-}
diff --git a/luni/src/main/java/libcore/timezone/TelephonyNetwork.java b/luni/src/main/java/libcore/timezone/TelephonyNetwork.java
deleted file mode 100644
index e0f26ad..0000000
--- a/luni/src/main/java/libcore/timezone/TelephonyNetwork.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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.timezone;
-
-import static libcore.timezone.XmlUtils.normalizeCountryIso;
-
-import java.util.Objects;
-
-/**
- * Information about a telephony network.
- *
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class TelephonyNetwork {
-
-    /**
-     * A numeric network identifier consisting of the Mobile Country Code (MCC) and the Mobile
-     * Network Code (MNC).
-     *
-     * @hide
-     */
-    public static final class MccMnc {
-        final String mcc;
-        final String mnc;
-
-        public MccMnc(String mcc, String mnc) {
-            this.mcc = mcc;
-            this.mnc = mnc;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (o == null || getClass() != o.getClass()) {
-                return false;
-            }
-            MccMnc mccMnc = (MccMnc) o;
-            return Objects.equals(mcc, mccMnc.mcc)
-                    && Objects.equals(mnc, mccMnc.mnc);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mcc, mnc);
-        }
-
-        @Override
-        public String toString() {
-            return "MccMnc{"
-                    + "mcc=" + mcc
-                    + ", mnc=" + mnc
-                    + '}';
-        }
-    }
-
-    private final MccMnc mccMnc;
-    private final String countryIsoCode;
-
-    public static TelephonyNetwork create(String mcc, String mnc, String countryIsoCode) {
-        String normalizedCountryIso = normalizeCountryIso(countryIsoCode);
-        return new TelephonyNetwork(new MccMnc(mcc, mnc), normalizedCountryIso);
-    }
-
-    private TelephonyNetwork(MccMnc mccMnc, String countryIsoCode) {
-        this.mccMnc = mccMnc;
-        this.countryIsoCode = Objects.requireNonNull(countryIsoCode);
-    }
-
-    public MccMnc getMccMnc() {
-        return mccMnc;
-    }
-
-    @libcore.api.CorePlatformApi
-    public String getMcc() {
-        return mccMnc.mcc;
-    }
-
-    @libcore.api.CorePlatformApi
-    public String getMnc() {
-        return mccMnc.mnc;
-    }
-
-    @libcore.api.CorePlatformApi
-    public String getCountryIsoCode() {
-        return countryIsoCode;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        TelephonyNetwork that = (TelephonyNetwork) o;
-        return mccMnc.equals(that.mccMnc) &&
-                countryIsoCode.equals(that.countryIsoCode);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mccMnc, countryIsoCode);
-    }
-
-    @Override
-    public String toString() {
-        return "TelephonyNetwork{"
-                + "mccMnc=" + mccMnc
-                + ", countryIsoCode='" + countryIsoCode + '\''
-                + '}';
-    }
-}
diff --git a/luni/src/main/java/libcore/timezone/TelephonyNetworkFinder.java b/luni/src/main/java/libcore/timezone/TelephonyNetworkFinder.java
deleted file mode 100644
index f244159..0000000
--- a/luni/src/main/java/libcore/timezone/TelephonyNetworkFinder.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * 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.timezone;
-
-import static libcore.timezone.XmlUtils.normalizeCountryIso;
-
-import libcore.timezone.TelephonyNetwork.MccMnc;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A class that can find telephony networks loaded via {@link TelephonyLookup}.
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class TelephonyNetworkFinder {
-
-    private final Map<MccMnc, TelephonyNetwork> networksMap;
-    private final List<TelephonyNetwork> networksList;
-
-    public static TelephonyNetworkFinder create(List<TelephonyNetwork> networksList) {
-        Set<String> validCountryIsoCodes = new HashSet<>();
-        for (String validCountryIsoCode : Locale.getISOCountries()) {
-            validCountryIsoCodes.add(normalizeCountryIso(validCountryIsoCode));
-        }
-
-        Map<MccMnc, TelephonyNetwork> networksMap = new HashMap<>();
-        for (TelephonyNetwork network : networksList) {
-            if (!validCountryIsoCodes.contains(network.getCountryIsoCode())) {
-                System.logW("Unrecognized country code: " + network.getCountryIsoCode()
-                        + " for telephony network=" + network);
-            }
-
-            MccMnc mccMnc = network.getMccMnc();
-            TelephonyNetwork existingEntry = networksMap.put(mccMnc, network);
-            if (existingEntry != null) {
-                System.logW("Duplicate MccMnc detected for " + mccMnc
-                        + ". New entry=" + network + " replacing previous entry.");
-            }
-        }
-        return new TelephonyNetworkFinder(
-                Collections.unmodifiableList(new ArrayList<>(networksList)),
-                networksMap);
-    }
-
-    private TelephonyNetworkFinder(List<TelephonyNetwork> networksList,
-            Map<MccMnc, TelephonyNetwork> networksMap) {
-        this.networksList = networksList;
-        this.networksMap = networksMap;
-    }
-
-    @libcore.api.CorePlatformApi
-    public TelephonyNetwork findNetworkByMccMnc(String mcc, String mnc) {
-        return networksMap.get(new MccMnc(mcc, mnc));
-    }
-
-    // @VisibleForTesting
-    public List<TelephonyNetwork> getAll() {
-        return networksList;
-    }
-}
diff --git a/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java b/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
deleted file mode 100644
index b4c8976..0000000
--- a/luni/src/main/java/libcore/timezone/TimeZoneDataFiles.java
+++ /dev/null
@@ -1,137 +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.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_I18N_ROOT_ENV = "ANDROID_I18N_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 (must exist).</li>
-     * </ul>
-     */
-    // VisibleForTesting
-    public static String[] getTimeZoneFilePaths(String fileName) {
-        return new String[] {
-                getDataTimeZoneFile(fileName),
-                getTimeZoneModuleTzFile(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/";
-    }
-
-    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
-    @libcore.api.CorePlatformApi
-    public static String getDataTimeZoneFile(String fileName) {
-        return getDataTimeZoneRootDir() + "current/" + fileName;
-    }
-
-    public static String getTimeZoneModuleTzFile(String fileName) {
-        return getTimeZoneModuleFile("tz/" + fileName);
-    }
-
-    public static String getTimeZoneModuleIcuFile(String fileName) {
-        return getTimeZoneModuleFile("icu/" + fileName);
-    }
-
-    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
-    @libcore.api.CorePlatformApi
-    public static String getTimeZoneModuleTzVersionFile() {
-        return getTimeZoneModuleTzFile(TzDataSetVersion.DEFAULT_FILE_NAME);
-    }
-
-    // VisibleForTesting
-    public static String getTimeZoneModuleFile(String fileName) {
-        return System.getenv(ANDROID_TZDATA_ROOT_ENV) + "/etc/" + fileName;
-    }
-
-    public static String getI18nModuleIcuFile(String fileName) {
-        return getI18nModuleFile("icu/" + fileName);
-    }
-
-    private static String getI18nModuleFile(String fileName) {
-        return System.getenv(ANDROID_I18N_ROOT_ENV) + "/etc/" + fileName;
-    }
-
-    public static String getSystemTzFile(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);
-
-        // Note: This logic below should match the logic in IcuRegistration.cpp in external/icu/
-        // to ensure consistent behavior between ICU4C and ICU4J.
-
-        // 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 = getTimeZoneModuleIcuFile("");
-        paths.add(timeZoneModuleIcuDataPath);
-
-        // ICU should always look in the i18n module path as this is where most of the data
-        // can be found.
-        String i18nModuleIcuDataPath = getI18nModuleIcuFile("");
-        paths.add(i18nModuleIcuDataPath);
-
-        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
deleted file mode 100644
index 3f18e36..0000000
--- a/luni/src/main/java/libcore/timezone/TimeZoneFinder.java
+++ /dev/null
@@ -1,529 +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.timezone;
-
-import static libcore.timezone.XmlUtils.checkOnEndTag;
-import static libcore.timezone.XmlUtils.consumeText;
-import static libcore.timezone.XmlUtils.consumeUntilEndTag;
-import static libcore.timezone.XmlUtils.findNextStartTagOrEndTagNoRecurse;
-import static libcore.timezone.XmlUtils.findNextStartTagOrThrowNoRecurse;
-import static libcore.timezone.XmlUtils.normalizeCountryIso;
-import static libcore.timezone.XmlUtils.parseBooleanAttribute;
-import static libcore.timezone.XmlUtils.parseLongAttribute;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlPullParserFactory;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import libcore.timezone.CountryTimeZones.TimeZoneMapping;
-import libcore.timezone.XmlUtils.ReaderSupplier;
-
-/**
- * A class that can find matching time zones by loading data from the tzlookup.xml file.
- * @hide
- */
-@libcore.api.CorePlatformApi
-public final class TimeZoneFinder {
-
-    // VisibleForTesting
-    public 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" defaultBoost="y" 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 DEFAULT_TIME_ZONE_BOOST_ATTRIBUTE = "defaultBoost";
-    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 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 {@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, 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" defaultBoost="y">
-             *       <id>Europe/London</id>
-             *     </country>
-             *   </countryzones>
-             * </timezones>
-             */
-
-            findNextStartTagOrThrowNoRecurse(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.
-            findNextStartTagOrThrowNoRecurse(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 (findNextStartTagOrEndTagNoRecurse(parser, COUNTRY_ELEMENT)) {
-            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 defaultTimeZoneBoost = parseBooleanAttribute(parser,
-                    DEFAULT_TIME_ZONE_BOOST_ATTRIBUTE, false);
-
-            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,
-                    defaultTimeZoneBoost, 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 (findNextStartTagOrEndTagNoRecurse(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);
-    }
-
-    /**
-     * 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 defaultTimeZoneBoost, 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 defaultTimeZoneBoost, 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 defaultTimeZoneBoost, boolean everUsesUtc,
-                List<TimeZoneMapping> timeZoneMappings, String debugInfo)
-                throws XmlPullParserException {
-
-            CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                    countryIso, defaultTimeZoneId, defaultTimeZoneBoost, 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 defaultTimeZoneBoost, boolean everUsesUtc,
-                List<TimeZoneMapping> timeZoneMappings, String debugInfo) {
-            countryIso = normalizeCountryIso(countryIso);
-            if (!countryCodeToMatch.equals(countryIso)) {
-                return CONTINUE;
-            }
-            validatedCountryTimeZones = CountryTimeZones.createValidated(countryIso,
-                    defaultTimeZoneId, defaultTimeZoneBoost, everUsesUtc, timeZoneMappings,
-                    debugInfo);
-
-            return HALT;
-        }
-
-        /**
-         * Returns the CountryTimeZones that matched, or {@code null} if there were no matches.
-         */
-        CountryTimeZones getValidatedCountryTimeZones() {
-            return validatedCountryTimeZones;
-        }
-    }
-
-}
diff --git a/luni/src/main/java/libcore/timezone/TzDataSetVersion.java b/luni/src/main/java/libcore/timezone/TzDataSetVersion.java
deleted file mode 100644
index 8b97069b..0000000
--- a/luni/src/main/java/libcore/timezone/TzDataSetVersion.java
+++ /dev/null
@@ -1,322 +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.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 final 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 = 4; // Android R
-
-    /**
-     * 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 */);
-
-    private final int formatMajorVersion;
-    private final int formatMinorVersion;
-    private final String rulesVersion;
-    private 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);
-    }
-
-    /**
-     * Reads the version of time zone data supplied by the time zone data module.
-     */
-    @libcore.api.CorePlatformApi
-    public static TzDataSetVersion readTimeZoneModuleVersion()
-            throws IOException, TzDataSetException {
-        String tzVersionFileName =
-                TimeZoneDataFiles.getTimeZoneModuleTzFile(TzDataSetVersion.DEFAULT_FILE_NAME);
-        return readFromFile(new File(tzVersionFileName));
-    }
-
-    @libcore.api.CorePlatformApi
-    public int getFormatMajorVersion() {
-        return formatMajorVersion;
-    }
-
-    @libcore.api.CorePlatformApi
-    public int getFormatMinorVersion() {
-        return formatMinorVersion;
-    }
-
-    @libcore.api.CorePlatformApi
-    public String getRulesVersion() {
-        return rulesVersion;
-    }
-
-    // Remove from CorePlatformApi when all users in platform code are removed. http://b/123398797
-    @libcore.api.CorePlatformApi
-    public int getRevision() {
-        return revision;
-    }
-
-    // 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/XmlUtils.java b/luni/src/main/java/libcore/timezone/XmlUtils.java
deleted file mode 100644
index a9616f9..0000000
--- a/luni/src/main/java/libcore/timezone/XmlUtils.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * 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.timezone;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Locale;
-
-class XmlUtils {
-
-    private static final String TRUE_ATTRIBUTE_VALUE = "y";
-
-    private static final String FALSE_ATTRIBUTE_VALUE = "n";
-
-    private XmlUtils() {}
-
-    /**
-     * 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.
-     */
-    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.
-     */
-    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;
-    }
-
-    /**
-     * Advances the the parser to the START_TAG for the specified element without decreasing the
-     * depth, or increasing the depth by more than one (i.e. no recursion into child nodes).
-     * If the next (non-nested) END_TAG an exception is thrown. Throws an exception if the end of
-     * the document is encountered unexpectedly.
-     */
-    static void findNextStartTagOrThrowNoRecurse(XmlPullParser parser, String elementName)
-            throws IOException, XmlPullParserException {
-        if (!findNextStartTagOrEndTagNoRecurse(parser, elementName)) {
-            throw new XmlPullParserException("No next element found with name " + elementName);
-        }
-    }
-
-    /**
-     * Advances the the parser to the START_TAG for the specified element without decreasing the
-     * depth, or increasing the depth by more than one (i.e. no recursion into child nodes).
-     * Returns {@code true} if the requested START_TAG is found, or {@code false} when the next
-     * (non-nested) END_TAG is encountered instead. Throws an exception if the end of the document
-     * is encountered unexpectedly.
-     */
-    static boolean findNextStartTagOrEndTagNoRecurse(XmlPullParser parser, String elementName)
-            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:
-                    return false;
-                default:
-                    // Ignore.
-                    break;
-            }
-        }
-        throw new XmlPullParserException("Unexpected end of document while looking for "
-                + elementName);
-    }
-
-    /**
-     * Consume any remaining contents of an element and move to the END_TAG. Used when processing
-     * within an element can stop.
-     *
-     * <p>When called, the parser must be pointing at one of:
-     * <ul>
-     *     <li>the END_TAG we are looking for</li>
-     *     <li>a TEXT</li>
-     *     <li>a START_TAG nested within the element that can be consumed</li>
-     * </ul>
-     * Note: The parser synthesizes an END_TAG for self-closing tags so this works for them too.
-     */
-    static void consumeUntilEndTag(XmlPullParser parser, String elementName)
-            throws IOException, XmlPullParserException {
-
-        if (isEndTag(parser, elementName)) {
-            // 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");
-    }
-
-    /**
-     * Throws an exception if the current element is not an end tag.
-     * Note: The parser synthesizes an END_TAG for self-closing tags so this works for them too.
-     */
-    static void checkOnEndTag(XmlPullParser parser, String elementName)
-            throws XmlPullParserException {
-        if (!isEndTag(parser, elementName)) {
-            throw new XmlPullParserException(
-                    "Unexpected tag encountered: " + parser.getPositionDescription());
-        }
-    }
-
-    /**
-     * Returns true if the current tag is an end tag.
-     * Note: The parser synthesizes an END_TAG for self-closing tags so this works for them too.
-     */
-    private static boolean isEndTag(XmlPullParser parser, String elementName)
-            throws XmlPullParserException {
-        return parser.getEventType() == XmlPullParser.END_TAG
-                && parser.getName().equals(elementName);
-    }
-
-    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);
-    }
-
-    /**
-     * 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.
-     */
-    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;
-    }
-
-    /**
-     * A source of Readers that can be used repeatedly.
-     */
-    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);
-        }
-    }
-}
diff --git a/luni/src/main/java/libcore/timezone/ZoneInfoDb.java b/luni/src/main/java/libcore/timezone/ZoneInfoDb.java
deleted file mode 100644
index a94d293..0000000
--- a/luni/src/main/java/libcore/timezone/ZoneInfoDb.java
+++ /dev/null
@@ -1,411 +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.timezone;
-
-import android.system.ErrnoException;
-import dalvik.annotation.optimization.ReachabilitySensitive;
-
-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 implements AutoCloseable {
-
-  // VisibleForTesting
-  public static final String TZDATA_FILE_NAME = "tzdata";
-
-  private static final ZoneInfoDb DATA = ZoneInfoDb.loadTzDataWithFallback(
-          TimeZoneDataFiles.getTimeZoneFilePaths(TZDATA_FILE_NAME));
-
-  // 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);
-      }
-    }
-  };
-
-  @libcore.api.CorePlatformApi
-  public static ZoneInfoDb getInstance() {
-    return DATA;
-  }
-
-  /**
-   * Loads the data at the specified paths in order, returning the first valid one as a
-   * {@link ZoneInfoDb} object. If there is no valid one found a basic fallback instance is created
-   * containing just GMT.
-   */
-  public static ZoneInfoDb loadTzDataWithFallback(String... paths) {
-    for (String path : paths) {
-      ZoneInfoDb tzData = new ZoneInfoDb();
-      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_NAME + " file!");
-    return ZoneInfoDb.createFallback();
-  }
-
-  /**
-   * Loads the data at the specified path and returns the {@link ZoneInfoDb} object if it is valid,
-   * otherwise {@code null}.
-   */
-  @libcore.api.CorePlatformApi
-  public static ZoneInfoDb loadTzData(String path) {
-    ZoneInfoDb tzData = new ZoneInfoDb();
-    if (tzData.loadData(path)) {
-      return tzData;
-    }
-    return null;
-  }
-
-  private static ZoneInfoDb createFallback() {
-    ZoneInfoDb tzData = new ZoneInfoDb();
-    tzData.populateFallback();
-    return tzData;
-  }
-
-  private ZoneInfoDb() {
-  }
-
-  /**
-   * 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 ZoneInfoDb} instance can be used. If {@code false} is returned then the
-   * ZoneInfoDB 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_NAME + " 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("ZoneInfoDB instance is closed");
-    }
-  }
-
-  @Override protected void finalize() throws Throwable {
-    try {
-      close();
-    } finally {
-      super.finalize();
-    }
-  }
-}
diff --git a/luni/src/main/java/libcore/util/ArrayUtils.java b/luni/src/main/java/libcore/util/ArrayUtils.java
index 3a8d854..5330bc0 100644
--- a/luni/src/main/java/libcore/util/ArrayUtils.java
+++ b/luni/src/main/java/libcore/util/ArrayUtils.java
@@ -18,7 +18,6 @@
 /**
  * @hide
  */
-@libcore.api.CorePlatformApi
 public final class ArrayUtils {
     private ArrayUtils() {}
 
@@ -30,7 +29,6 @@
      * @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);
diff --git a/luni/src/main/java/libcore/util/CoreLibraryDebug.java b/luni/src/main/java/libcore/util/CoreLibraryDebug.java
deleted file mode 100644
index 0d6ee46..0000000
--- a/luni/src/main/java/libcore/util/CoreLibraryDebug.java
+++ /dev/null
@@ -1,117 +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 com.android.icu.util.Icu4cMetadata;
-
-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 versionFile =
-                    TimeZoneDataFiles.getTimeZoneModuleTzFile(TzDataSetVersion.DEFAULT_FILE_NAME);
-            addTzDataSetVersionDebugInfo(versionFile, tzDataModulePrefix, debugInfo);
-        }
-
-        // /system tz data set.
-        {
-            String systemDirPrefix = debugKeyPrefix + "system_";
-            String versionFile =
-                    TimeZoneDataFiles.getSystemTzFile(TzDataSetVersion.DEFAULT_FILE_NAME);
-            addTzDataSetVersionDebugInfo(versionFile, systemDirPrefix, debugInfo);
-        }
-    }
-
-    private static void addTzDataSetVersionDebugInfo(String tzDataSetVersionFile,
-            String debugKeyPrefix, DebugInfo debugInfo) {
-        File file = new File(tzDataSetVersionFile);
-        String statusKey = debugKeyPrefix + "status";
-        if (file.exists()) {
-            try {
-                TzDataSetVersion tzDataSetVersion =
-                        TzDataSetVersion.readFromFile(file);
-                String formatVersionString = tzDataSetVersion.getFormatMajorVersion() + "."
-                        + tzDataSetVersion.getFormatMinorVersion();
-                debugInfo.addStringEntry(statusKey, "OK")
-                        .addStringEntry(debugKeyPrefix + "formatVersion", formatVersionString)
-                        .addStringEntry(debugKeyPrefix + "rulesVersion",
-                                tzDataSetVersion.getRulesVersion())
-                        .addStringEntry(debugKeyPrefix + "revision",
-                                tzDataSetVersion.getRevision());
-            } 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",
-                Icu4cMetadata.getTzdbVersion());
-    }
-}
diff --git a/luni/src/main/java/libcore/util/DebugInfo.java b/luni/src/main/java/libcore/util/DebugInfo.java
deleted file mode 100644
index 78baa71..0000000
--- a/luni/src/main/java/libcore/util/DebugInfo.java
+++ /dev/null
@@ -1,100 +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.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/FP16.java b/luni/src/main/java/libcore/util/FP16.java
index 602e1d4..49fd926 100644
--- a/luni/src/main/java/libcore/util/FP16.java
+++ b/luni/src/main/java/libcore/util/FP16.java
@@ -86,91 +86,118 @@
  * @hide
  */
 
-@libcore.api.CorePlatformApi
-public class FP16 {
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+public final class FP16 {
     /**
      * The number of bits used to represent a half-precision float value.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SIZE = 16;
 
     /**
      * Epsilon is the difference between 1.0 and the next value representable
      * by a half-precision floating-point.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short EPSILON = (short) 0x1400;
 
     /**
      * Maximum exponent a finite half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int MAX_EXPONENT = 15;
     /**
      * Minimum exponent a normalized half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int MIN_EXPONENT = -14;
 
     /**
      * Smallest negative value a half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short LOWEST_VALUE = (short) 0xfbff;
     /**
      * Maximum positive finite value a half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short MAX_VALUE = (short) 0x7bff;
     /**
      * Smallest positive normal value a half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short MIN_NORMAL = (short) 0x0400;
     /**
      * Smallest positive non-zero value a half-precision float may have.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short MIN_VALUE = (short) 0x0001;
     /**
      * A Not-a-Number representation of a half-precision float.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short NaN = (short) 0x7e00;
     /**
      * Negative infinity of type half-precision float.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short NEGATIVE_INFINITY = (short) 0xfc00;
     /**
      * Negative 0 of type half-precision float.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short NEGATIVE_ZERO = (short) 0x8000;
     /**
      * Positive infinity of type half-precision float.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short POSITIVE_INFINITY = (short) 0x7c00;
     /**
      * Positive 0 of type half-precision float.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final short POSITIVE_ZERO = (short) 0x0000;
 
-    @libcore.api.CorePlatformApi
+    /**
+     * The offset to shift by to obtain the sign bit.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SIGN_SHIFT                = 15;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The offset to shift by to obtain the exponent bits.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int EXPONENT_SHIFT            = 10;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The bitmask to AND a number with to obtain the sign bit.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SIGN_MASK                 = 0x8000;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The bitmask to AND a number shifted by {@link #EXPONENT_SHIFT} right, to obtain exponent bits.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SHIFTED_EXPONENT_MASK     = 0x1f;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The bitmask to AND a number with to obtain significand bits.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int SIGNIFICAND_MASK          = 0x3ff;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The bitmask to AND with to obtain exponent and significand bits.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int EXPONENT_SIGNIFICAND_MASK = 0x7fff;
-    @libcore.api.CorePlatformApi
+
+    /**
+     * The offset of the exponent from the actual value.
+     */
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static final int EXPONENT_BIAS             = 15;
 
     private static final int FP32_SIGN_SHIFT            = 31;
@@ -204,7 +231,7 @@
      *          and a value greater than {@code 0} if {@code x} is numerically greater
      *          than {@code y}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static int compare(short x, short y) {
         if (less(x, y)) return -1;
         if (greater(x, y)) return 1;
@@ -234,7 +261,7 @@
      * @return The value of the specified half-precision float rounded to the nearest
      *         half-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short rint(short h) {
         int bits = h & 0xffff;
         int abs = bits & EXPONENT_SIGNIFICAND_MASK;
@@ -277,7 +304,7 @@
      * @return The smallest half-precision float value toward negative infinity
      *         greater than or equal to the specified half-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short ceil(short h) {
         int bits = h & 0xffff;
         int abs = bits & EXPONENT_SIGNIFICAND_MASK;
@@ -318,7 +345,7 @@
      * @return The largest half-precision float value toward positive infinity
      *         less than or equal to the specified half-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short floor(short h) {
         int bits = h & 0xffff;
         int abs = bits & EXPONENT_SIGNIFICAND_MASK;
@@ -357,7 +384,7 @@
      * @return The truncated half-precision float value of the specified
      *         half-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short trunc(short h) {
         int bits = h & 0xffff;
         int abs = bits & EXPONENT_SIGNIFICAND_MASK;
@@ -386,7 +413,7 @@
      * @param y The second half-precision value
      * @return The smaller of the two specified half-precision values
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short min(short x, short y) {
         if (isNaN(x)) return NaN;
         if (isNaN(y)) return NaN;
@@ -412,7 +439,7 @@
      *
      * @return The larger of the two specified half-precision values
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short max(short x, short y) {
         if (isNaN(x)) return NaN;
         if (isNaN(y)) return NaN;
@@ -435,7 +462,7 @@
      *
      * @return True if x is less than y, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean less(short x, short y) {
         if (isNaN(x)) return false;
         if (isNaN(y)) return false;
@@ -454,7 +481,7 @@
      *
      * @return True if x is less than or equal to y, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean lessEquals(short x, short y) {
         if (isNaN(x)) return false;
         if (isNaN(y)) return false;
@@ -473,7 +500,7 @@
      *
      * @return True if x is greater than y, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean greater(short x, short y) {
         if (isNaN(x)) return false;
         if (isNaN(y)) return false;
@@ -492,7 +519,7 @@
      *
      * @return True if x is greater than y, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean greaterEquals(short x, short y) {
         if (isNaN(x)) return false;
         if (isNaN(y)) return false;
@@ -511,7 +538,7 @@
      *
      * @return True if x is equal to y, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean equals(short x, short y) {
         if (isNaN(x)) return false;
         if (isNaN(y)) return false;
@@ -527,7 +554,7 @@
      * @return True if the value is positive infinity or negative infinity,
      *         false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean isInfinite(short h) {
         return (h & EXPONENT_SIGNIFICAND_MASK) == POSITIVE_INFINITY;
     }
@@ -539,7 +566,7 @@
      * @param h A half-precision float value
      * @return True if the value is a NaN, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean isNaN(short h) {
         return (h & EXPONENT_SIGNIFICAND_MASK) > POSITIVE_INFINITY;
     }
@@ -554,7 +581,7 @@
      * @param h A half-precision float value
      * @return True if the value is normalized, false otherwise
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static boolean isNormalized(short h) {
         return (h & POSITIVE_INFINITY) != 0 && (h & POSITIVE_INFINITY) != POSITIVE_INFINITY;
     }
@@ -574,7 +601,7 @@
      * @param h The half-precision float value to convert to single-precision
      * @return A normalized single-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static float toFloat(short h) {
         int bits = h & 0xffff;
         int s = bits & SIGN_MASK;
@@ -629,7 +656,7 @@
      * @param f The single-precision float value to convert to half-precision
      * @return A half-precision float value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static short toHalf(float f) {
         int bits = Float.floatToRawIntBits(f);
         int s = (bits >>> FP32_SIGN_SHIFT    );
@@ -709,7 +736,7 @@
      * @param h A half-precision float value
      * @return A hexadecimal string representation of the specified value
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String toHexString(short h) {
         StringBuilder o = new StringBuilder();
 
diff --git a/luni/src/main/java/libcore/util/HexEncoding.java b/luni/src/main/java/libcore/util/HexEncoding.java
index 6d00074..b8d3765 100644
--- a/luni/src/main/java/libcore/util/HexEncoding.java
+++ b/luni/src/main/java/libcore/util/HexEncoding.java
@@ -20,7 +20,7 @@
  * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class HexEncoding {
 
     private static final char[] LOWER_CASE_DIGITS = {
@@ -36,8 +36,13 @@
 
     /**
      * Encodes the provided byte as a two-digit hexadecimal String value.
+     *
+     * @param  b byte to encode
+     * @param  upperCase {@code true} to use uppercase letters, {@code false}
+     *         for lowercase
+     * @return the encoded string
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String encodeToString(byte b, boolean upperCase) {
         char[] digits = upperCase ? UPPER_CASE_DIGITS : LOWER_CASE_DIGITS;
         char[] buf = new char[2]; // We always want two digits.
@@ -48,24 +53,37 @@
 
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
+     *
+     * @param  data byte array to encode
+     * @return the encoded data, using uppercase letters
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static char[] encode(byte[] data) {
         return encode(data, 0, data.length, true /* upperCase */);
     }
 
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
+     *
+     * @param  data byte array to encode
+     * @param  upperCase {@code true} to use uppercase letters, {@code false}
+     *         for lowercase
+     * @return the encoded data
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static char[] encode(byte[] data, boolean upperCase) {
         return encode(data, 0, data.length, upperCase);
     }
 
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
+     *
+     * @param  data byte array containing the data to encode
+     * @param  offset offset of the data to encode in the {@code data} array
+     * @param  len length of the data to encode in the {@code data} array
+     * @return the encoded data, using uppercase letters
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static char[] encode(byte[] data, int offset, int len) {
         return encode(data, offset, len, true /* upperCase */);
     }
@@ -88,63 +106,85 @@
 
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
+     *
+     * @param  data byte array to encode
+     * @return the encoded data, using uppercase letters
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String encodeToString(byte[] data) {
         return encodeToString(data, true /* upperCase */);
     }
 
     /**
      * Encodes the provided data as a sequence of hexadecimal characters.
+     *
+     * @param  data byte array to encode.
+     * @param  upperCase {@code true} to use uppercase letters, {@code false}
+     *         for lowercase
+     * @return the encoded data
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static String encodeToString(byte[] data, boolean upperCase) {
         return new String(encode(data, upperCase));
     }
 
     /**
-     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
-     * are not allowed.
+     * Decodes the provided hexadecimal sequence. Odd-length inputs are not
+     * allowed.
      *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     * @param  encoded string of hexadecimal characters to decode. Letters
+     *         can be either uppercase or lowercase.
+     * @return the decoded data
+     * @throws IllegalArgumentException if the input is malformed
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static byte[] decode(String encoded) throws IllegalArgumentException {
         return decode(encoded.toCharArray());
     }
 
     /**
-     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
-     * is {@code true} odd-length inputs are allowed and the first character is interpreted
-     * as the lower bits of the first result byte.
+     * Decodes the provided hexadecimal sequence.
      *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     * @param  encoded string of hexadecimal characters to decode. Letters
+     *         can be either uppercase or lowercase.
+     * @param  allowSingleChar If {@code true} odd-length inputs are allowed and
+     *         the first character is interpreted as the lower bits of the first
+     *         result byte. If {@code false} odd-length inputs are not allowed.
+     * @return the decoded data
+     * @throws IllegalArgumentException if the input is malformed
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static byte[] decode(String encoded, boolean allowSingleChar)
             throws IllegalArgumentException {
         return decode(encoded.toCharArray(), allowSingleChar);
     }
 
     /**
-     * Decodes the provided hexadecimal string into a byte array.  Odd-length inputs
-     * are not allowed.
+     * Decodes the provided hexadecimal sequence. Odd-length inputs are not
+     * allowed.
      *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     * @param  encoded char array of hexadecimal characters to decode. Letters
+     *         can be either uppercase or lowercase.
+     * @return the decoded data
+     * @throws IllegalArgumentException if the input is malformed
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static byte[] decode(char[] encoded) throws IllegalArgumentException {
         return decode(encoded, false);
     }
 
     /**
-     * Decodes the provided hexadecimal string into a byte array. If {@code allowSingleChar}
-     * is {@code true} odd-length inputs are allowed and the first character is interpreted
-     * as the lower bits of the first result byte.
+     * Decodes the provided hexadecimal sequence.
      *
-     * Throws an {@code IllegalArgumentException} if the input is malformed.
+     * @param  encoded char array of hexadecimal characters to decode. Letters
+     *         can be either uppercase or lowercase.
+     * @param  allowSingleChar If {@code true} odd-length inputs are allowed and
+     *         the first character is interpreted as the lower bits of the first
+     *         result byte. If {@code false} odd-length inputs are not allowed.
+     * @return the decoded data
+     * @throws IllegalArgumentException if the input is malformed
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static byte[] decode(char[] encoded, boolean allowSingleChar)
             throws IllegalArgumentException {
         int encodedLength = encoded.length;
diff --git a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
index e114ebe..6a1cb47 100644
--- a/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
+++ b/luni/src/main/java/libcore/util/NativeAllocationRegistry.java
@@ -21,6 +21,8 @@
 
 import java.lang.ref.Reference;
 
+import libcore.util.NonNull;
+
 /**
  * A NativeAllocationRegistry is used to associate native allocations with
  * Java objects and register them with the runtime.
@@ -40,7 +42,7 @@
  * used to register any number of native allocations of that kind.
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.IntraCoreApi
 public class NativeAllocationRegistry {
 
@@ -60,29 +62,30 @@
     private static final long IS_MALLOCED = 0x1;
 
     /**
-     * Return a NativeAllocationRegistry for native memory that is mostly
+     * Return a {@link 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.
+     *                     before {@code freeFunction} is called.
      * @param freeFunction address of a native function of type
-     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     {@code void f(void* nativePtr)} 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
+     * @return allocated {@link NativeAllocationRegistry}
+     * @throws IllegalArgumentException If {@code size} is negative
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static NativeAllocationRegistry createNonmalloced(
-            ClassLoader classLoader, long freeFunction, long size) {
+            @NonNull ClassLoader classLoader, long freeFunction, long size) {
         return new NativeAllocationRegistry(classLoader, freeFunction, size, false);
     }
 
     /**
-     * Return a NativeAllocationRegistry for native memory that is mostly
+     * Return a {@link 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>
@@ -92,36 +95,38 @@
      * </pre>
      * <p>
      * @param classLoader  ClassLoader that was used to load the native
-     *                     library freeFunction belongs to.
+     *                     library {@code freeFunction} belongs to.
      * @param freeFunction address of a native function of type
-     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     {@code void f(void* nativePtr)} 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
+     * @return allocated {@link NativeAllocationRegistry}
+     * @throws IllegalArgumentException If {@code size} is negative
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static NativeAllocationRegistry createMalloced(
-            ClassLoader classLoader, long freeFunction, long size) {
+            @NonNull ClassLoader classLoader, long freeFunction, long size) {
         return new NativeAllocationRegistry(classLoader, freeFunction, size, true);
     }
 
     /**
-     * Return a NativeAllocationRegistry for native memory that is mostly
+     * Return a {@link 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.
+     *                     library {@code freeFunction} belongs to.
      * @param freeFunction address of a native function of type
-     *                     <code>void f(void* nativePtr)</code> used to free this
+     *                     {@code void f(void* nativePtr)} used to free this
      *                     kind of native allocation
+     * @return allocated {@link NativeAllocationRegistry}
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public static NativeAllocationRegistry createMalloced(
-            ClassLoader classLoader, long freeFunction) {
+            @NonNull ClassLoader classLoader, long freeFunction) {
         return new NativeAllocationRegistry(classLoader, freeFunction, 0, true);
     }
 
@@ -164,51 +169,49 @@
     }
 
     /**
-     * Constructs a NativeAllocationRegistry for a particular kind of native
+     * Constructs a {@link 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
+     * The {@code size} 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
+     * {@link NativeAllocationRegistry}s 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
+     * {@code freeFunction}. 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.
+     *                     library {@code 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) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public NativeAllocationRegistry(@NonNull ClassLoader classLoader, long freeFunction, long size) {
         this(classLoader, freeFunction, size, size == 0);
     }
 
     /**
      * Registers a new native allocation and associated Java object with the
      * runtime.
-     * This NativeAllocationRegistry's <code>freeFunction</code> will
-     * automatically be called with <code>nativePtr</code> as its sole
-     * argument when <code>referent</code> becomes unreachable. If you
-     * maintain copies of <code>nativePtr</code> outside
-     * <code>referent</code>, you must not access these after
-     * <code>referent</code> becomes unreachable, because they may be dangling
+     * This {@link NativeAllocationRegistry}'s {@code freeFunction} will
+     * automatically be called with {@code nativePtr} as its sole
+     * argument when {@code referent} becomes unreachable. If you
+     * maintain copies of {@code nativePtr} outside
+     * {@code referent}, you must not access these after
+     * {@code referent} becomes unreachable, because they may be dangling
      * pointers.
      * <p>
      * The returned Runnable can be used to free the native allocation before
-     * <code>referent</code> becomes unreachable. The runnable will have no
+     * {@code referent} becomes unreachable. The runnable will have no
      * effect if the native allocation has already been freed by the runtime
      * or by using the runnable.
      * <p>
@@ -217,20 +220,20 @@
      * if the registration attempt throws an exception (other than one reporting
      * a programming error).
      *
-     * @param referent      Non-null java object to associate the native allocation with
+     * @param referent      Non-{@code null} java object to associate the native allocation with
      * @param nativePtr     Non-zero address of the native allocation
      * @return runnable to explicitly free native allocation
-     * @throws IllegalArgumentException if either referent or nativePtr is null.
+     * @throws IllegalArgumentException if either referent or nativePtr is {@code null}.
      * @throws OutOfMemoryError  if there is not enough space on the Java heap
      *                           in which to register the allocation. In this
-     *                           case, <code>freeFunction</code> will be
-     *                           called with <code>nativePtr</code> as its
-     *                           argument before the OutOfMemoryError is
+     *                           case, {@code freeFunction} will be
+     *                           called with {@code nativePtr} as its
+     *                           argument before the {@link OutOfMemoryError} is
      *                           thrown.
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
-    public Runnable registerNativeAllocation(Object referent, long nativePtr) {
+    public @NonNull Runnable registerNativeAllocation(@NonNull Object referent, long nativePtr) {
         if (referent == null) {
             throw new IllegalArgumentException("referent is null");
         }
@@ -311,12 +314,16 @@
     }
 
     /**
-     * Calls <code>freeFunction</code>(<code>nativePtr</code>).
+     * Calls {@code freeFunction}({@code nativePtr}).
      * Provided as a convenience in the case where you wish to manually free a
-     * native allocation using a <code>freeFunction</code> without using a
-     * NativeAllocationRegistry.
+     * native allocation using a {@code freeFunction} without using a
+     * {@link NativeAllocationRegistry}.
+     *
+     * @param freeFunction address of a native function used to free this
+     *                     kind of native allocation
+     * @param nativePtr    pointer to pass to freeing function
      */
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static native void applyFreeFunction(long freeFunction, long nativePtr);
 }
 
diff --git a/luni/src/main/java/libcore/util/NullFromTypeParam.java b/luni/src/main/java/libcore/util/NullFromTypeParam.java
index 3b6908e..e895f87 100644
--- a/luni/src/main/java/libcore/util/NullFromTypeParam.java
+++ b/luni/src/main/java/libcore/util/NullFromTypeParam.java
@@ -26,6 +26,8 @@
  * Annotation for generic types in methods, denotes that a type nullability is
  * deliberately left floating; the nullability is the same as the
  * actual type parameter of the class.
+ *
+ * @hide - prevent references to this from being output to the signature file.
  */
 @Documented
 @Retention(SOURCE)
diff --git a/luni/src/main/java/libcore/util/SneakyThrow.java b/luni/src/main/java/libcore/util/SneakyThrow.java
index 679996f..4cfcbf6 100644
--- a/luni/src/main/java/libcore/util/SneakyThrow.java
+++ b/luni/src/main/java/libcore/util/SneakyThrow.java
@@ -25,7 +25,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class SneakyThrow {
 
     private SneakyThrow() {
@@ -34,9 +34,11 @@
     /**
      * A hacky method that always throws {@code t} even if {@code t} is a checked exception,
      * and is not declared to be thrown.
+     *
+     * @param t throwable to throw
      */
-    @libcore.api.CorePlatformApi
-    public static void sneakyThrow(Throwable t) {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static void sneakyThrow(@NonNull Throwable t) {
         SneakyThrow.<RuntimeException>sneakyThrow_(t);
     }
 
diff --git a/luni/src/main/java/libcore/util/XmlObjectFactory.java b/luni/src/main/java/libcore/util/XmlObjectFactory.java
index 3fafb39..ed8b1ac 100644
--- a/luni/src/main/java/libcore/util/XmlObjectFactory.java
+++ b/luni/src/main/java/libcore/util/XmlObjectFactory.java
@@ -28,7 +28,7 @@
  *
  * @hide
  */
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class XmlObjectFactory {
 
     private XmlObjectFactory() {}
@@ -36,26 +36,32 @@
     /**
      * Returns a new instance of the platform default {@link XmlSerializer} more efficiently than
      * using {@code XmlPullParserFactory.newInstance().newSerializer()}.
+     *
+     * @return platform default {@link XmlSerializer}
      */
-    @libcore.api.CorePlatformApi
-    public static XmlSerializer newXmlSerializer() {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull XmlSerializer newXmlSerializer() {
         return new KXmlSerializer();
     }
 
     /**
      * Returns a new instance of the platform default {@link XmlPullParser} more efficiently than
      * using {@code XmlPullParserFactory.newInstance().newPullParser()}.
+     *
+     * @return platform default {@link XmlPullParser}
      */
-    @libcore.api.CorePlatformApi
-    public static XmlPullParser newXmlPullParser() {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull XmlPullParser newXmlPullParser() {
         return new KXmlParser();
     }
 
     /**
      * Returns the plaform default {@link XMLReader}.
+     *
+     * @return plaform default {@link XMLReader}
      */
-    @libcore.api.CorePlatformApi
-    public static XMLReader newXMLReader() {
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static @NonNull 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 85bf1bc..32ec445 100644
--- a/luni/src/main/java/libcore/util/ZoneInfo.java
+++ b/luni/src/main/java/libcore/util/ZoneInfo.java
@@ -24,41 +24,30 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 
+import com.android.i18n.timezone.ZoneInfoData;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
+import java.io.ObjectStreamField;
+import java.lang.reflect.Field;
 import java.util.Arrays;
-import java.util.Calendar;
 import java.util.Date;
-import java.util.GregorianCalendar;
+import java.util.Objects;
 import java.util.TimeZone;
-import libcore.io.BufferIterator;
-import libcore.timezone.ZoneInfoDb;
 
 /**
- * Our concrete TimeZone implementation, backed by zoneinfo data.
+ *  Our concrete TimeZone implementation, backed by a {@link ZoneInfoData}. This class is not
+ *  thread-safe.
  *
- * <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 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
- * reading the index and creating a {@link BufferIterator} that provides access to an entry for a
- * specific file. This class is responsible for reading the data from that {@link BufferIterator}
- * and storing it a representation to support the {@link TimeZone} and {@link GregorianCalendar}
- * implementations. See {@link ZoneInfo#readTimeZone(String, BufferIterator, long)}.
- *
- * <p>This class does not use all the information from the {@code tzfile}; it uses:
- * {@code tzh_timecnt} and the associated transition times and type information. For each type
- * (described by {@code struct ttinfo}) it uses {@code tt_gmtoff} and {@code tt_isdst}.
- *
- * <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.
+ * This class exists in this package and has certain fields / a defined serialization footprint for
+ * app compatibility reasons. The knowledge of the underlying file format has been split out into
+ * {@link ZoneInfoData} which is intended to be updated independently of the classes in
+ * libcore.util.
  *
  * @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 =
@@ -67,27 +56,34 @@
     private static final long UNIX_OFFSET = 62167219200000L;
 
     private static final int[] NORMAL = new int[] {
-        0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
+            0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
     };
 
     private static final int[] LEAP = new int[] {
-        0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
+            0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
     };
 
     // 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.
+     * Keep the serialization compatibility even though most of the fields have been moved to
+     * {@link ZoneInfoData}. Originally, Android just had the Serializable subclass of TimeZone,
+     * ZoneInfo. This has been split into two: ZoneInfoData is now responsible for the immutable
+     * data fields, and this class holds the rest.
      */
-    private int mRawOffset;
+    private static final ObjectStreamField[] serialPersistentFields;
 
-    /**
-     * 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;
+    static {
+        int srcLen = ZoneInfoData.ZONEINFO_SERIALIZED_FIELDS.length;
+        serialPersistentFields = new ObjectStreamField[2 + srcLen];
+        // Serialize mDstSavings and mUseDst fields, but not mTransitions because the
+        // ZoneInfoData delegate should handle it.
+        serialPersistentFields[0] = new ObjectStreamField("mDstSavings", int.class);
+        serialPersistentFields[1] = new ObjectStreamField("mUseDst", boolean.class);
+        System.arraycopy(ZoneInfoData.ZONEINFO_SERIALIZED_FIELDS, 0 /* srcPos */,
+                serialPersistentFields, 2 /* destPos */, srcLen /* length */);
+    }
 
     /**
      * Implements {@link #useDaylightTime()}
@@ -95,9 +91,9 @@
      * <p>True if the transition active at the time this instance was created, or future
      * transitions support DST. It is possible that caching this value at construction time and
      * using it for the lifetime of the instance does not match the contract of the
-     * {@link TimeZone#useDaylightTime()} method but it appears to be what the RI does and that
-     * method is not particularly useful when it comes to historical or future times as it does not
-     * allow the time to be specified.
+     * {@link java.util.TimeZone#useDaylightTime()} method but it appears to be what the RI does
+     * and that method is not particularly useful when it comes to historical or future times as it
+     * does not allow the time to be specified.
      *
      * <p>When this is false then {@link #mDstSavings} will be 0.
      *
@@ -108,362 +104,95 @@
     /**
      * Implements {@link #getDSTSavings()}
      *
-     * <p>This should be final but is not because it may need to be fixed up by
-     * {@link #readObject(ObjectInputStream)} to correct an inconsistency in the previous version
-     * of the code whereby this was set to a non-zero value even though DST was not actually used.
-     *
      * @see #mUseDst
      */
-    private int mDstSavings;
+    private final int mDstSavings;
 
     /**
-     * The times (in seconds) at which the offsets changes for any reason, whether that is a change
-     * in the offset from UTC or a change in the DST.
-     *
-     * <p>These times are pre-calculated externally from a set of rules (both historical and
-     * future) and stored in a file from which {@link ZoneInfo#readTimeZone(String, BufferIterator,
-     * long)} reads the data. That is quite different to {@link java.util.SimpleTimeZone}, which has
-     * essentially human readable rules (e.g. DST starts at 01:00 on the first Sunday in March and
-     * ends at 01:00 on the last Sunday in October) that can be used to determine the DST transition
-     * times across a number of years
-     *
-     * <p>In terms of {@link ZoneInfo tzfile} structure this array is of length {@code tzh_timecnt}
-     * and contains the times in seconds converted to long to make them safer to use.
-     *
-     * <p>They are stored in order from earliest (lowest) time to latest (highest). A transition is
-     * identified by its index within this array. A transition {@code T} is active at a specific
-     * time {@code X} if {@code T} is the highest transition whose time is less than or equal to
-     * {@code X}.
-     *
-     * @see #mTypes
+     * This field is kept only for app compatibility indicated by @UnsupportedAppUsage. Do not
+     * modify the content of this array as it is a reference to an internal data structure used by
+     * mDelegate.
      */
     @UnsupportedAppUsage
     private final long[] mTransitions;
 
     /**
-     * The type of the transition, where type is a pair consisting of the offset and whether the
-     * offset includes DST or not.
-     *
-     * <p>Each transition in {@link #mTransitions} has an associated type in this array at the same
-     * index. The type is an index into the arrays {@link #mOffsets} and {@link #mIsDsts} that each
-     * contain one part of the pair.
-     *
-     * <p>In the {@link ZoneInfo tzfile} structure the type array only contains unique instances of
-     * the {@code struct ttinfo} to save space and each type may be referenced by multiple
-     * transitions. However, the type pairs stored in this class are not guaranteed unique because
-     * they do not include the {@code tt_abbrind}, which is the abbreviated identifier to use for
-     * the time zone after the transition.
-     *
-     * @see #mTransitions
-     * @see #mOffsets
-     * @see #mIsDsts
+     * Despite being transient, mDelegate is still serialized as part of this object. Please
+     * see {@link #readObject(ObjectInputStream)} and {@link #writeObject(ObjectOutputStream)}
      */
-    private final byte[] mTypes;
+    private transient ZoneInfoData mDelegate;
 
     /**
-     * The offset parts of the transition types, in seconds.
-     *
-     * <p>These are actually a delta to the {@link #mRawOffset}. So, if the offset is say +7200
-     * seconds and {@link #mRawOffset} is say +3600 then this will have a value of +3600.
-     *
-     * <p>The offset in milliseconds can be computed using:
-     * {@code mRawOffset + mOffsets[type] * 1000}
-     *
-     * @see #mTypes
-     * @see #mIsDsts
+     * Creates an instance using the current system clock time to calculate the {@link #mDstSavings}
+     * and {@link #mUseDst} fields. See also {@link #createZoneInfo(ZoneInfoData, long)}.
      */
-    private final int[] mOffsets;
-
-    /**
-     * Specifies whether an associated offset includes DST or not.
-     *
-     * <p>Each entry in here is 1 if the offset at the same index in {@link #mOffsets} includes DST
-     * and 0 otherwise.
-     *
-     * @see #mTypes
-     * @see #mOffsets
-     */
-    private final byte[] mIsDsts;
-
-    public static ZoneInfo readTimeZone(String id, BufferIterator it, long currentTimeMillis)
-            throws IOException {
-
-        // Skip over the superseded 32-bit header and data.
-        skipOver32BitData(id, it);
-
-        // Read the v2+ 64-bit header and data.
-        return read64BitData(id, it, currentTimeMillis);
+    public static ZoneInfo createZoneInfo(ZoneInfoData delegate) {
+        return createZoneInfo(delegate, System.currentTimeMillis());
     }
 
     /**
-     * Skip over the 32-bit data with some minimal validation to make sure sure we reading a valid
-     * and supported file.
+     * Creates an instance and recalculate the fields {@link #mDstSavings} and {@link #mUseDst} from
+     * the {@code timeInMillis}.
      */
-    private static void skipOver32BitData(String id, BufferIterator it) throws IOException {
-        // Variable names beginning tzh_ correspond to those in "tzfile.h".
-
-        // Check tzh_magic.
-        int tzh_magic = it.readInt();
-        if (tzh_magic != 0x545a6966) { // "TZif"
-            throw new IOException("Timezone id=" + id + " has an invalid header=" + tzh_magic);
-        }
-
-        byte tzh_version = it.readByte();
-        checkTzifVersionAcceptable(id, tzh_version);
-
-        // Skip the unused bytes.
-        it.skip(15);
-
-        // Read the header values necessary to read through all the 32-bit data.
-        int tzh_ttisgmtcnt = it.readInt();
-        int tzh_ttisstdcnt = it.readInt();
-        int tzh_leapcnt = it.readInt();
-        int tzh_timecnt = it.readInt();
-        int tzh_typecnt = it.readInt();
-        int tzh_charcnt = it.readInt();
-
-        // Skip transitions data, 4 bytes for each 32-bit time + 1 byte for isDst.
-        final int transitionInfoSize = 4 + 1;
-        it.skip(tzh_timecnt * transitionInfoSize);
-
-        // Skip ttinfos.
-        // struct ttinfo {
-        //     int32_t       tt_gmtoff;
-        //     unsigned char tt_isdst;
-        //     unsigned char tt_abbrind;
-        // };
-        final int ttinfoSize = 4 + 1 + 1;
-        it.skip(tzh_typecnt * ttinfoSize);
-
-        // Skip tzh_charcnt time zone abbreviations.
-        it.skip(tzh_charcnt);
-
-        // Skip tzh_leapcnt repetitions of a 32-bit time + a 32-bit correction.
-        int leapInfoSize = 4 + 4;
-        it.skip(tzh_leapcnt * leapInfoSize);
-
-        // Skip ttisstds and ttisgmts information. These can be ignored for our usecases as per
-        // https://mm.icann.org/pipermail/tz/2006-February/013359.html
-        it.skip(tzh_ttisstdcnt + tzh_ttisgmtcnt);
+    // VisibleForTesting
+    public static ZoneInfo createZoneInfo(ZoneInfoData delegate, long timeInMillis) {
+        Integer latestDstSavings = delegate.getLatestDstSavingsMillis(timeInMillis);
+        boolean useDst = latestDstSavings != null;
+        int dstSavings = latestDstSavings == null ? 0 : latestDstSavings;
+        return new ZoneInfo(delegate, dstSavings, useDst);
     }
 
-    /**
-     * Read the 64-bit header and data for {@code id} from the current position of {@code it} and
-     * return a ZoneInfo.
-     */
-    private static ZoneInfo read64BitData(String id, BufferIterator it, long currentTimeMillis)
-            throws IOException {
-        // Variable names beginning tzh_ correspond to those in "tzfile.h".
-
-        // Check tzh_magic.
-        int tzh_magic = it.readInt();
-        if (tzh_magic != 0x545a6966) { // "TZif"
-            throw new IOException("Timezone id=" + id + " has an invalid header=" + tzh_magic);
-        }
-
-        byte tzh_version = it.readByte();
-        checkTzifVersionAcceptable(id, tzh_version);
-
-        // Skip the uninteresting parts of the header.
-        it.skip(27);
-
-        // Read the sizes of the arrays we're about to read.
-        int tzh_timecnt = it.readInt();
-
-        // Arbitrary ceiling to prevent allocating memory for corrupt data.
-        final int MAX_TRANSITIONS = 2000;
-        if (tzh_timecnt < 0 || tzh_timecnt > MAX_TRANSITIONS) {
-            throw new IOException(
-                    "Timezone id=" + id + " has an invalid number of transitions="
-                            + tzh_timecnt);
-        }
-
-        int tzh_typecnt = it.readInt();
-        final int MAX_TYPES = 256;
-        if (tzh_typecnt < 1) {
-            throw new IOException("ZoneInfo requires at least one type "
-                    + "to be provided for each timezone but could not find one for '" + id
-                    + "'");
-        } else if (tzh_typecnt > MAX_TYPES) {
-            throw new IOException(
-                    "Timezone with id " + id + " has too many types=" + tzh_typecnt);
-        }
-
-        it.skip(4); // Skip tzh_charcnt.
-
-        long[] transitions64 = new long[tzh_timecnt];
-        it.readLongArray(transitions64, 0, transitions64.length);
-        for (int i = 0; i < tzh_timecnt; ++i) {
-            if (i > 0 && transitions64[i] <= transitions64[i - 1]) {
-                throw new IOException(
-                        id + " transition at " + i + " is not sorted correctly, is "
-                                + transitions64[i] + ", previous is " + transitions64[i - 1]);
-            }
-        }
-
-        byte[] types = new byte[tzh_timecnt];
-        it.readByteArray(types, 0, types.length);
-        for (int i = 0; i < types.length; i++) {
-            int typeIndex = types[i] & 0xff;
-            if (typeIndex >= tzh_typecnt) {
-                throw new IOException(
-                        id + " type at " + i + " is not < " + tzh_typecnt + ", is "
-                                + typeIndex);
-            }
-        }
-
-        int[] gmtOffsets = new int[tzh_typecnt];
-        byte[] isDsts = new byte[tzh_typecnt];
-        for (int i = 0; i < tzh_typecnt; ++i) {
-            gmtOffsets[i] = it.readInt();
-            byte isDst = it.readByte();
-            if (isDst != 0 && isDst != 1) {
-                throw new IOException(id + " dst at " + i + " is not 0 or 1, is " + isDst);
-            }
-            isDsts[i] = isDst;
-            // We skip the abbreviation index. This would let us provide historically-accurate
-            // time zone abbreviations (such as "AHST", "YST", and "AKST" for standard time in
-            // America/Anchorage in 1982, 1983, and 1984 respectively). ICU only knows the current
-            // names, though, so even if we did use this data to provide the correct abbreviations
-            // for en_US, we wouldn't be able to provide correct abbreviations for other locales,
-            // nor would we be able to provide correct long forms (such as "Yukon Standard Time")
-            // for any locale. (The RI doesn't do any better than us here either.)
-            it.skip(1);
-        }
-        return new ZoneInfo(id, transitions64, types, gmtOffsets, isDsts, currentTimeMillis);
+    private ZoneInfo(ZoneInfoData delegate, int dstSavings, boolean useDst) {
+        mDelegate = delegate;
+        mDstSavings = dstSavings;
+        mUseDst = useDst;
+        mTransitions = delegate.getTransitions();
+        setID(delegate.getID());
     }
 
-    private static void checkTzifVersionAcceptable(String id, byte tzh_version) throws IOException {
-        char tzh_version_char = (char) tzh_version;
-        // Version >= 2 is required because the 64-bit time section is required. v3 is the latest
-        // version known at the time of writing and is identical to v2 in the parts used by this
-        // class.
-        if (tzh_version_char != '2' && tzh_version_char != '3') {
-            throw new IOException(
-                    "Timezone id=" + id + " has an invalid format version=\'" + tzh_version_char
-                            + "\' (" + tzh_version + ")");
-        }
-    }
-
-    private ZoneInfo(String name, long[] transitions, byte[] types, int[] gmtOffsets, byte[] isDsts,
-            long currentTimeMillis) {
-        if (gmtOffsets.length == 0) {
-            throw new IllegalArgumentException("ZoneInfo requires at least one offset "
-                    + "to be provided for each timezone but could not find one for '" + name + "'");
-        }
-        mTransitions = transitions;
-        mTypes = types;
-        mIsDsts = isDsts;
-        setID(name);
-
-        // Find the latest daylight and standard offsets (if any).
-        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 (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 (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[lastStdTransitionIndex] & 0xff];
-        }
-
-        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[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
-            // rounds up rather than down. It does that because this is interested in what
-            // transitions apply in future
-            long currentUnixTimeSeconds = roundUpMillisToSeconds(currentTimeMillis);
-
-            // Is this zone observing DST currently or in the future?
-            // We don't care if they've historically used it: most places have at least once.
-            // See http://code.google.com/p/android/issues/detail?id=877.
-            // This test means that for somewhere like Morocco, which tried DST in 2009 but has
-            // no future plans (and thus no future schedule info) will report "true" from
-            // 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.
-                lastDstTransitionIndex = -1;
-            }
-        }
-
-        if (lastDstTransitionIndex == -1) {
-            // There were no DST transitions or at least no future DST transitions so DST is not
-            // used.
-            mDstSavings = 0;
-            mUseDst = false;
-        } 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[lastStdTransitionIndex] & 0xff];
-            int lastDstOffset = gmtOffsets[mTypes[lastDstTransitionIndex] & 0xff];
-            mDstSavings = (lastDstOffset - lastGmtOffset) * 1000;
-            mUseDst = true;
-        }
-
-        // 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 = (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.
-        mOffsets = gmtOffsets;
-        for (int i = 0; i < mOffsets.length; i++) {
-            mOffsets[i] -= mRawOffset;
-        }
-
-        // tzdata uses seconds, but Java uses milliseconds.
-        mRawOffset *= 1000;
-        mEarliestRawOffset = earliestRawOffset * 1000;
-    }
-
-    /**
-     * Ensure that when deserializing an instance that {@link #mDstSavings} is always 0 when
-     * {@link #mUseDst} is false.
-     */
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-        in.defaultReadObject();
-        if (!mUseDst && mDstSavings != 0) {
-            mDstSavings = 0;
+        GetField getField = in.readFields();
+        // TimeZone#getID() should return the proper ID because the fields in the superclass should
+        // have been deserialized.
+        mDelegate = ZoneInfoData.createFromSerializationFields(getID(), getField);
+
+        // Set the final fields by reflection.
+        boolean useDst = getField.get("mUseDst", false);
+        int dstSavings = getField.get("mDstSavings", 0);
+        long[] transitions = mDelegate.getTransitions();
+        /** For pre-OpenJDK compatibility, ensure that when deserializing an instance that
+         * {@link #mDstSavings} is always 0 when {@link #mUseDst} is false
+         */
+        if (!useDst && dstSavings != 0) {
+            dstSavings = 0;
         }
+        int finalDstSavings = dstSavings;
+        setFinalField("mDstSavings", (f -> f.setInt(this, finalDstSavings)));
+        setFinalField("mUseDst", (f -> f.setBoolean(this, useDst)));
+        setFinalField("mTransitions", (f -> f.set(this, transitions)));
+    }
+
+    private void writeObject(ObjectOutputStream out) throws IOException {
+        PutField putField = out.putFields();
+        putField.put("mUseDst", mUseDst);
+        putField.put("mDstSavings", mDstSavings);
+        // mDelegate writes the field mTransitions.
+        mDelegate.writeToSerializationFields(putField);
+        out.writeFields();
+    }
+
+    private static void setFinalField(String field, FieldSetter setter) {
+        try {
+            Field mTransitionsField = ZoneInfo.class.getDeclaredField(field);
+            mTransitionsField.setAccessible(true);
+            setter.set(mTransitionsField);
+        } catch (ReflectiveOperationException e) {
+            // The field should always exist because it's a member field in this class.
+        }
+    }
+
+    private interface FieldSetter {
+        void set(Field field) throws IllegalArgumentException, IllegalAccessException;
     }
 
     @Override
@@ -489,244 +218,60 @@
         calc += (day - 1) * MILLISECONDS_PER_DAY;
         calc += millis;
 
-        calc -= mRawOffset;
+        calc -= mDelegate.getRawOffset();
         calc -= UNIX_OFFSET;
 
-        return getOffset(calc);
-    }
-
-    /**
-     * Find the transition in the {@code timezone} in effect at {@code seconds}.
-     *
-     * <p>Returns an index in the range -1..timeZone.mTransitions.length - 1. -1 is used to
-     * indicate the time is before the first transition. Other values are an index into
-     * timeZone.mTransitions.
-     */
-    public int findTransitionIndex(long seconds) {
-        int transition = Arrays.binarySearch(mTransitions, seconds);
-        if (transition < 0) {
-            transition = ~transition - 1;
-            if (transition < 0) {
-                return -1;
-            }
-        }
-
-        return transition;
-    }
-
-    /**
-     * Finds the index within the {@link #mOffsets}/{@link #mIsDsts} arrays for the specified time
-     * in seconds, since 1st Jan 1970 00:00:00.
-     * @param seconds the time in seconds.
-     * @return -1 if the time is before the first transition, or [0..{@code mOffsets}-1] for the
-     * active offset.
-     */
-    int findOffsetIndexForTimeInSeconds(long seconds) {
-        int transition = findTransitionIndex(seconds);
-        if (transition < 0) {
-            return -1;
-        }
-
-        return mTypes[transition] & 0xff;
-    }
-
-    /**
-     * Finds the index within the {@link #mOffsets}/{@link #mIsDsts} arrays for the specified time
-     * in milliseconds, since 1st Jan 1970 00:00:00.000.
-     * @param millis the time in milliseconds.
-     * @return -1 if the time is before the first transition, or [0..{@code mOffsets}-1] for the
-     * active offset.
-     */
-    int findOffsetIndexForTimeInMilliseconds(long millis) {
-        // This rounds the time in milliseconds down to the time in seconds.
-        //
-        // It can't just divide a timestamp in millis by 1000 to obtain a transition time in
-        // seconds because / (div) in Java rounds towards zero. Times before 1970 are negative and
-        // if they have a millisecond component then div would result in obtaining a time that is
-        // one second after what we need.
-        //
-        // e.g. dividing -12,001 milliseconds by 1000 would result in -12 seconds. If there was a
-        //      transition at -12 seconds then that would be incorrectly treated as being active
-        //      for a time of -12,001 milliseconds even though that time is before the transition
-        //      should occur.
-
-        return findOffsetIndexForTimeInSeconds(roundDownMillisToSeconds(millis));
-    }
-
-    /**
-     * Converts time in milliseconds into a time in seconds, rounding down to the closest time
-     * in seconds before the time in milliseconds.
-     *
-     * <p>It's not sufficient to simply divide by 1000 because that rounds towards 0 and so while
-     * for positive numbers it produces a time in seconds that precedes the time in milliseconds
-     * for negative numbers it can produce a time in seconds that follows the time in milliseconds.
-     *
-     * <p>This basically does the same as {@code (long) Math.floor(millis / 1000.0)} but should be
-     * faster.
-     *
-     * @param millis the time in milliseconds, may be negative.
-     * @return the time in seconds.
-     */
-    static long roundDownMillisToSeconds(long millis) {
-        if (millis < 0) {
-            // If the time is less than zero then subtract 999 and then divide by 1000 rounding
-            // towards 0 as usual, e.g.
-            // -12345 -> -13344 / 1000 = -13
-            // -12000 -> -12999 / 1000 = -12
-            // -12001 -> -13000 / 1000 = -13
-            return (millis - 999) / 1000;
-        } else {
-            return millis / 1000;
-        }
-    }
-
-    /**
-     * Converts time in milliseconds into a time in seconds, rounding up to the closest time
-     * in seconds before the time in milliseconds.
-     *
-     * <p>It's not sufficient to simply divide by 1000 because that rounds towards 0 and so while
-     * for negative numbers it produces a time in seconds that follows the time in milliseconds
-     * for positive numbers it can produce a time in seconds that precedes the time in milliseconds.
-     *
-     * <p>This basically does the same as {@code (long) Math.ceil(millis / 1000.0)} but should be
-     * faster.
-     *
-     * @param millis the time in milliseconds, may be negative.
-     * @return the time in seconds.
-     */
-    static long roundUpMillisToSeconds(long millis) {
-        if (millis > 0) {
-            // If the time is greater than zero then add 999 and then divide by 1000 rounding
-            // towards 0 as usual, e.g.
-            // 12345 -> 13344 / 1000 = 13
-            // 12000 -> 12999 / 1000 = 12
-            // 12001 -> 13000 / 1000 = 13
-            return (millis + 999) / 1000;
-        } else {
-            return millis / 1000;
-        }
-    }
-
-    /**
-     * Get the raw and DST offsets for the specified time in milliseconds since
-     * 1st Jan 1970 00:00:00.000 UTC.
-     *
-     * <p>The raw offset, i.e. that part of the total offset which is not due to DST, is stored at
-     * index 0 of the {@code offsets} array and the DST offset, i.e. that part of the offset which
-     * is due to DST is stored at index 1.
-     *
-     * @param utcTimeInMillis the UTC time in milliseconds.
-     * @param offsets the array whose length must be greater than or equal to 2.
-     * @return the total offset which is the sum of the raw and DST offsets.
-     */
-    public int getOffsetsByUtcTime(long utcTimeInMillis, int[] offsets) {
-        int transitionIndex = findTransitionIndex(roundDownMillisToSeconds(utcTimeInMillis));
-        int totalOffset;
-        int rawOffset;
-        int dstOffset;
-        if (transitionIndex == -1) {
-            // See getOffset(long) and inDaylightTime(Date) for an explanation as to why these
-            // values are used for times before the first transition.
-            rawOffset = mEarliestRawOffset;
-            dstOffset = 0;
-            totalOffset = rawOffset;
-        } else {
-            int type = mTypes[transitionIndex] & 0xff;
-
-            // Get the total offset used for the transition.
-            totalOffset = mRawOffset + mOffsets[type] * 1000;
-            if (mIsDsts[type] == 0) {
-                // Offset does not include DST so DST is 0 and the raw offset is the total offset.
-                rawOffset = totalOffset;
-                dstOffset = 0;
-            } else {
-                // Offset does include DST, we need to find the preceding transition that did not
-                // include the DST offset so that we can calculate the DST offset.
-                rawOffset = -1;
-                for (transitionIndex -= 1; transitionIndex >= 0; --transitionIndex) {
-                    type = mTypes[transitionIndex] & 0xff;
-                    if (mIsDsts[type] == 0) {
-                        rawOffset = mRawOffset + mOffsets[type] * 1000;
-                        break;
-                    }
-                }
-                // If no previous transition was found then use the earliest raw offset.
-                if (rawOffset == -1) {
-                    rawOffset = mEarliestRawOffset;
-                }
-
-                // The DST offset is the difference between the total and the raw offset.
-                dstOffset = totalOffset - rawOffset;
-            }
-        }
-
-        offsets[0] = rawOffset;
-        offsets[1] = dstOffset;
-
-        return totalOffset;
+        return mDelegate.getOffset(calc);
     }
 
     @Override
     public int getOffset(long when) {
-        int offsetIndex = findOffsetIndexForTimeInMilliseconds(when);
-        if (offsetIndex == -1) {
-            // Assume that all times before our first transition correspond to the
-            // oldest-known non-daylight offset. The obvious alternative would be to
-            // use the current raw offset, but that seems like a greater leap of faith.
-            return mEarliestRawOffset;
-        }
-        return mRawOffset + mOffsets[offsetIndex] * 1000;
+        return mDelegate.getOffset(when);
     }
 
-    @Override public boolean inDaylightTime(Date time) {
-        long when = time.getTime();
-        int offsetIndex = findOffsetIndexForTimeInMilliseconds(when);
-        if (offsetIndex == -1) {
-            // Assume that all times before our first transition are non-daylight.
-            // Transition data tends to start with a transition to daylight, so just
-            // copying the first transition would assume the opposite.
-            // http://code.google.com/p/android/issues/detail?id=14395
-            return false;
-        }
-        return mIsDsts[offsetIndex] == 1;
+    @Override
+    public boolean inDaylightTime(Date time) {
+        return mDelegate.isInDaylightTime(time.getTime());
     }
 
-    @Override public int getRawOffset() {
-        return mRawOffset;
+    @Override
+    public int getRawOffset() {
+        return mDelegate.getRawOffset();
     }
 
-    @Override public void setRawOffset(int off) {
-        mRawOffset = off;
+    @Override
+    public void setRawOffset(int off) {
+        mDelegate = mDelegate.createCopyWithRawOffset(off);
     }
 
-    @Override public int getDSTSavings() {
+    @Override
+    public int getDSTSavings() {
         return mDstSavings;
     }
 
-    @Override public boolean useDaylightTime() {
+    @Override
+    public boolean useDaylightTime() {
         return mUseDst;
     }
 
-    @Override public boolean hasSameRules(TimeZone timeZone) {
+    @Override
+    public boolean hasSameRules(TimeZone timeZone) {
         if (!(timeZone instanceof ZoneInfo)) {
             return false;
         }
         ZoneInfo other = (ZoneInfo) timeZone;
+
         if (mUseDst != other.mUseDst) {
             return false;
         }
         if (!mUseDst) {
-            return mRawOffset == other.mRawOffset;
+            return mDelegate.getRawOffset() == other.getRawOffset();
         }
-        return mRawOffset == other.mRawOffset
-                // Arrays.equals returns true if both arrays are null
-                && Arrays.equals(mOffsets, other.mOffsets)
-                && Arrays.equals(mIsDsts, other.mIsDsts)
-                && Arrays.equals(mTypes, other.mTypes)
-                && Arrays.equals(mTransitions, other.mTransitions);
+        return mDelegate.hasSameRules(other.mDelegate);
     }
 
-    @Override public boolean equals(Object obj) {
+    @Override
+    public boolean equals(Object obj) {
         if (!(obj instanceof ZoneInfo)) {
             return false;
         }
@@ -736,736 +281,29 @@
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + getID().hashCode();
-        result = prime * result + Arrays.hashCode(mOffsets);
-        result = prime * result + Arrays.hashCode(mIsDsts);
-        result = prime * result + mRawOffset;
-        result = prime * result + Arrays.hashCode(mTransitions);
-        result = prime * result + Arrays.hashCode(mTypes);
-        result = prime * result + (mUseDst ? 1231 : 1237);
-        return result;
+        /*
+         * TODO(http://b/173499812): Can 2 ZoneInfo objects have different hashCode but equals?
+         * mDelegate.hashCode compares more fields than rules and ID.
+         */
+        return Objects.hash(mUseDst, mDelegate);
     }
 
     @Override
     public String toString() {
-        return getClass().getName() + "[id=\"" + getID() + "\"" +
-            ",mRawOffset=" + mRawOffset +
-            ",mEarliestRawOffset=" + mEarliestRawOffset +
-            ",mUseDst=" + mUseDst +
-            ",mDstSavings=" + mDstSavings +
-            ",transitions=" + mTransitions.length +
-            "]";
+        return getClass().getName() +
+                "[mDstSavings=" + mDstSavings +
+                ",mUseDst=" + mUseDst +
+                ",mDelegate=" + mDelegate.toString() + "]";
     }
 
     @Override
     public Object clone() {
-        // Overridden for documentation. The default clone() behavior is exactly what we want.
-        // Though mutable, the arrays of offset data are treated as immutable. Only ID and
-        // mRawOffset are mutable in this class, and those are an immutable object and a primitive
-        // respectively.
-        return super.clone();
+        // Pass the mDstSavings and mUseDst explicitly because they must not be recalculated when
+        // cloning. See {@link #create(ZoneInfoData)}.
+        return new ZoneInfo(mDelegate, mDstSavings, mUseDst);
     }
 
-    /**
-     * A class that represents a "wall time". This class is modeled on the C tm struct and
-     * is used to support android.text.format.Time behavior. Unlike the tm struct the year is
-     * represented as the full year, not the years since 1900.
-     *
-     * <p>This class contains a rewrite of various native functions that android.text.format.Time
-     * once relied on such as mktime_tz and localtime_tz. This replacement does not support leap
-     * seconds but does try to preserve behavior around ambiguous date/times found in the BSD
-     * version of mktime that was previously used.
-     *
-     * <p>The original native code used a 32-bit value for time_t on 32-bit Android, which
-     * was the only variant of Android available at the time. To preserve old behavior this code
-     * deliberately uses {@code int} rather than {@code long} for most things and performs
-     * calculations in seconds. This creates deliberate truncation issues for date / times before
-     * 1901 and after 2038. This is intentional but might be fixed in future if all the knock-ons
-     * can be resolved: Application code may have come to rely on the range so previously values
-     * like zero for year could indicate an invalid date but if we move to long the year zero would
-     * be valid.
-     *
-     * <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
-        // and to convert from a broken-down date/time to a millis value.
-        // Unfortunately, it cannot represent an initial state with a zero day and would
-        // automatically normalize it, so we must copy values into and out of it as needed.
-        private final GregorianCalendar calendar;
-
-        private int year;
-        private int month;
-        private int monthDay;
-        private int hour;
-        private int minute;
-        private int second;
-        private int weekDay;
-        private int yearDay;
-        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"));
-        }
-
-        /**
-         * Sets the wall time to a point in time using the time zone information provided. This
-         * is a replacement for the old native localtime_tz() function.
-         *
-         * <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;
-
-                // Find out the timezone DST state and adjustment.
-                byte isDst;
-                if (zoneInfo.mTransitions.length == 0) {
-                    isDst = 0;
-                } else {
-                    // offsetIndex can be in the range -1..zoneInfo.mOffsets.length - 1
-                    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
-                        // earliest known raw offset.
-                        offsetSeconds = zoneInfo.mEarliestRawOffset / 1000;
-                        isDst = 0;
-                    } else {
-                        offsetSeconds += zoneInfo.mOffsets[offsetIndex];
-                        isDst = zoneInfo.mIsDsts[offsetIndex];
-                    }
-                }
-
-                // Perform arithmetic that might underflow before setting fields.
-                int wallTimeSeconds = checked32BitAdd(timeSeconds, offsetSeconds);
-
-                // Set fields.
-                calendar.setTimeInMillis(wallTimeSeconds * 1000L);
-                copyFieldsFromCalendar();
-                this.isDst = isDst;
-                this.gmtOffsetSeconds = offsetSeconds;
-            } catch (CheckedArithmeticException e) {
-                // Just stop, leaving fields untouched.
-            }
-        }
-
-        /**
-         * Returns the time in seconds since beginning of the Unix epoch for the wall time using the
-         * time zone information provided. This is a replacement for an old native mktime_tz() C
-         * function.
-         *
-         * <p>When going from a wall time to an instant the answer can be ambiguous. A wall
-         * time can map to zero, one or two instants given sane date/time transitions. Sane
-         * in this case means that transitions occur less frequently than the offset
-         * differences between them (which could cause all sorts of craziness like the
-         * skipping out of transitions).
-         *
-         * <p>For example, this is not fully supported:
-         * <ul>
-         *     <li>t1 { time = 1, offset = 0 }
-         *     <li>t2 { time = 2, offset = -1 }
-         *     <li>t3 { time = 3, offset = -2 }
-         * </ul>
-         * A wall time in this case might map to t1, t2 or t3.
-         *
-         * <p>We do not handle leap seconds.
-         * <p>We assume that no timezone offset transition has an absolute offset > 24 hours.
-         * <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;
-
-            copyFieldsToCalendar();
-            final long longWallTimeSeconds = calendar.getTimeInMillis() / 1000;
-            if (Integer.MIN_VALUE > longWallTimeSeconds
-                    || longWallTimeSeconds > Integer.MAX_VALUE) {
-                // For compatibility with the old native 32-bit implementation we must treat
-                // this as an error. Note: -1 could be confused with a real time.
-                return -1;
-            }
-
-            try {
-                final int wallTimeSeconds =  (int) longWallTimeSeconds;
-                final int rawOffsetSeconds = zoneInfo.mRawOffset / 1000;
-                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.
-                    if (this.isDst > 0) {
-                        // Caller has asserted DST, but there is no DST information available.
-                        return -1;
-                    }
-                    copyFieldsFromCalendar();
-                    this.isDst = 0;
-                    this.gmtOffsetSeconds = rawOffsetSeconds;
-                    return rawTimeSeconds;
-                }
-
-                // We cannot know for sure what instant the wall time will map to. Unfortunately, in
-                // order to know for sure we need the timezone information, but to get the timezone
-                // information we need an instant. To resolve this we use the raw offset to find an
-                // OffsetInterval; this will get us the OffsetInterval we need or very close.
-
-                // The initialTransition can be between -1 and (zoneInfo.mTransitions - 1). -1
-                // indicates the rawTime is before the first transition and is handled gracefully by
-                // createOffsetInterval().
-                final int initialTransitionIndex = zoneInfo.findTransitionIndex(rawTimeSeconds);
-
-                if (isDst < 0) {
-                    // This is treated as a special case to get it out of the way:
-                    // When a caller has set isDst == -1 it means we can return the first match for
-                    // the wall time we find. If the caller has specified a wall time that cannot
-                    // exist this always returns -1.
-
-                    Integer result = doWallTimeSearch(zoneInfo, initialTransitionIndex,
-                            wallTimeSeconds, true /* mustMatchDst */);
-                    return result == null ? -1 : result;
-                }
-
-                // If the wall time asserts a DST (isDst == 0 or 1) the search is performed twice:
-                // 1) The first attempts to find a DST offset that matches isDst exactly.
-                // 2) If it fails, isDst is assumed to be incorrect and adjustments are made to see
-                // if a valid wall time can be created. The result can be somewhat arbitrary.
-
-                Integer result = doWallTimeSearch(zoneInfo, initialTransitionIndex, wallTimeSeconds,
-                        true /* mustMatchDst */);
-                if (result == null) {
-                    result = doWallTimeSearch(zoneInfo, initialTransitionIndex, wallTimeSeconds,
-                            false /* mustMatchDst */);
-                }
-                if (result == null) {
-                    result = -1;
-                }
-                return result;
-            } catch (CheckedArithmeticException e) {
-                return -1;
-            }
-        }
-
-        /**
-         * Attempt to apply DST adjustments to {@code oldWallTimeSeconds} to create a wall time in
-         * {@code targetInterval}.
-         *
-         * <p>This is used when a caller has made an assertion about standard time / DST that cannot
-         * be matched to any offset interval that exists. We must therefore assume that the isDst
-         * assertion is incorrect and the invalid wall time is the result of some modification the
-         * caller made to a valid wall time that pushed them outside of the offset interval they
-         * were in. We must correct for any DST change that should have been applied when they did
-         * so.
-         *
-         * <p>Unfortunately, we have no information about what adjustment they made and so cannot
-         * know which offset interval they were previously in. For example, they may have added a
-         * second or a year to a valid time to arrive at what they have.
-         *
-         * <p>We try all offset types that are not the same as the isDst the caller asserted. For
-         * each possible offset we work out the offset difference between that and
-         * {@code targetInterval}, apply it, and see if we are still in {@code targetInterval}. If
-         * we are, then we have found an adjustment.
-         */
-        private Integer tryOffsetAdjustments(ZoneInfo zoneInfo, int oldWallTimeSeconds,
-                OffsetInterval targetInterval, int transitionIndex, int isDstToFind)
-                throws CheckedArithmeticException {
-
-            int[] offsetsToTry = getOffsetsOfType(zoneInfo, transitionIndex, isDstToFind);
-            for (int j = 0; j < offsetsToTry.length; j++) {
-                int rawOffsetSeconds = zoneInfo.mRawOffset / 1000;
-                int jOffsetSeconds = rawOffsetSeconds + offsetsToTry[j];
-                int targetIntervalOffsetSeconds = targetInterval.getTotalOffsetSeconds();
-                int adjustmentSeconds = targetIntervalOffsetSeconds - jOffsetSeconds;
-                int adjustedWallTimeSeconds =
-                        checked32BitAdd(oldWallTimeSeconds, adjustmentSeconds);
-                if (targetInterval.containsWallTime(adjustedWallTimeSeconds)) {
-                    // Perform any arithmetic that might overflow.
-                    int returnValue = checked32BitSubtract(adjustedWallTimeSeconds,
-                            targetIntervalOffsetSeconds);
-
-                    // Modify field state and return the result.
-                    calendar.setTimeInMillis(adjustedWallTimeSeconds * 1000L);
-                    copyFieldsFromCalendar();
-                    this.isDst = targetInterval.getIsDst();
-                    this.gmtOffsetSeconds = targetIntervalOffsetSeconds;
-                    return returnValue;
-                }
-            }
-            return null;
-        }
-
-        /**
-         * Return an array of offsets that have the requested {@code isDst} value.
-         * The {@code startIndex} is used as a starting point so transitions nearest
-         * to that index are returned first.
-         */
-        private static int[] getOffsetsOfType(ZoneInfo zoneInfo, int startIndex, int isDst) {
-            // +1 to account for the synthetic transition we invent before the first recorded one.
-            int[] offsets = new int[zoneInfo.mOffsets.length + 1];
-            boolean[] seen = new boolean[zoneInfo.mOffsets.length];
-            int numFound = 0;
-
-            int delta = 0;
-            boolean clampTop = false;
-            boolean clampBottom = false;
-            do {
-                // delta = { 1, -1, 2, -2, 3, -3...}
-                delta *= -1;
-                if (delta >= 0) {
-                    delta++;
-                }
-
-                int transitionIndex = startIndex + delta;
-                if (delta < 0 && transitionIndex < -1) {
-                    clampBottom = true;
-                    continue;
-                } else if (delta > 0 && transitionIndex >=  zoneInfo.mTypes.length) {
-                    clampTop = true;
-                    continue;
-                }
-
-                if (transitionIndex == -1) {
-                    if (isDst == 0) {
-                        // Synthesize a non-DST transition before the first transition we have
-                        // data for.
-                        offsets[numFound++] = 0; // offset of 0 from raw offset
-                    }
-                    continue;
-                }
-                int type = zoneInfo.mTypes[transitionIndex] & 0xff;
-                if (!seen[type]) {
-                    if (zoneInfo.mIsDsts[type] == isDst) {
-                        offsets[numFound++] = zoneInfo.mOffsets[type];
-                    }
-                    seen[type] = true;
-                }
-            } while (!(clampTop && clampBottom));
-
-            int[] toReturn = new int[numFound];
-            System.arraycopy(offsets, 0, toReturn, 0, numFound);
-            return toReturn;
-        }
-
-        /**
-         * Find a time <em>in seconds</em> the same or close to {@code wallTimeSeconds} that
-         * satisfies {@code mustMatchDst}. The search begins around the timezone offset transition
-         * with {@code initialTransitionIndex}.
-         *
-         * <p>If {@code mustMatchDst} is {@code true} the method can only return times that
-         * use timezone offsets that satisfy the {@code this.isDst} requirements.
-         * If {@code this.isDst == -1} it means that any offset can be used.
-         *
-         * <p>If {@code mustMatchDst} is {@code false} any offset that covers the
-         * currently set time is acceptable. That is: if {@code this.isDst} == -1, any offset
-         * transition can be used, if it is 0 or 1 the offset used must match {@code this.isDst}.
-         *
-         * <p>Note: This method both uses and can modify field state. It returns the matching time
-         * in seconds if a match has been found and modifies fields, or it returns {@code null} and
-         * leaves the field state unmodified.
-         */
-        private Integer doWallTimeSearch(ZoneInfo zoneInfo, int initialTransitionIndex,
-                int wallTimeSeconds, boolean mustMatchDst) throws CheckedArithmeticException {
-
-            // The loop below starts at the initialTransitionIndex and radiates out from that point
-            // up to 24 hours in either direction by applying transitionIndexDelta to inspect
-            // adjacent transitions (0, -1, +1, -2, +2). 24 hours is used because we assume that no
-            // total offset from UTC is ever > 24 hours. clampTop and clampBottom are used to
-            // indicate whether the search has either searched > 24 hours or exhausted the
-            // transition data in that direction. The search stops when a match is found or if
-            // clampTop and clampBottom are both true.
-            // The match logic employed is determined by the mustMatchDst parameter.
-            final int MAX_SEARCH_SECONDS = 24 * 60 * 60;
-            boolean clampTop = false, clampBottom = false;
-            int loop = 0;
-            do {
-                // transitionIndexDelta = { 0, -1, 1, -2, 2,..}
-                int transitionIndexDelta = (loop + 1) / 2;
-                if (loop % 2 == 1) {
-                    transitionIndexDelta *= -1;
-                }
-                loop++;
-
-                // Only do any work in this iteration if we need to.
-                if (transitionIndexDelta > 0 && clampTop
-                        || transitionIndexDelta < 0 && clampBottom) {
-                    continue;
-                }
-
-                // Obtain the OffsetInterval to use.
-                int currentTransitionIndex = initialTransitionIndex + transitionIndexDelta;
-                OffsetInterval offsetInterval =
-                        OffsetInterval.create(zoneInfo, currentTransitionIndex);
-                if (offsetInterval == null) {
-                    // No transition exists with the index we tried: Stop searching in the
-                    // current direction.
-                    clampTop |= (transitionIndexDelta > 0);
-                    clampBottom |= (transitionIndexDelta < 0);
-                    continue;
-                }
-
-                // Match the wallTimeSeconds against the OffsetInterval.
-                if (mustMatchDst) {
-                    // Work out if the interval contains the wall time the caller specified and
-                    // matches their isDst value.
-                    if (offsetInterval.containsWallTime(wallTimeSeconds)) {
-                        if (this.isDst == -1 || offsetInterval.getIsDst() == this.isDst) {
-                            // This always returns the first OffsetInterval it finds that matches
-                            // the wall time and isDst requirements. If this.isDst == -1 this means
-                            // 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 =
-                                    checked32BitSubtract(wallTimeSeconds, totalOffsetSeconds);
-
-                            copyFieldsFromCalendar();
-                            this.isDst = offsetInterval.getIsDst();
-                            this.gmtOffsetSeconds = totalOffsetSeconds;
-                            return returnValue;
-                        }
-                    }
-                } else {
-                    // To retain similar behavior to the old native implementation: if the caller is
-                    // asserting the same isDst value as the OffsetInterval we are looking at we do
-                    // not try to find an adjustment from another OffsetInterval of the same isDst
-                    // type. If you remove this you get different results in situations like a
-                    // DST -> DST transition or STD -> STD transition that results in an interval of
-                    // "skipped" wall time. For example: if 01:30 (DST) is invalid and between two
-                    // DST intervals, and the caller has passed isDst == 1, this results in a -1
-                    // being returned.
-                    if (isDst != offsetInterval.getIsDst()) {
-                        final int isDstToFind = isDst;
-                        Integer returnValue = tryOffsetAdjustments(zoneInfo, wallTimeSeconds,
-                                offsetInterval, currentTransitionIndex, isDstToFind);
-                        if (returnValue != null) {
-                            return returnValue;
-                        }
-                    }
-                }
-
-                // See if we can avoid another loop in the current direction.
-                if (transitionIndexDelta > 0) {
-                    // If we are searching forward and the OffsetInterval we have ends
-                    // > MAX_SEARCH_SECONDS after the wall time, we don't need to look any further
-                    // forward.
-                    boolean endSearch = offsetInterval.getEndWallTimeSeconds() - wallTimeSeconds
-                            > MAX_SEARCH_SECONDS;
-                    if (endSearch) {
-                        clampTop = true;
-                    }
-                } else if (transitionIndexDelta < 0) {
-                    boolean endSearch = wallTimeSeconds - offsetInterval.getStartWallTimeSeconds()
-                            >= MAX_SEARCH_SECONDS;
-                    if (endSearch) {
-                        // If we are searching backward and the OffsetInterval starts
-                        // > MAX_SEARCH_SECONDS before the wall time, we don't need to look any
-                        // further backwards.
-                        clampBottom = true;
-                    }
-                }
-            } while (!(clampTop && clampBottom));
-            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;
-        }
-
-        private void copyFieldsToCalendar() {
-            calendar.set(Calendar.YEAR, year);
-            calendar.set(Calendar.MONTH, month);
-            calendar.set(Calendar.DAY_OF_MONTH, monthDay);
-            calendar.set(Calendar.HOUR_OF_DAY, hour);
-            calendar.set(Calendar.MINUTE, minute);
-            calendar.set(Calendar.SECOND, second);
-            calendar.set(Calendar.MILLISECOND, 0);
-        }
-
-        private void copyFieldsFromCalendar() {
-            year = calendar.get(Calendar.YEAR);
-            month = calendar.get(Calendar.MONTH);
-            monthDay = calendar.get(Calendar.DAY_OF_MONTH);
-            hour = calendar.get(Calendar.HOUR_OF_DAY);
-            minute = calendar.get(Calendar.MINUTE);
-            second =  calendar.get(Calendar.SECOND);
-
-            // Calendar uses Sunday == 1. Android Time uses Sunday = 0.
-            weekDay = calendar.get(Calendar.DAY_OF_WEEK) - 1;
-            // Calendar enumerates from 1, Android Time enumerates from 0.
-            yearDay = calendar.get(Calendar.DAY_OF_YEAR) - 1;
-        }
-    }
-
-    /**
-     * A wall-time representation of a timezone offset interval.
-     *
-     * <p>Wall-time means "as it would appear locally in the timezone in which it applies".
-     * For example in 2007:
-     * PST was a -8:00 offset that ran until Mar 11, 2:00 AM.
-     * PDT was a -7:00 offset and ran from Mar 11, 3:00 AM to Nov 4, 2:00 AM.
-     * PST was a -8:00 offset and ran from Nov 4, 1:00 AM.
-     * Crucially this means that there was a "gap" after PST when PDT started, and an overlap when
-     * PDT ended and PST began.
-     *
-     * <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;
-
-        /**
-         * Creates an {@link OffsetInterval}.
-         *
-         * <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} 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) {
-            if (transitionIndex < -1 || transitionIndex >= timeZone.mTransitions.length) {
-                return null;
-            }
-
-            if (transitionIndex == -1) {
-                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) {
-                endWallTimeSeconds = Integer.MAX_VALUE;
-            } else {
-                endWallTimeSeconds = saturated32BitAdd(
-                        timeZone.mTransitions[transitionIndex + 1], totalOffsetSeconds);
-            }
-            int isDst = timeZone.mIsDsts[type];
-            int startWallTimeSeconds =
-                    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);
-        }
-
-        private OffsetInterval(int startWallTimeSeconds, int endWallTimeSeconds, int isDst,
-                int totalOffsetSeconds) {
-            this.startWallTimeSeconds = startWallTimeSeconds;
-            this.endWallTimeSeconds = endWallTimeSeconds;
-            this.isDst = isDst;
-            this.totalOffsetSeconds = totalOffsetSeconds;
-        }
-
-        public boolean containsWallTime(long wallTimeSeconds) {
-            return wallTimeSeconds >= startWallTimeSeconds && wallTimeSeconds < endWallTimeSeconds;
-        }
-
-        public int getIsDst() {
-            return isDst;
-        }
-
-        public int getTotalOffsetSeconds() {
-            return totalOffsetSeconds;
-        }
-
-        public long getEndWallTimeSeconds() {
-            return endWallTimeSeconds;
-        }
-
-        public long getStartWallTimeSeconds() {
-            return startWallTimeSeconds;
-        }
-    }
-
-    /**
-     * An exception used to indicate an arithmetic overflow or underflow.
-     */
-    private static class CheckedArithmeticException extends Exception {
-    }
-
-    /**
-     * 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 checked32BitAdd(long a, int b) throws CheckedArithmeticException {
-        // Adapted from Guava IntMath.checkedAdd();
-        long result = a + b;
-        if (result != (int) result) {
-            throw new CheckedArithmeticException();
-        }
-        return (int) result;
-    }
-
-    /**
-     * 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 checked32BitSubtract(long a, int b) throws CheckedArithmeticException {
-        // Adapted from Guava IntMath.checkedSubtract();
-        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;
+    public int getOffsetsByUtcTime(long utcTimeInMillis, int[] offsets) {
+        return mDelegate.getOffsetsByUtcTime(utcTimeInMillis, offsets);
     }
 }
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 8872e1d..52ed681 100644
--- a/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
+++ b/luni/src/main/java/org/apache/harmony/xml/ExpatParser.java
@@ -268,7 +268,7 @@
          * specify how to tell whether or not the systemId is a URL let alone
          * how to resolve it.
          *
-         * Other implementations do various insane things. We try to keep it
+         * Other implementations do various dangerous things. We try to keep it
          * simple: if the systemId parses as a URI and it's relative, we try to
          * resolve it against the parent document's systemId. If anything goes
          * wrong, we go with the original systemId. If crazybob had designed
diff --git a/luni/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java b/luni/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
index d9b903f..662a0ff 100644
--- a/luni/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
+++ b/luni/src/main/java/org/apache/harmony/xml/dom/DocumentTypeImpl.java
@@ -81,12 +81,12 @@
     }
 
     public NamedNodeMap getEntities() {
-        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        // TODO Fake. Implement this later, if at all (we're DOM level 2 only).
         return null;
     }
 
     public String getInternalSubset() {
-        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        // TODO Fake. Implement this later, if at all (we're DOM level 2 only).
         return null;
     }
 
@@ -95,7 +95,7 @@
     }
 
     public NamedNodeMap getNotations() {
-        // TODO Dummy. Implement this later, if at all (we're DOM level 2 only).
+        // TODO Fake. Implement this later, if at all (we're DOM level 2 only).
         return null;
     }
 
diff --git a/luni/src/main/native/Android.bp b/luni/src/main/native/Android.bp
index 423cdd1..1f69c67 100644
--- a/luni/src/main/native/Android.bp
+++ b/luni/src/main/native/Android.bp
@@ -12,6 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
 filegroup {
     name: "luni_native_srcs",
     visibility: [
@@ -30,9 +38,8 @@
         "java_lang_StringToReal.cpp",
         "java_lang_invoke_MethodHandle.cpp",
         "java_lang_invoke_VarHandle.cpp",
-        "java_math_NativeBN.cpp",
+        "libcore_math_NativeBN.cpp",
         "libcore_icu_ICU.cpp",
-        "libcore_icu_TimeZoneNames.cpp",
         "libcore_io_AsynchronousCloseMonitor.cpp",
         "libcore_io_Linux.cpp",
         "libcore_io_Memory.cpp",
diff --git a/luni/src/main/native/IcuUtilities.cpp b/luni/src/main/native/IcuUtilities.cpp
index 0db59f9..6811ce5 100644
--- a/luni/src/main/native/IcuUtilities.cpp
+++ b/luni/src/main/native/IcuUtilities.cpp
@@ -16,18 +16,11 @@
 
 #define LOG_TAG "IcuUtilities"
 
-#include <android/log.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"
-#include "unicode/uloc.h"
 
 bool maybeThrowIcuException(JNIEnv* env, const char* function, UErrorCode error) {
   if (U_SUCCESS(error)) {
diff --git a/luni/src/main/native/JniConstants.cpp b/luni/src/main/native/JniConstants.cpp
old mode 100644
new mode 100755
index 478d015..5127fa1
--- a/luni/src/main/native/JniConstants.cpp
+++ b/luni/src/main/native/JniConstants.cpp
@@ -45,6 +45,7 @@
 
 // Constants
 jclass booleanClass;
+jclass byteBufferClass;
 jclass doubleClass;
 jclass errnoExceptionClass;
 jclass fileDescriptorClass;
@@ -60,11 +61,15 @@
 jclass longClass;
 jclass netlinkSocketAddressClass;
 jclass packetSocketAddressClass;
+jclass vmSocketAddressClass;
+jclass primitiveByteArrayClass;
 jclass stringClass;
 jclass structAddrinfoClass;
+jclass structCmsghdrClass;
 jclass structGroupReqClass;
 jclass structIfaddrsClass;
 jclass structLingerClass;
+jclass structMsghdrClass;
 jclass structPasswdClass;
 jclass structPollfdClass;
 jclass structStatClass;
@@ -90,6 +95,7 @@
     }
 
     booleanClass = findClass(env, "java/lang/Boolean");
+    byteBufferClass = findClass(env, "java/nio/ByteBuffer");
     doubleClass = findClass(env, "java/lang/Double");
     errnoExceptionClass = findClass(env, "android/system/ErrnoException");
     fileDescriptorClass = findClass(env, "java/io/FileDescriptor");
@@ -105,11 +111,15 @@
     longClass = findClass(env, "java/lang/Long");
     netlinkSocketAddressClass = findClass(env, "android/system/NetlinkSocketAddress");
     packetSocketAddressClass = findClass(env, "android/system/PacketSocketAddress");
+    vmSocketAddressClass = findClass(env, "android/system/VmSocketAddress");
+    primitiveByteArrayClass = findClass(env, "[B");
     stringClass = findClass(env, "java/lang/String");
     structAddrinfoClass = findClass(env, "android/system/StructAddrinfo");
+    structCmsghdrClass = findClass(env, "android/system/StructCmsghdr");
     structGroupReqClass = findClass(env, "android/system/StructGroupReq");
     structIfaddrsClass = findClass(env, "android/system/StructIfaddrs");
     structLingerClass = findClass(env, "android/system/StructLinger");
+    structMsghdrClass = findClass(env, "android/system/StructMsghdr");
     structPasswdClass = findClass(env, "android/system/StructPasswd");
     structPollfdClass = findClass(env, "android/system/StructPollfd");
     structStatClass = findClass(env, "android/system/StructStat");
@@ -148,6 +158,11 @@
     return booleanClass;
 }
 
+jclass JniConstants::GetByteBufferClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return byteBufferClass;
+}
+
 jclass JniConstants::GetDoubleClass(JNIEnv* env) {
     EnsureJniConstantsInitialized(env);
     return doubleClass;
@@ -223,6 +238,16 @@
     return packetSocketAddressClass;
 }
 
+jclass JniConstants::GetVmSocketAddressClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return vmSocketAddressClass;
+}
+
+jclass JniConstants::GetPrimitiveByteArrayClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return primitiveByteArrayClass;
+}
+
 jclass JniConstants::GetStringClass(JNIEnv* env) {
     EnsureJniConstantsInitialized(env);
     return stringClass;
@@ -233,6 +258,11 @@
     return structAddrinfoClass;
 }
 
+jclass JniConstants::GetStructCmsghdrClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structCmsghdrClass;
+}
+
 jclass JniConstants::GetStructGroupReqClass(JNIEnv* env) {
     EnsureJniConstantsInitialized(env);
     return structGroupReqClass;
@@ -248,6 +278,11 @@
     return structLingerClass;
 }
 
+jclass JniConstants::GetStructMsghdrClass(JNIEnv* env) {
+    EnsureJniConstantsInitialized(env);
+    return structMsghdrClass;
+}
+
 jclass JniConstants::GetStructPasswdClass(JNIEnv* env) {
     EnsureJniConstantsInitialized(env);
     return structPasswdClass;
diff --git a/luni/src/main/native/JniConstants.h b/luni/src/main/native/JniConstants.h
old mode 100644
new mode 100755
index 868e928..bf824b8
--- a/luni/src/main/native/JniConstants.h
+++ b/luni/src/main/native/JniConstants.h
@@ -30,6 +30,7 @@
     static void Invalidate();
 
     static jclass GetBooleanClass(JNIEnv* env);
+    static jclass GetByteBufferClass(JNIEnv* env);
     static jclass GetDoubleClass(JNIEnv* env);
     static jclass GetErrnoExceptionClass(JNIEnv* env);
     static jclass GetFileDescriptorClass(JNIEnv* env);
@@ -45,12 +46,16 @@
     static jclass GetLongClass(JNIEnv* env);
     static jclass GetNetlinkSocketAddressClass(JNIEnv* env);
     static jclass GetPacketSocketAddressClass(JNIEnv* env);
+    static jclass GetVmSocketAddressClass(JNIEnv* env);
+    static jclass GetPrimitiveByteArrayClass(JNIEnv* env);
     static jclass GetStringClass(JNIEnv* env);
     static jclass GetStructAddrinfoClass(JNIEnv* env);
+    static jclass GetStructCmsghdrClass(JNIEnv* env);
     static jclass GetStructFlockClass(JNIEnv* env);
     static jclass GetStructGroupReqClass(JNIEnv* env);
     static jclass GetStructIfaddrsClass(JNIEnv* env);
     static jclass GetStructLingerClass(JNIEnv* env);
+    static jclass GetStructMsghdrClass(JNIEnv* env);
     static jclass GetStructPasswdClass(JNIEnv* env);
     static jclass GetStructPollfdClass(JNIEnv* env);
     static jclass GetStructStatClass(JNIEnv* env);
diff --git a/luni/src/main/native/JniException.cpp b/luni/src/main/native/JniException.cpp
index 164281d..01346ef 100644
--- a/luni/src/main/native/JniException.cpp
+++ b/luni/src/main/native/JniException.cpp
@@ -19,15 +19,6 @@
 #include "JniException.h"
 #include <nativehelper/JNIHelp.h>
 
-void jniThrowExceptionWithErrno(JNIEnv* env, const char* exceptionClassName, int error) {
-    char buf[BUFSIZ];
-    jniThrowException(env, exceptionClassName, jniStrError(error, buf, sizeof(buf)));
-}
-
 void jniThrowOutOfMemoryError(JNIEnv* env, const char* message) {
     jniThrowException(env, "java/lang/OutOfMemoryError", message);
 }
-
-void jniThrowSocketException(JNIEnv* env, int error) {
-    jniThrowExceptionWithErrno(env, "java/net/SocketException", error);
-}
diff --git a/luni/src/main/native/JniException.h b/luni/src/main/native/JniException.h
index 2d4a097..cff68b8 100644
--- a/luni/src/main/native/JniException.h
+++ b/luni/src/main/native/JniException.h
@@ -19,9 +19,6 @@
 
 #include "jni.h"
 
-void jniThrowExceptionWithErrno(JNIEnv* env, const char* exceptionClassName, int error);
-
 void jniThrowOutOfMemoryError(JNIEnv* env, const char* message);
-void jniThrowSocketException(JNIEnv* env, int error);
 
 #endif  // JNI_EXCEPTION_H_included
diff --git a/luni/src/main/native/NetworkUtilities.cpp b/luni/src/main/native/NetworkUtilities.cpp
old mode 100644
new mode 100755
index b765c4e..cd695b7
--- a/luni/src/main/native/NetworkUtilities.cpp
+++ b/luni/src/main/native/NetworkUtilities.cpp
@@ -21,6 +21,7 @@
 #include <arpa/inet.h>
 #include <fcntl.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <sys/socket.h>
 #include <sys/un.h>
@@ -30,6 +31,9 @@
 
 #include "JniConstants.h"
 
+#include <log/log.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".
@@ -199,6 +203,325 @@
     return inetAddressToSockaddr(env, inetAddress, port, ss, sa_len, true);
 }
 
+/*
+ * Fill msg_contrl data from structCmsghdr[]
+ */
+bool structCmsghdrArrayToMsgcontrol(JNIEnv* env, jobjectArray cmsgArray, struct msghdr& mhdr) {
+    struct cmsghdr *cm = NULL;
+    int i = 0;
+    jclass structCmsghdrClass = JniConstants::GetStructCmsghdrClass(env);
+    static jfieldID cmsgDataFid = env->GetFieldID(structCmsghdrClass, "cmsg_data", "[B");
+    if (!cmsgDataFid) {
+        return false;
+    }
+    static jfieldID cmsgLevelFid = env->GetFieldID(structCmsghdrClass, "cmsg_level", "I");
+    if (!cmsgLevelFid) {
+        return false;
+    }
+    static jfieldID cmsgTypeFid = env->GetFieldID(structCmsghdrClass, "cmsg_type", "I");
+    if (!cmsgTypeFid) {
+        return false;
+    }
+
+    int cmsgArrayize = env->GetArrayLength(cmsgArray);
+    if (!cmsgArrayize) {
+        // Return true since msg_control is optional parameter.
+        return true;
+    }
+
+    for (int i = 0; i < cmsgArrayize; ++i) {
+        ScopedLocalRef<jobject> cmsg(env, env->GetObjectArrayElement(cmsgArray, i));
+        ScopedLocalRef<jbyteArray> cmsgData(env, reinterpret_cast<jbyteArray>(
+                env->GetObjectField(cmsg.get(), cmsgDataFid)));
+
+        mhdr.msg_controllen += CMSG_SPACE(env->GetArrayLength(cmsgData.get()));
+    }
+
+    mhdr.msg_control = (unsigned char*)malloc(mhdr.msg_controllen);
+    if (mhdr.msg_control == NULL) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory");
+        return false;
+    }
+    memset(mhdr.msg_control, 0, mhdr.msg_controllen);
+
+    // Loop over each cmsghdr header and set data.
+    for (cm = CMSG_FIRSTHDR(&mhdr), i = 0; (cm != NULL); cm = CMSG_NXTHDR(&mhdr, cm), ++i)
+    {
+        size_t data_len = 0;
+        ScopedLocalRef<jobject> cmsg(env, env->GetObjectArrayElement(cmsgArray, i));
+        ScopedLocalRef<jbyteArray> cmsgData(env, reinterpret_cast<jbyteArray>(
+                env->GetObjectField(cmsg.get(), cmsgDataFid)));
+
+        cm->cmsg_level = env->GetIntField(cmsg.get(), cmsgLevelFid);
+        cm->cmsg_type  = env->GetIntField(cmsg.get(), cmsgTypeFid);
+        data_len = env->GetArrayLength(cmsgData.get());
+        cm->cmsg_len   = CMSG_LEN(data_len);
+        env->GetByteArrayRegion(cmsgData.get(), 0,
+                data_len, reinterpret_cast<jbyte*>CMSG_DATA(cm));
+    }
+    return true;
+}
+
+/*
+ * Fill structCmsghdr[] data per msgcontrol data, used when recvmsg
+ */
+bool msgcontrolToStructCmsghdrArray(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr) {
+    struct cmsghdr *cm = NULL;
+    int i = 0;
+
+    static jfieldID msgControlFid = env->GetFieldID(JniConstants::GetStructMsghdrClass(env),
+                                                 "msg_control", "[Landroid/system/StructCmsghdr;");
+    if (!msgControlFid) {
+        return false;
+    }
+
+    static jmethodID cmsgInitMid = env->GetMethodID(JniConstants::GetStructCmsghdrClass(env),
+                                                    "<init>", "(II[B)V");
+    if (!cmsgInitMid) {
+        return false;
+    }
+
+    int cmsghdrNumber = 0;
+    for (cm = CMSG_FIRSTHDR(&mhdr); (cm != NULL); cm = CMSG_NXTHDR(&mhdr, cm)) {
+        cmsghdrNumber++;
+    }
+    if (!cmsghdrNumber)
+        return true;
+
+    jobjectArray structCmsghdrArray = env->NewObjectArray(cmsghdrNumber,
+                                          JniConstants::GetStructCmsghdrClass(env), NULL);
+    if (!structCmsghdrArray) {
+        return false;
+    }
+
+    // Loop over each cmsghdr header and set data.
+    for (cm = CMSG_FIRSTHDR(&mhdr),i=0; (cm!=NULL); cm = CMSG_NXTHDR(&mhdr, cm),i++) {
+        // copy out cmsg_data
+        ScopedLocalRef<jbyteArray> msgData(env,
+            env->NewByteArray(cm->cmsg_len - sizeof(struct cmsghdr)));
+        env->SetByteArrayRegion(msgData.get(),
+                                0,
+                                env->GetArrayLength(msgData.get()),
+                                reinterpret_cast<jbyte*>CMSG_DATA(cm));
+
+        ScopedLocalRef<jobject> objItem(env, env->NewObject(
+                JniConstants::GetStructCmsghdrClass(env),
+                cmsgInitMid, cm->cmsg_level, cm->cmsg_type, msgData.get()));
+
+        env->SetObjectArrayElement(structCmsghdrArray, i, objItem.get());
+    }
+
+    env->SetObjectField(structMsghdr, msgControlFid, structCmsghdrArray);
+
+    return true;
+}
+
+/*
+ * generate ScopedBytes object per ByteBuffer.isDirect
+ * if ByteBuffer.isDirect, generate ScopedBytes object by ByteBuffer itself;
+ * else,  generate ScopedBytes object by ByteBuffer.array;
+ *
+ * Input:  ByteBuffer object, isRW(R only or RW)
+ * Output: byte_len, length of the byte data per ByteBuffer.remaining;
+ * return value: pointer of new ScopedBytesRW or ScopedBytesRO
+ */
+static void* getScopedBytesFromByteBuffer(JNIEnv* env,
+                                          jobject byteBuffer, int& byteLen, bool isRW) {
+
+    jclass byteBufferClass = JniConstants::GetByteBufferClass(env);
+    static jmethodID isDirectMid = env->GetMethodID(byteBufferClass, "isDirect", "()Z");
+    static jmethodID remainingMid = env->GetMethodID(byteBufferClass, "remaining", "()I");
+    static jmethodID arrayMid = env->GetMethodID(byteBufferClass, "array", "()[B");
+
+    if (!isDirectMid || !remainingMid || !arrayMid) {
+        return NULL;
+    }
+
+    byteLen = env->CallIntMethod(byteBuffer, remainingMid);
+    bool isDirect = env->CallBooleanMethod(byteBuffer, isDirectMid);
+    jobject objBuff;
+    if (isDirect == true) {
+        objBuff = env->NewLocalRef(byteBuffer); // Add LocalRef to align with CallObjectMethod
+    } else {
+        // return array
+        objBuff = env->CallObjectMethod(byteBuffer, arrayMid);
+    }
+
+    if (isRW) {
+        return (void*)(new ScopedBytesRW(env, objBuff));
+    } else {
+        return (void*)(new ScopedBytesRO(env, objBuff));
+    }
+
+}
+
+/*
+ *  Convert ByteBuffer[] to mhdr.msg_iov/msg_iovlen
+ */
+bool byteBufferArrayToIOV(JNIEnv* env, jobjectArray msgiovArray, struct msghdr& mhdr,
+                         ScopedByteBufferArray& scopeBufArray) {
+    int msgIovArraySize = env->GetArrayLength(msgiovArray);
+    if (!msgIovArraySize) {
+        /* would not happen since msg_iov is marked as NonNull */
+        mhdr.msg_iov = NULL;
+        mhdr.msg_iovlen = 0;
+    }
+
+    struct iovec* iovarr = (struct iovec*)malloc(sizeof(iovec)*msgIovArraySize);
+    if (!iovarr) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory");
+        return false;
+    }
+
+    if (scopeBufArray.initArray(msgIovArraySize) == false) {
+        jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory");
+        return false;
+    }
+
+    // Set memory of each msg_iov item by the original bytes address.
+    for (int i=0; i<msgIovArraySize; i++)
+    {
+        jobject msgiovItem = env->GetObjectArrayElement(msgiovArray, i);
+        int byteLen = 0;
+        void* ptr = getScopedBytesFromByteBuffer(env, msgiovItem, byteLen, scopeBufArray.isRW());
+        if (!ptr) {
+            jniThrowException(env, "java/lang/OutOfMemoryError", "Out of memory");
+            return false;
+        }
+
+        scopeBufArray.setArrayItem(i, ptr);
+
+        if (scopeBufArray.isRW()) {
+            iovarr[i].iov_base = (unsigned char*)(((ScopedBytesRW*)ptr)->get());
+        }
+        else {
+            iovarr[i].iov_base = (unsigned char*)(((ScopedBytesRO*)ptr)->get());
+        }
+
+        iovarr[i].iov_len  = byteLen;
+    }
+
+    mhdr.msg_iov = iovarr;
+    mhdr.msg_iovlen = msgIovArraySize;
+
+    return true;
+}
+
+/*
+ * Function: convertStructMsghdrAndmsghdr
+ * Description: convert between Java#StructMsghdr and C#msghdr for sendmsg/recvmsg
+ *
+ * Function Parameters:
+ *   StructMsghdr, input, StructMsghdr
+ *                 for sendmsg,
+ *                   StructMsghdr.msg_name       input(mandatory),
+ *                   StructMsghdr.msg_iov        iput(mandatory)
+ *                   StructMsghdr.msg_control    input(optional)
+ *                   StructMsghdr.msg_flags      input(mandatory)
+ *                 for recvmsg,
+ *                   StructMsghdr.msg_name       input/output(optional),
+ *                   StructMsghdr.msg_iov        input/output(mandatory)
+ *                   StructMsghdr.msg_control    input/output(optional)
+ *                   StructMsghdr.msg_flags      input
+ *   mhdr, input, struct msghdr
+ *   scopeBufArray, output, store buffer array of ScopedBytesRW or ScopedBytesRO
+ *   isFromStructCMsghdrTomsghdr, input,  indicate StructMsghdr->msghdr or msghdr->StructMsghdr
+ *
+ * then in sendmsg scenario, call sequence will be:
+ *             1. convert(StructMsg->msghdr)
+ *             2. sendmsg
+ *      in recvmsg scenario, call sequence will be:
+ *             1. convert(StructMsg->msghdr)
+ *             2. recvmsg
+ *             3. convert again(msghdr->StructMsg)
+ */
+bool convertStructMsghdrAndmsghdr(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr,
+                                  ScopedByteBufferArray& scopeBufArray,
+                                  bool isFromStructCMsghdrTomsghdr) {
+    if (!structMsghdr) {
+        jniThrowNullPointerException(env, "missing structMsghdr");
+        return false;
+    }
+
+    jclass StructMsghdrClass = JniConstants::GetStructMsghdrClass(env);
+
+    // Get fieldID of each item in StructMsghdr.
+    static jfieldID msgIovFid = env->GetFieldID(StructMsghdrClass,
+                                                 "msg_iov",
+                                                 "[Ljava/nio/ByteBuffer;");
+    if (!msgIovFid) {
+        return false;
+    }
+    static jfieldID msgControlFid = env->GetFieldID(StructMsghdrClass,
+                                                    "msg_control",
+                                                    "[Landroid/system/StructCmsghdr;");
+    if (!msgControlFid) {
+        return false;
+    }
+    static jfieldID msgFlagsFid = env->GetFieldID(StructMsghdrClass,
+                                                  "msg_flags",
+                                                  "I");
+    if (!msgFlagsFid) {
+        return false;
+    }
+
+    if (isFromStructCMsghdrTomsghdr) {
+        // Pick StructMsghdr.msg_iov[].
+        jobjectArray msgIovArray = reinterpret_cast<jobjectArray>(
+                                        env->GetObjectField(structMsghdr, msgIovFid));
+        if (!msgIovArray) {
+            jniThrowNullPointerException(env, "null StructMsghdr.msg_iov");
+            return false;
+        }
+        // In case sendmsg, IOV buffer are RO to send data,
+        // in case recvmsg, IOV buffer are RW to store received data.
+        if (byteBufferArrayToIOV(env, msgIovArray, mhdr, scopeBufArray) == false) {
+            return false;
+        }
+
+        if (!scopeBufArray.isRW()) {
+            jobjectArray structCmsghdrObjArray = reinterpret_cast<jobjectArray>(
+                                               env->GetObjectField(structMsghdr, msgControlFid));
+            if (structCmsghdrObjArray != NULL) {
+                // convert StrucCmsg[] <-> msghdr.msgcontrl
+                if (structCmsghdrArrayToMsgcontrol(env, structCmsghdrObjArray, mhdr) == false) {
+                    return false;
+                }
+            }
+        } else {
+            // hardcode 512 for recvmsg/msg_controllen, it should be enough for recvmsg
+            mhdr.msg_controllen = 512;
+            mhdr.msg_control = (unsigned char*)malloc(mhdr.msg_controllen);
+        }
+
+        mhdr.msg_flags = env->GetIntField(structMsghdr, msgFlagsFid);
+    } else {
+        // StructMsghdr.msg_iov[]/msg_control[] are output paramenter.
+        // StructMsghdr.msg_iov[] data are already updated by recvmsg syscall directly.
+        // StructMsghdr.msg_control[] are set below.
+        if (msgcontrolToStructCmsghdrArray(env, structMsghdr, mhdr) == false)
+            return false;
+        env->SetIntField(structMsghdr, msgFlagsFid, mhdr.msg_flags);
+    }
+
+    return true;
+
+}
+
+// Convert Java StructMsghdr to C msghdr.
+bool msghdrJavaToC(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr,
+                          ScopedByteBufferArray& scopedBufArray) {
+    return convertStructMsghdrAndmsghdr(env, structMsghdr, mhdr,
+                                             scopedBufArray, true);
+}
+
+// Convert C msghdr to Java StructMsghdr.
+bool msghdrCToJava(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr,
+                          ScopedByteBufferArray& scopedBufArray) {
+    return convertStructMsghdrAndmsghdr(env, structMsghdr, mhdr,
+                                             scopedBufArray, false);
+}
+
 bool setBlocking(int fd, bool blocking) {
     int flags = fcntl(fd, F_GETFL);
     if (flags == -1) {
diff --git a/luni/src/main/native/NetworkUtilities.h b/luni/src/main/native/NetworkUtilities.h
old mode 100644
new mode 100755
index db1ad1f..da35036
--- a/luni/src/main/native/NetworkUtilities.h
+++ b/luni/src/main/native/NetworkUtilities.h
@@ -16,6 +16,7 @@
 
 #include "jni.h"
 #include <sys/socket.h>
+#include "ScopedByteBufferArray.h"
 
 // Convert from sockaddr_storage to Inet4Address (AF_INET) or Inet6Address (AF_INET6).
 // If 'port' is non-NULL and the address family includes a notion
@@ -38,7 +39,15 @@
 bool inetAddressToSockaddrVerbatim(JNIEnv* env, jobject inetAddress, int port,
                                    sockaddr_storage& ss, socklen_t& sa_len);
 
+// Convert from StructMsghdr to msghdr,
+// set all fields except msg_name which would be set outside since IPv4 fallback handled outside
+bool msghdrJavaToC(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr,
+                   ScopedByteBufferArray& scopedBufArray);
 
+// Convert from msghdr to StructMsghdr,
+// msg_iov/msg_control need to be set since they are output parameters;
+bool msghdrCToJava(JNIEnv* env, jobject structMsghdr, struct msghdr& mhdr,
+                   ScopedByteBufferArray& scopedBufArray);
 
 // Changes 'fd' to be blocking/non-blocking. Returns false and sets errno on failure.
 // @Deprecated - use IoUtils.setBlocking
diff --git a/luni/src/main/native/Portability.h b/luni/src/main/native/Portability.h
index 4df3353..887a47b 100644
--- a/luni/src/main/native/Portability.h
+++ b/luni/src/main/native/Portability.h
@@ -31,6 +31,17 @@
 }
 #endif
 
+#if __has_include(<linux/vm_sockets.h>)
+#include <linux/vm_sockets.h>
+#else  // __has_include(<linux/vm_sockets.h>)
+// the platform does not support virtio-vsock
+#define AF_VSOCK (-1)
+#define VMADDR_PORT_ANY (-1)
+#define VMADDR_CID_ANY (-1)
+#define VMADDR_CID_LOCAL (-1)
+#define VMADDR_CID_HOST (-1)
+#endif  // __has_include(<linux/vm_sockets.h>)
+
 #if defined(__GLIBC__) && !defined(__LP64__)
 
 #include <unistd.h>
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 17ca839..91cabf7 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -19,7 +19,7 @@
 #include <stdlib.h>
 
 #include <log/log.h>
-#include <nativehelper/JNIHelp.h>
+#include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/ScopedLocalFrame.h>
 
 #include "JniConstants.h"
@@ -39,14 +39,12 @@
     //    REGISTER(register_java_lang_StringToReal);
     REGISTER(register_java_lang_invoke_MethodHandle);
     REGISTER(register_java_lang_invoke_VarHandle);
-    REGISTER(register_java_math_NativeBN);
     REGISTER(register_libcore_icu_ICU);
-    REGISTER(register_libcore_icu_TimeZoneNames);
     REGISTER(register_libcore_io_AsynchronousCloseMonitor);
     REGISTER(register_libcore_io_Linux);
     REGISTER(register_libcore_io_Memory);
+    REGISTER(register_libcore_math_NativeBN);
     REGISTER(register_libcore_util_NativeAllocationRegistry);
-    REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
     REGISTER(register_org_apache_harmony_xml_ExpatParser);
     REGISTER(register_sun_misc_Unsafe);
 #undef REGISTER
diff --git a/luni/src/main/native/ScopedByteBufferArray.h b/luni/src/main/native/ScopedByteBufferArray.h
new file mode 100755
index 0000000..d5dd6ba
--- /dev/null
+++ b/luni/src/main/native/ScopedByteBufferArray.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <nativehelper/ScopedLocalRef.h>
+#include "ScopedBytes.h"
+
+/**
+ * ScopedByteBufferArray manages the dynamic buffer array of ScopedBytesRW/ScopedBytesRO.
+ */
+class ScopedByteBufferArray {
+public:
+    ScopedByteBufferArray(JNIEnv* env, int isRW)
+    : mEnv(env), mIsRW(isRW)
+    {
+        mArrayPtr = NULL;
+        mArraySize = 0;
+    }
+
+    ~ScopedByteBufferArray() {
+        if(!mArrayPtr) {
+            return;
+        }
+
+        // Loop over arrary and release memory.
+        for (int i = 0; i < mArraySize; ++i) {
+            if (!mArrayPtr[i])
+                continue;
+
+            if (mIsRW) {
+                jobject tmp = ((ScopedBytesRW*)mArrayPtr[i])->getObject();
+                delete (ScopedBytesRW*)mArrayPtr[i];
+                mEnv->DeleteLocalRef(tmp);
+            } else {
+                jobject tmp = ((ScopedBytesRO*)mArrayPtr[i])->getObject();
+                delete (ScopedBytesRO*)mArrayPtr[i];
+                mEnv->DeleteLocalRef(tmp);
+            }
+        }
+        delete[] mArrayPtr;
+    }
+
+    bool initArray(int size) {
+        if (mArrayPtr) {
+            return false;
+        }
+
+        mArraySize = size;
+
+        if (mIsRW) {
+            mArrayPtr = (void**)(new ScopedBytesRW*[size]);
+        }
+        else {
+            mArrayPtr = (void**)(new ScopedBytesRO*[size]);
+        }
+
+        if (!mArrayPtr) {
+            return false;
+        }
+
+        for (int i=0; i<size; ++i) {
+            mArrayPtr[i] = 0;
+        }
+
+        return true;
+    }
+
+    bool isRW() const {
+        return mIsRW;
+    }
+
+    bool setArrayItem(int itemNo, void* item) {
+        if (itemNo >= mArraySize || itemNo < 0) {
+            return false;
+        }
+        mArrayPtr[itemNo] = item;
+        return true;
+    }
+
+private:
+    JNIEnv* const mEnv;
+    int mIsRW;
+    int mArraySize;
+    void** mArrayPtr;
+};
diff --git a/luni/src/main/native/ScopedBytes.h b/luni/src/main/native/ScopedBytes.h
new file mode 100644
index 0000000..951ef4b
--- /dev/null
+++ b/luni/src/main/native/ScopedBytes.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <nativehelper/JNIHelp.h>
+
+#include "JniConstants.h"
+
+/**
+ * ScopedBytesRO and ScopedBytesRW attempt to paper over the differences between byte[]s and
+ * ByteBuffers. This in turn helps paper over the differences between non-direct ByteBuffers backed
+ * by byte[]s, direct ByteBuffers backed by bytes[]s, and direct ByteBuffers not backed by byte[]s.
+ * (On Android, this last group only contains MappedByteBuffers.)
+ */
+template<bool readOnly>
+class ScopedBytes {
+public:
+    ScopedBytes(JNIEnv* env, jobject object)
+    : mEnv(env), mObject(object), mByteArray(nullptr), mPtr(nullptr)
+    {
+        if (mObject == nullptr) {
+            jniThrowNullPointerException(mEnv);
+        } else {
+            jclass byteArrayClass = JniConstants::GetPrimitiveByteArrayClass(env);
+            if (mEnv->IsInstanceOf(mObject, byteArrayClass)) {
+                mByteArray = reinterpret_cast<jbyteArray>(mObject);
+                mPtr = mEnv->GetByteArrayElements(mByteArray, nullptr);
+            } else {
+                mPtr = reinterpret_cast<jbyte*>(mEnv->GetDirectBufferAddress(mObject));
+            }
+        }
+    }
+
+    ~ScopedBytes() {
+        if (mByteArray != nullptr) {
+            mEnv->ReleaseByteArrayElements(mByteArray, mPtr, readOnly ? JNI_ABORT : 0);
+        }
+    }
+
+    jobject getObject() {
+        return mObject;
+    }
+
+private:
+    JNIEnv* const mEnv;
+    const jobject mObject;
+    jbyteArray mByteArray;
+
+protected:
+    jbyte* mPtr;
+
+private:
+    DISALLOW_COPY_AND_ASSIGN(ScopedBytes);
+};
+
+class ScopedBytesRO : public ScopedBytes<true> {
+public:
+    ScopedBytesRO(JNIEnv* env, jobject object) : ScopedBytes<true>(env, object) {}
+    const jbyte* get() const {
+        return mPtr;
+    }
+};
+
+class ScopedBytesRW : public ScopedBytes<false> {
+public:
+    ScopedBytesRW(JNIEnv* env, jobject object) : ScopedBytes<false>(env, object) {}
+    jbyte* get() {
+        return mPtr;
+    }
+};
+
diff --git a/luni/src/main/native/ScopedIcuLocale.h b/luni/src/main/native/ScopedIcuLocale.h
deleted file mode 100644
index 851de76..0000000
--- a/luni/src/main/native/ScopedIcuLocale.h
+++ /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.
- */
-
-#ifndef SCOPED_ICU_LOCALE_H_included
-#define SCOPED_ICU_LOCALE_H_included
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include "unicode/locid.h"
-
-class ScopedIcuLocale {
- public:
-  ScopedIcuLocale(JNIEnv* env, jstring javaLocaleName) : mEnv(env) {
-    mLocale.setToBogus();
-
-    if (javaLocaleName == NULL) {
-      jniThrowNullPointerException(mEnv, "javaLocaleName == null");
-      return;
-    }
-
-    const ScopedUtfChars localeName(env, javaLocaleName);
-    if (localeName.c_str() == NULL) {
-      return;
-    }
-
-    mLocale = icu::Locale::createFromName(localeName.c_str());
-  }
-
-  ~ScopedIcuLocale() {
-  }
-
-  bool valid() const {
-    return !mLocale.isBogus();
-  }
-
-  icu::Locale& locale() {
-    return mLocale;
-  }
-
- private:
-  JNIEnv* const mEnv;
-  icu::Locale mLocale;
-
-  // Disallow copy and assignment.
-  ScopedIcuLocale(const ScopedIcuLocale&);
-  void operator=(const ScopedIcuLocale&);
-};
-
-#endif  // SCOPED_ICU_LOCALE_H_included
diff --git a/luni/src/main/native/ScopedIcuULoc.h b/luni/src/main/native/ScopedIcuULoc.h
index 5de5e36..5f7ca0a 100644
--- a/luni/src/main/native/ScopedIcuULoc.h
+++ b/luni/src/main/native/ScopedIcuULoc.h
@@ -19,7 +19,7 @@
 #include <nativehelper/JNIHelp.h>
 #include <nativehelper/ScopedUtfChars.h>
 
-#include "unicode/uloc.h"
+#include <unicode/uloc.h>
 
 
 static void getLocale(const char* localeName, std::string& locale, UErrorCode* status) {
diff --git a/luni/src/main/native/ScopedJavaUnicodeString.h b/luni/src/main/native/ScopedJavaUnicodeString.h
deleted file mode 100644
index a30aa7e..0000000
--- a/luni/src/main/native/ScopedJavaUnicodeString.h
+++ /dev/null
@@ -1,67 +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 SCOPED_JAVA_UNICODE_STRING_H_included
-#define SCOPED_JAVA_UNICODE_STRING_H_included
-
-#include <nativehelper/JNIHelp.h>
-#include "unicode/unistr.h"
-
-// A smart pointer that provides access to an ICU UnicodeString given a JNI
-// jstring. We give ICU a direct pointer to the characters on the Java heap.
-// It's clever enough to copy-on-write if necessary.
-class ScopedJavaUnicodeString {
- public:
-  ScopedJavaUnicodeString(JNIEnv* env, jstring s) : mEnv(env), mString(s) {
-    if (s == NULL) {
-      jniThrowNullPointerException(mEnv, NULL);
-    } else {
-      mChars = env->GetStringChars(mString, NULL);
-      const int32_t charCount = env->GetStringLength(mString);
-      mUnicodeString.setTo(false, mChars, charCount);
-    }
-  }
-
-  ~ScopedJavaUnicodeString() {
-    if (mString != NULL) {
-      mEnv->ReleaseStringChars(mString, mChars);
-    }
-  }
-
-  bool valid() const {
-    return (mString != NULL);
-  }
-
-  const icu::UnicodeString& unicodeString() const {
-    return mUnicodeString;
-  }
-
-  icu::UnicodeString& unicodeString() {
-    return mUnicodeString;
-  }
-
- private:
-  JNIEnv* mEnv;
-  jstring mString;
-  const jchar* mChars;
-  icu::UnicodeString mUnicodeString;
-
-  // Disallow copy and assignment.
-  ScopedJavaUnicodeString(const ScopedJavaUnicodeString&);
-  void operator=(const ScopedJavaUnicodeString&);
-};
-
-#endif  // SCOPED_JAVA_UNICODE_STRING_H_included
diff --git a/luni/src/main/native/ScopedMsghdr.h b/luni/src/main/native/ScopedMsghdr.h
new file mode 100755
index 0000000..1361390
--- /dev/null
+++ b/luni/src/main/native/ScopedMsghdr.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <nativehelper/JNIHelp.h>
+
+#include "JniConstants.h"
+#include "ScopedBytes.h"
+
+/**
+ * Wrapper for managing the name and length of msghdr.
+ */
+class ScopedMsghdr {
+public:
+    ScopedMsghdr() {
+    }
+
+    ~ScopedMsghdr() {
+        if (mMsghdrValue.msg_iov)
+            free(mMsghdrValue.msg_iov);
+        if (mMsghdrValue.msg_control)
+            free(mMsghdrValue.msg_control);
+    }
+
+    struct msghdr& getObject() {
+        return mMsghdrValue;
+    }
+
+    void setMsgNameAndLen(sockaddr* ss, socklen_t sa_len) {
+        mMsghdrValue.msg_name = ss;
+        mMsghdrValue.msg_namelen = sa_len;
+    }
+
+    bool isNameLenValid() const {
+        if(mMsghdrValue.msg_name == NULL) {
+            return false;
+        }
+        if ((mMsghdrValue.msg_namelen != sizeof(sockaddr_in6)) &&
+            (mMsghdrValue.msg_namelen != sizeof(sockaddr_in))) {
+            return false;
+        }
+        return true;
+    }
+
+private:
+    struct msghdr mMsghdrValue = {};
+
+};
+
+
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 6cf2c8b..50e3c10 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -69,6 +69,7 @@
     initConstant(env, c, "AF_PACKET", AF_PACKET);
     initConstant(env, c, "AF_NETLINK", AF_NETLINK);
     initConstant(env, c, "AF_UNIX", AF_UNIX);
+    initConstant(env, c, "AF_VSOCK", AF_VSOCK);
     initConstant(env, c, "AF_UNSPEC", AF_UNSPEC);
     initConstant(env, c, "AI_ADDRCONFIG", AI_ADDRCONFIG);
     initConstant(env, c, "AI_ALL", AI_ALL);
@@ -80,6 +81,10 @@
     initConstant(env, c, "AI_PASSIVE", AI_PASSIVE);
     initConstant(env, c, "AI_V4MAPPED", AI_V4MAPPED);
     initConstant(env, c, "ARPHRD_ETHER", ARPHRD_ETHER);
+    initConstant(env, c, "VMADDR_PORT_ANY", VMADDR_PORT_ANY);
+    initConstant(env, c, "VMADDR_CID_ANY", VMADDR_CID_ANY);
+    initConstant(env, c, "VMADDR_CID_LOCAL", VMADDR_CID_LOCAL);
+    initConstant(env, c, "VMADDR_CID_HOST", VMADDR_CID_HOST);
     initConstant(env, c, "ARPHRD_LOOPBACK", ARPHRD_LOOPBACK);
 #if defined(CAP_LAST_CAP)
     initConstant(env, c, "CAP_AUDIT_CONTROL", CAP_AUDIT_CONTROL);
@@ -522,6 +527,9 @@
     initConstant(env, c, "SOCK_SEQPACKET", SOCK_SEQPACKET);
     initConstant(env, c, "SOCK_STREAM", SOCK_STREAM);
     initConstant(env, c, "SOL_SOCKET", SOL_SOCKET);
+#if defined(SOL_UDP)
+    initConstant(env, c, "SOL_UDP", SOL_UDP);
+#endif
 #if defined(SO_BINDTODEVICE)
     initConstant(env, c, "SO_BINDTODEVICE", SO_BINDTODEVICE);
 #endif
@@ -598,6 +606,12 @@
     initConstant(env, c, "UDP_ENCAP", UDP_ENCAP);
     initConstant(env, c, "UDP_ENCAP_ESPINUDP_NON_IKE", UDP_ENCAP_ESPINUDP_NON_IKE);
     initConstant(env, c, "UDP_ENCAP_ESPINUDP", UDP_ENCAP_ESPINUDP);
+#if defined(UDP_GRO)
+    initConstant(env, c, "UDP_GRO", UDP_GRO);
+#endif
+#if defined(UDP_SEGMENT)
+    initConstant(env, c, "UDP_SEGMENT", UDP_SEGMENT);
+#endif
     // UNIX_PATH_MAX is mentioned in some versions of unix(7), but not actually declared.
     initConstant(env, c, "UNIX_PATH_MAX", sizeof(sockaddr_un::sun_path));
     initConstant(env, c, "WCONTINUED", WCONTINUED);
diff --git a/luni/src/main/native/java_math_NativeBN.cpp b/luni/src/main/native/java_math_NativeBN.cpp
deleted file mode 100644
index 5d085ec..0000000
--- a/luni/src/main/native/java_math_NativeBN.cpp
+++ /dev/null
@@ -1,569 +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.
- */
-
-#define LOG_TAG "NativeBN"
-
-#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);
-  }
-};
-typedef std::unique_ptr<BN_CTX, BN_CTX_Deleter> Unique_BN_CTX;
-
-static BIGNUM* toBigNum(jlong address) {
-  return reinterpret_cast<BIGNUM*>(static_cast<uintptr_t>(address));
-}
-
-static void throwException(JNIEnv* env) {
-  long error = ERR_get_error();
-  // OpenSSL's error queue may contain multiple errors. Clean up after them.
-  ERR_clear_error();
-
-  if (error == 0) {
-    // An operation failed but did not push to the error queue. Throw a default
-    // exception.
-    jniThrowException(env, "java/lang/ArithmeticException", "Operation failed");
-    return;
-  }
-
-  char message[256];
-  ERR_error_string_n(error, message, sizeof(message));
-  int reason = ERR_GET_REASON(error);
-  if (reason == BN_R_DIV_BY_ZERO) {
-    jniThrowException(env, "java/lang/ArithmeticException", "BigInteger division by zero");
-  } else if (reason == BN_R_NO_INVERSE) {
-    jniThrowException(env, "java/lang/ArithmeticException", "BigInteger not invertible");
-  } else if (reason == ERR_R_MALLOC_FAILURE) {
-    jniThrowOutOfMemoryError(env, message);
-  } else {
-    jniThrowException(env, "java/lang/ArithmeticException", message);
-  }
-}
-
-static int isValidHandle(JNIEnv* env, jlong handle, const char* message) {
-  if (handle == 0) {
-    jniThrowNullPointerException(env, message);
-    return JNI_FALSE;
-  }
-  return JNI_TRUE;
-}
-
-static int oneValidHandle(JNIEnv* env, jlong a) {
-  return isValidHandle(env, a, "Mandatory handle (first) passed as null");
-}
-
-static int twoValidHandles(JNIEnv* env, jlong a, jlong b) {
-  if (!oneValidHandle(env, a)) return JNI_FALSE;
-  return isValidHandle(env, b, "Mandatory handle (second) passed as null");
-}
-
-static int threeValidHandles(JNIEnv* env, jlong a, jlong b, jlong c) {
-  if (!twoValidHandles(env, a, b)) return JNI_FALSE;
-  return isValidHandle(env, c, "Mandatory handle (third) passed as null");
-}
-
-static int fourValidHandles(JNIEnv* env, jlong a, jlong b, jlong c, jlong d) {
-  if (!threeValidHandles(env, a, b, c)) return JNI_FALSE;
-  return isValidHandle(env, d, "Mandatory handle (fourth) passed as null");
-}
-
-static jlong NativeBN_BN_new(JNIEnv* env, jclass) {
-  jlong result = static_cast<jlong>(reinterpret_cast<uintptr_t>(BN_new()));
-  if (!result) {
-    throwException(env);
-  }
-  return result;
-}
-
-static jlong NativeBN_getNativeFinalizer(JNIEnv*, jclass) {
-  return static_cast<jlong>(reinterpret_cast<uintptr_t>(&BN_free));
-}
-
-static void NativeBN_BN_free(JNIEnv* env, jclass, jlong a) {
-  if (!oneValidHandle(env, a)) return;
-  BN_free(toBigNum(a));
-}
-
-static int NativeBN_BN_cmp(JNIEnv* env, jclass, jlong a, jlong b) {
-  if (!twoValidHandles(env, a, b)) return 1;
-  return BN_cmp(toBigNum(a), toBigNum(b));
-}
-
-static void NativeBN_BN_copy(JNIEnv* env, jclass, jlong to, jlong from) {
-  if (!twoValidHandles(env, to, from)) return;
-  if (!BN_copy(toBigNum(to), toBigNum(from))) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_putULongInt(JNIEnv* env, jclass, jlong a0, jlong java_dw, jboolean neg) {
-  if (!oneValidHandle(env, a0)) return;
-
-  uint64_t dw = java_dw;
-  BIGNUM* a = toBigNum(a0);
-
-  if (!BN_set_u64(a, dw)) {
-    throwException(env);
-    return;
-  }
-
-  BN_set_negative(a, neg);
-}
-
-static void NativeBN_putLongInt(JNIEnv* env, jclass cls, jlong a, jlong dw) {
-  if (dw >= 0) {
-    NativeBN_putULongInt(env, cls, a, dw, JNI_FALSE);
-  } else {
-    NativeBN_putULongInt(env, cls, a, -dw, JNI_TRUE);
-  }
-}
-
-static int NativeBN_BN_dec2bn(JNIEnv* env, jclass, jlong a0, jstring str) {
-  if (!oneValidHandle(env, a0)) return -1;
-  ScopedUtfChars chars(env, str);
-  if (chars.c_str() == NULL) {
-    return -1;
-  }
-  BIGNUM* a = toBigNum(a0);
-  int result = BN_dec2bn(&a, chars.c_str());
-  if (result == 0) {
-    throwException(env);
-  }
-  return result;
-}
-
-static int NativeBN_BN_hex2bn(JNIEnv* env, jclass, jlong a0, jstring str) {
-  if (!oneValidHandle(env, a0)) return -1;
-  ScopedUtfChars chars(env, str);
-  if (chars.c_str() == NULL) {
-    return -1;
-  }
-  BIGNUM* a = toBigNum(a0);
-  int result = BN_hex2bn(&a, chars.c_str());
-  if (result == 0) {
-    throwException(env);
-  }
-  return result;
-}
-
-static void NativeBN_BN_bin2bn(JNIEnv* env, jclass, jbyteArray arr, int len, jboolean neg, jlong ret) {
-  if (!oneValidHandle(env, ret)) return;
-  ScopedByteArrayRO bytes(env, arr);
-  if (bytes.get() == NULL) {
-    return;
-  }
-  if (!BN_bin2bn(reinterpret_cast<const unsigned char*>(bytes.get()), len, toBigNum(ret))) {
-    throwException(env);
-    return;
-  }
-
-  BN_set_negative(toBigNum(ret), neg);
-}
-
-static void NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len, jboolean neg, jlong ret0) {
-  if (!oneValidHandle(env, ret0)) return;
-  BIGNUM* ret = toBigNum(ret0);
-
-  ScopedIntArrayRO scopedArray(env, arr);
-
-  if (scopedArray.get() == NULL) {
-    return;
-  }
-
-  // We can simply interpret the little-endian integer stream as a
-  // little-endian byte stream and use BN_le2bn.
-  const uint8_t* tmpBytes = reinterpret_cast<const uint8_t *>(scopedArray.get());
-  size_t numBytes = len * sizeof(int);
-
-  if (!BN_le2bn(tmpBytes, numBytes, ret)) {
-    throwException(env);
-  }
-
-  BN_set_negative(ret, neg);
-}
-
-static void NativeBN_twosComp2bn(JNIEnv* env, jclass, jbyteArray arr, int bytesLen, jlong ret0) {
-  if (!oneValidHandle(env, ret0)) return;
-  BIGNUM* ret = toBigNum(ret0);
-
-  ScopedByteArrayRO bytes(env, arr);
-  if (bytes.get() == NULL) {
-    return;
-  }
-
-  if (bytesLen == 0) {
-    BN_zero(ret);
-    return;
-  }
-
-  const unsigned char* bytesTmp = reinterpret_cast<const unsigned char*>(bytes.get());
-
-  if (!BN_bin2bn(bytesTmp, bytesLen, ret)) {
-    throwException(env);
-    return;
-  }
-
-  // Use the high bit to determine the sign in twos-complement.
-  BN_set_negative(ret, (bytes[0] & 0x80) != 0);
-
-  if (BN_is_negative(ret)) {
-    // For negative values, BN_bin2bn doesn't interpret the twos-complement
-    // representation, so ret is now (- value - 2^N). We can use nnmod_pow2 to set
-    // ret to (-value).
-    if (!BN_nnmod_pow2(ret, ret, bytesLen * 8)) {
-      throwException(env);
-      return;
-    }
-
-    // And now we correct the sign.
-    BN_set_negative(ret, 1);
-  }
-}
-
-static jlong NativeBN_longInt(JNIEnv* env, jclass, jlong a0) {
-  if (!oneValidHandle(env, a0)) return -1;
-  BIGNUM* a = toBigNum(a0);
-  uint64_t word;
-
-  if (BN_get_u64(a, &word)) {
-    return BN_is_negative(a) ? -((jlong) word) : word;
-  } else {
-    // This should be unreachable if our caller checks BigInt::twosCompFitsIntoBytes(8)
-    throwException(env);
-    return 0;
-  }
-}
-
-static char* leadingZerosTrimmed(char* s) {
-    char* p = s;
-    if (*p == '-') {
-        p++;
-        while ((*p == '0') && (*(p + 1) != 0)) { p++; }
-        p--;
-        *p = '-';
-    } else {
-        while ((*p == '0') && (*(p + 1) != 0)) { p++; }
-    }
-    return p;
-}
-
-static jstring NativeBN_BN_bn2dec(JNIEnv* env, jclass, jlong a) {
-  if (!oneValidHandle(env, a)) return NULL;
-  char* tmpStr = BN_bn2dec(toBigNum(a));
-  if (tmpStr == NULL) {
-    throwException(env);
-    return NULL;
-  }
-  char* retStr = leadingZerosTrimmed(tmpStr);
-  jstring returnJString = env->NewStringUTF(retStr);
-  OPENSSL_free(tmpStr);
-  return returnJString;
-}
-
-static jstring NativeBN_BN_bn2hex(JNIEnv* env, jclass, jlong a) {
-  if (!oneValidHandle(env, a)) return NULL;
-  char* tmpStr = BN_bn2hex(toBigNum(a));
-  if (tmpStr == NULL) {
-    throwException(env);
-    return NULL;
-  }
-  char* retStr = leadingZerosTrimmed(tmpStr);
-  jstring returnJString = env->NewStringUTF(retStr);
-  OPENSSL_free(tmpStr);
-  return returnJString;
-}
-
-static jbyteArray NativeBN_BN_bn2bin(JNIEnv* env, jclass, jlong a0) {
-  if (!oneValidHandle(env, a0)) return NULL;
-  BIGNUM* a = toBigNum(a0);
-  jbyteArray result = env->NewByteArray(BN_num_bytes(a));
-  if (result == NULL) {
-    return NULL;
-  }
-  ScopedByteArrayRW bytes(env, result);
-  if (bytes.get() == NULL) {
-    return NULL;
-  }
-  BN_bn2bin(a, reinterpret_cast<unsigned char*>(bytes.get()));
-  return result;
-}
-
-static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) {
-  if (!oneValidHandle(env, a0)) return NULL;
-
-  BIGNUM* a = toBigNum(a0);
-
-  // The number of integers we need is BN_num_bytes(a) / sizeof(int), rounded up
-  int intLen = (BN_num_bytes(a) + sizeof(int) - 1) / sizeof(int);
-
-  // Allocate our result with the JNI boilerplate
-  jintArray result = env->NewIntArray(intLen);
-
-  if (result == NULL) {
-    throwException(env);
-    return NULL;
-  }
-
-  ScopedIntArrayRW ints(env, result);
-
-  unsigned int* uints = reinterpret_cast<unsigned int*>(ints.get());
-  if (uints == NULL) {
-    throwException(env);
-    return NULL;
-  }
-
-  // We can simply interpret a little-endian byte stream as a little-endian integer stream.
-  if (!BN_bn2le_padded(reinterpret_cast<uint8_t*>(uints), intLen * sizeof(int), a)) {
-    throwException(env);
-    return NULL;
-  }
-
-  return result;
-}
-
-static int NativeBN_sign(JNIEnv* env, jclass, jlong a) {
-  if (!oneValidHandle(env, a)) return -2;
-  if (BN_is_zero(toBigNum(a))) {
-      return 0;
-  } else if (BN_is_negative(toBigNum(a))) {
-    return -1;
-  }
-  return 1;
-}
-
-static void NativeBN_BN_set_negative(JNIEnv* env, jclass, jlong b, int n) {
-  if (!oneValidHandle(env, b)) return;
-  BN_set_negative(toBigNum(b), n);
-}
-
-static int NativeBN_bitLength(JNIEnv* env, jclass, jlong a0) {
-  if (!oneValidHandle(env, a0)) return JNI_FALSE;
-  BIGNUM* a = toBigNum(a0);
-
-  // If a is not negative, we can use BN_num_bits directly.
-  if (!BN_is_negative(a)) {
-    return BN_num_bits(a);
-  }
-
-  // In the negative case, the number of bits in a is the same as the number of bits in |a|,
-  // except one less when |a| is a power of two.
-  BIGNUM positiveA;
-  BN_init(&positiveA);
-
-  if (!BN_copy(&positiveA, a)) {
-    BN_free(&positiveA);
-    throwException(env);
-    return -1;
-  }
-
-  BN_set_negative(&positiveA, false);
-  int numBits = BN_is_pow2(&positiveA) ? BN_num_bits(&positiveA) - 1 : BN_num_bits(&positiveA);
-
-  BN_free(&positiveA);
-  return numBits;
-}
-
-static jboolean NativeBN_BN_is_bit_set(JNIEnv* env, jclass, jlong a, int n) {
-  if (!oneValidHandle(env, a)) return JNI_FALSE;
-
-  // NOTE: this is only called in the positive case, so BN_is_bit_set is fine here.
-  return BN_is_bit_set(toBigNum(a), n) ? JNI_TRUE : JNI_FALSE;
-}
-
-static void NativeBN_BN_shift(JNIEnv* env, jclass, jlong r, jlong a, int n) {
-  if (!twoValidHandles(env, r, a)) return;
-  int ok;
-  if (n >= 0) {
-    ok = BN_lshift(toBigNum(r), toBigNum(a), n);
-  } else {
-    ok = BN_rshift(toBigNum(r), toBigNum(a), -n);
-  }
-  if (!ok) {
-    throwException(env);
-  }
-}
-
-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, jint w) {
-  if (!oneValidHandle(env, a)) return;
-  if (!BN_mul_word(toBigNum(a), w)) {
-    throwException(env);
-  }
-}
-
-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) {
-    throwException(env);
-  }
-  return result;
-}
-
-static void NativeBN_BN_add(JNIEnv* env, jclass, jlong r, jlong a, jlong b) {
-  if (!threeValidHandles(env, r, a, b)) return;
-  if (!BN_add(toBigNum(r), toBigNum(a), toBigNum(b))) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_sub(JNIEnv* env, jclass, jlong r, jlong a, jlong b) {
-  if (!threeValidHandles(env, r, a, b)) return;
-  if (!BN_sub(toBigNum(r), toBigNum(a), toBigNum(b))) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_gcd(JNIEnv* env, jclass, jlong r, jlong a, jlong b) {
-  if (!threeValidHandles(env, r, a, b)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_gcd(toBigNum(r), toBigNum(a), toBigNum(b), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_mul(JNIEnv* env, jclass, jlong r, jlong a, jlong b) {
-  if (!threeValidHandles(env, r, a, b)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_mul(toBigNum(r), toBigNum(a), toBigNum(b), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p) {
-  if (!threeValidHandles(env, r, a, p)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_exp(toBigNum(r), toBigNum(a), toBigNum(p), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_div(JNIEnv* env, jclass, jlong dv, jlong rem, jlong m, jlong d) {
-  if (!fourValidHandles(env, (rem ? rem : dv), (dv ? dv : rem), m, d)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_div(toBigNum(dv), toBigNum(rem), toBigNum(m), toBigNum(d), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_nnmod(JNIEnv* env, jclass, jlong r, jlong a, jlong m) {
-  if (!threeValidHandles(env, r, a, m)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_nnmod(toBigNum(r), toBigNum(a), toBigNum(m), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_mod_exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p, jlong m) {
-  if (!fourValidHandles(env, r, a, p, m)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_mod_exp(toBigNum(r), toBigNum(a), toBigNum(p), toBigNum(m), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_mod_inverse(JNIEnv* env, jclass, jlong ret, jlong a, jlong n) {
-  if (!threeValidHandles(env, ret, a, n)) return;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  if (!BN_mod_inverse(toBigNum(ret), toBigNum(a), toBigNum(n), ctx.get())) {
-    throwException(env);
-  }
-}
-
-static void NativeBN_BN_generate_prime_ex(JNIEnv* env, jclass, jlong ret, int bits,
-                                          jboolean safe, jlong add, jlong rem) {
-  if (!oneValidHandle(env, ret)) return;
-  if (!BN_generate_prime_ex(toBigNum(ret), bits, safe, toBigNum(add), toBigNum(rem),
-                            NULL)) {
-    throwException(env);
-  }
-}
-
-static jboolean NativeBN_BN_primality_test(JNIEnv* env, jclass, jlong candidate, int checks,
-                                           jboolean do_trial_decryption) {
-  if (!oneValidHandle(env, candidate)) return JNI_FALSE;
-  Unique_BN_CTX ctx(BN_CTX_new());
-  int is_probably_prime;
-  if (!BN_primality_test(&is_probably_prime, toBigNum(candidate), checks, ctx.get(),
-                         do_trial_decryption, NULL)) {
-    throwException(env);
-    return JNI_FALSE;
-  }
-  return is_probably_prime ? JNI_TRUE : JNI_FALSE;
-}
-
-static JNINativeMethod gMethods[] = {
-   NATIVE_METHOD(NativeBN, BN_add, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_add_word, "(JI)V"),
-   NATIVE_METHOD(NativeBN, BN_bin2bn, "([BIZJ)V"),
-   NATIVE_METHOD(NativeBN, BN_bn2bin, "(J)[B"),
-   NATIVE_METHOD(NativeBN, BN_bn2dec, "(J)Ljava/lang/String;"),
-   NATIVE_METHOD(NativeBN, BN_bn2hex, "(J)Ljava/lang/String;"),
-   NATIVE_METHOD(NativeBN, BN_cmp, "(JJ)I"),
-   NATIVE_METHOD(NativeBN, BN_copy, "(JJ)V"),
-   NATIVE_METHOD(NativeBN, BN_dec2bn, "(JLjava/lang/String;)I"),
-   NATIVE_METHOD(NativeBN, BN_div, "(JJJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_exp, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_free, "(J)V"),
-   NATIVE_METHOD(NativeBN, BN_gcd, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_generate_prime_ex, "(JIZJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_hex2bn, "(JLjava/lang/String;)I"),
-   NATIVE_METHOD(NativeBN, BN_is_bit_set, "(JI)Z"),
-   NATIVE_METHOD(NativeBN, BN_primality_test, "(JIZ)Z"),
-   NATIVE_METHOD(NativeBN, BN_mod_exp, "(JJJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_mod_inverse, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_mod_word, "(JI)I"),
-   NATIVE_METHOD(NativeBN, BN_mul, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_mul_word, "(JI)V"),
-   NATIVE_METHOD(NativeBN, BN_new, "()J"),
-   NATIVE_METHOD(NativeBN, BN_nnmod, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, BN_set_negative, "(JI)V"),
-   NATIVE_METHOD(NativeBN, BN_shift, "(JJI)V"),
-   NATIVE_METHOD(NativeBN, BN_sub, "(JJJ)V"),
-   NATIVE_METHOD(NativeBN, bitLength, "(J)I"),
-   NATIVE_METHOD(NativeBN, bn2litEndInts, "(J)[I"),
-   NATIVE_METHOD(NativeBN, getNativeFinalizer, "()J"),
-   NATIVE_METHOD(NativeBN, litEndInts2bn, "([IIZJ)V"),
-   NATIVE_METHOD(NativeBN, longInt, "(J)J"),
-   NATIVE_METHOD(NativeBN, putLongInt, "(JJ)V"),
-   NATIVE_METHOD(NativeBN, putULongInt, "(JJZ)V"),
-   NATIVE_METHOD(NativeBN, sign, "(J)I"),
-   NATIVE_METHOD(NativeBN, twosComp2bn, "([BIJ)V"),
-};
-void register_java_math_NativeBN(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "java/math/NativeBN", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index 9879761..f9401d1e 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -17,83 +17,26 @@
 #define LOG_NDEBUG 1
 #define LOG_TAG "ICU"
 
-#include <errno.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <string.h>
-#include <string>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
 #include <memory>
 #include <vector>
 
-#include <androidicuinit/IcuRegistration.h>
 #include <log/log.h>
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedLocalRef.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 "ScopedIcuLocale.h"
 #include "ScopedIcuULoc.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/brkiter.h"
 #include "unicode/char16ptr.h"
-#include "unicode/calendar.h"
-#include "unicode/datefmt.h"
-#include "unicode/dcfmtsym.h"
-#include "unicode/decimfmt.h"
-#include "unicode/dtfmtsym.h"
-#include "unicode/gregocal.h"
-#include "unicode/locid.h"
-#include "unicode/numfmt.h"
-#include "unicode/strenum.h"
-#include "unicode/ubrk.h"
-#include "unicode/ucal.h"
-#include "unicode/ucasemap.h"
-#include "unicode/ucol.h"
-#include "unicode/ucurr.h"
-#include "unicode/udat.h"
-#include "unicode/udatpg.h"
+#include "unicode/uchar.h"
 #include "unicode/uloc.h"
-#include "unicode/ures.h"
+#include "unicode/ulocdata.h"
 #include "unicode/ustring.h"
-#include "ureslocs.h"
-#include "valueOf.h"
+#include "unicode/uversion.h"
 
-class ScopedResourceBundle {
- public:
-  explicit ScopedResourceBundle(UResourceBundle* bundle) : bundle_(bundle) {
-  }
-
-  ~ScopedResourceBundle() {
-    if (bundle_ != NULL) {
-      ures_close(bundle_);
-    }
-  }
-
-  UResourceBundle* get() {
-    return bundle_;
-  }
-
-  bool hasKey(const char* key) {
-    UErrorCode status = U_ZERO_ERROR;
-    ures_getStringByKey(bundle_, key, NULL, &status);
-    return U_SUCCESS(status);
-  }
-
- private:
-  UResourceBundle* bundle_;
-  DISALLOW_COPY_AND_ASSIGN(ScopedResourceBundle);
-};
+#define U_ICUDATA_CURR U_ICUDATA_NAME "-" "curr"
 
 static jstring ICU_getScript(JNIEnv* env, jclass, jstring javaLocaleName) {
   ScopedIcuULoc icuLocale(env, javaLocaleName);
@@ -103,7 +46,7 @@
   // Normal script part is 4-char long. Being conservative for allocation size
   // because if the locale contains script part, it should not be longer than the locale itself.
   int32_t capacity = std::max(ULOC_SCRIPT_CAPACITY, icuLocale.locale_length() + 1);
-  std::unique_ptr<char[]> buffer(new char(capacity));
+  auto buffer = std::make_unique<char[]>(capacity);
   UErrorCode status = U_ZERO_ERROR;
   uloc_getScript(icuLocale.locale(), buffer.get(), capacity, &status);
   if (U_FAILURE(status)) {
@@ -112,81 +55,6 @@
   return env->NewStringUTF(buffer.get());
 }
 
-// TODO: rewrite this with int32_t ucurr_forLocale(const char* locale, UChar* buff, int32_t buffCapacity, UErrorCode* ec)...
-static jstring ICU_getCurrencyCode(JNIEnv* env, jclass, jstring javaCountryCode) {
-    UErrorCode status = U_ZERO_ERROR;
-    ScopedResourceBundle supplData(ures_openDirect(U_ICUDATA_CURR, "supplementalData", &status));
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-
-    ScopedResourceBundle currencyMap(ures_getByKey(supplData.get(), "CurrencyMap", NULL, &status));
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-
-    ScopedUtfChars countryCode(env, javaCountryCode);
-    ScopedResourceBundle currency(ures_getByKey(currencyMap.get(), countryCode.c_str(), NULL, &status));
-    if (U_FAILURE(status)) {
-        return NULL;
-    }
-
-    ScopedResourceBundle currencyElem(ures_getByIndex(currency.get(), 0, NULL, &status));
-    if (U_FAILURE(status)) {
-        return env->NewStringUTF("XXX");
-    }
-
-    // Check if there's a 'to' date. If there is, the currency isn't used anymore.
-    ScopedResourceBundle currencyTo(ures_getByKey(currencyElem.get(), "to", NULL, &status));
-    if (!U_FAILURE(status)) {
-        return NULL;
-    }
-    // Ignore the failure to find a 'to' date.
-    status = U_ZERO_ERROR;
-
-    ScopedResourceBundle currencyId(ures_getByKey(currencyElem.get(), "id", NULL, &status));
-    if (U_FAILURE(status)) {
-        // No id defined for this country
-        return env->NewStringUTF("XXX");
-    }
-
-    int32_t charCount;
-    const UChar* chars = ures_getString(currencyId.get(), &charCount, &status);
-    return (charCount == 0) ? env->NewStringUTF("XXX") : jniCreateString(env, chars, charCount);
-}
-
-static jstring getCurrencyName(JNIEnv* env, jstring javaLanguageTag, jstring javaCurrencyCode, UCurrNameStyle nameStyle) {
-  ScopedUtfChars languageTag(env, javaLanguageTag);
-  if (languageTag.c_str() == NULL) {
-    return NULL;
-  }
-  ScopedJavaUnicodeString currencyCode(env, javaCurrencyCode);
-  if (!currencyCode.valid()) {
-    return NULL;
-  }
-  icu::UnicodeString icuCurrencyCode(currencyCode.unicodeString());
-  UErrorCode status = U_ZERO_ERROR;
-  UBool isChoiceFormat = false;
-  int32_t charCount;
-  const UChar* chars = ucurr_getName(icuCurrencyCode.getTerminatedBuffer(), languageTag.c_str(),
-                                     nameStyle, &isChoiceFormat, &charCount, &status);
-  if (status == U_USING_DEFAULT_WARNING) {
-    if (nameStyle == UCURR_SYMBOL_NAME) {
-      // ICU doesn't distinguish between falling back to the root locale and meeting a genuinely
-      // unknown currency. The Currency class does.
-      if (!ucurr_isAvailable(icuCurrencyCode.getTerminatedBuffer(), U_DATE_MIN, U_DATE_MAX, &status)) {
-        return NULL;
-      }
-    }
-    if (nameStyle == UCURR_LONG_NAME) {
-      // ICU's default is English. We want the ISO 4217 currency code instead.
-      chars = icuCurrencyCode.getBuffer();
-      charCount = icuCurrencyCode.length();
-    }
-  }
-  return (charCount == 0) ? NULL : jniCreateString(env, chars, charCount);
-}
-
 static jstring ICU_getISO3Country(JNIEnv* env, jclass, jstring javaLanguageTag) {
   ScopedIcuULoc icuLocale(env, javaLanguageTag);
   if (!icuLocale.valid()) {
@@ -215,472 +83,53 @@
     return toStringArray(env, uloc_countAvailable, uloc_getAvailable);
 }
 
-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::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::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::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::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()) {
-            return;
-        }
-        env->SetObjectArrayElement(result.get(), i, s.get());
-        if (env->ExceptionCheck()) {
-            return;
-        }
-    }
-    setStringArrayField(env, obj, fieldName, result.get());
-}
-
-static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, UResourceBundle* bundle, int index) {
-  UErrorCode status = U_ZERO_ERROR;
-  int charCount;
-  const UChar* chars;
-  UResourceBundle* currentBundle = ures_getByIndex(bundle, index, NULL, &status);
-  switch (ures_getType(currentBundle)) {
-      case URES_STRING:
-         chars = ures_getString(currentBundle, &charCount, &status);
-         break;
-      case URES_ARRAY:
-         // In case there is an array, Android currently only cares about the
-         // first string of that array, the rest of the array is used by ICU
-         // for additional data ignored by Android.
-         chars = ures_getStringByIndex(currentBundle, 0, &charCount, &status);
-         break;
-      default:
-         status = U_INVALID_FORMAT_ERROR;
-  }
-  ures_close(currentBundle);
-  if (U_SUCCESS(status)) {
-    setStringField(env, obj, fieldName, jniCreateString(env, chars, charCount));
-  } else {
-    ALOGE("Error setting String field %s from ICU resource (index %d): %s", fieldName, index, u_errorName(status));
-  }
-}
-
-static void setCharField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString& value) {
-    if (value.length() == 0) {
-        return;
-    }
-    jfieldID fid = env->GetFieldID(JniConstants::GetLocaleDataClass(env), fieldName, "C");
-    env->SetCharField(obj, fid, value.charAt(0));
-}
-
-static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, const icu::UnicodeString& value) {
-    const UChar* chars = value.getBuffer();
-    setStringField(env, obj, fieldName, jniCreateString(env, chars, value.length()));
-}
-
-static void setNumberPatterns(JNIEnv* env, jobject obj, icu::Locale& locale) {
-    UErrorCode status = U_ZERO_ERROR;
-
-    icu::UnicodeString pattern;
-    std::unique_ptr<icu::DecimalFormat> fmt(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_CURRENCY, status)));
-    pattern = fmt->toPattern(pattern.remove());
-    setStringField(env, obj, "currencyPattern", pattern);
-
-    fmt.reset(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_DECIMAL, status)));
-    pattern = fmt->toPattern(pattern.remove());
-    setStringField(env, obj, "numberPattern", pattern);
-
-    fmt.reset(static_cast<icu::DecimalFormat*>(icu::NumberFormat::createInstance(locale, UNUM_PERCENT, status)));
-    pattern = fmt->toPattern(pattern.remove());
-    setStringField(env, obj, "percentPattern", pattern);
-}
-
-static void setDecimalFormatSymbolsData(JNIEnv* env, jobject obj, icu::Locale& locale) {
-    UErrorCode status = U_ZERO_ERROR;
-    icu::DecimalFormatSymbols dfs(locale, status);
-
-    setCharField(env, obj, "decimalSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kDecimalSeparatorSymbol));
-    setCharField(env, obj, "groupingSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kGroupingSeparatorSymbol));
-    setCharField(env, obj, "patternSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kPatternSeparatorSymbol));
-    setStringField(env, obj, "percent", dfs.getSymbol(icu::DecimalFormatSymbols::kPercentSymbol));
-    setStringField(env, obj, "perMill", dfs.getSymbol(icu::DecimalFormatSymbols::kPerMillSymbol));
-    setCharField(env, obj, "monetarySeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kMonetarySeparatorSymbol));
-    setStringField(env, obj, "minusSign", dfs.getSymbol(icu::DecimalFormatSymbols:: kMinusSignSymbol));
-    setStringField(env, obj, "exponentSeparator", dfs.getSymbol(icu::DecimalFormatSymbols::kExponentialSymbol));
-    setStringField(env, obj, "infinity", dfs.getSymbol(icu::DecimalFormatSymbols::kInfinitySymbol));
-    setStringField(env, obj, "NaN", dfs.getSymbol(icu::DecimalFormatSymbols::kNaNSymbol));
-    setCharField(env, obj, "zeroDigit", dfs.getSymbol(icu::DecimalFormatSymbols::kZeroDigitSymbol));
-}
-
-
-// Iterates up through the locale hierarchy. So "en_US" would return "en_US", "en", "".
-class LocaleNameIterator {
- public:
-  LocaleNameIterator(const char* locale_name, UErrorCode& status) : status_(status), has_next_(true) {
-    strcpy(locale_name_, locale_name);
-    locale_name_length_ = strlen(locale_name_);
-  }
-
-  const char* Get() {
-      return locale_name_;
-  }
-
-  bool HasNext() {
-    return has_next_;
-  }
-
-  void Up() {
-    if (locale_name_length_ == 0) {
-      has_next_ = false;
-    } else {
-      locale_name_length_ = uloc_getParent(locale_name_, locale_name_, sizeof(locale_name_), &status_);
-    }
-  }
-
- private:
-  UErrorCode& status_;
-  bool has_next_;
-  char locale_name_[ULOC_FULLNAME_CAPACITY];
-  int32_t locale_name_length_;
-
-  DISALLOW_COPY_AND_ASSIGN(LocaleNameIterator);
-};
-
-static bool getAmPmMarkersNarrow(JNIEnv* env, jobject localeData, const char* locale_name) {
-  UErrorCode status = U_ZERO_ERROR;
-  ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle amPmMarkersNarrow(ures_getByKey(gregorian.get(), "AmPmMarkersNarrow", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  setStringField(env, localeData, "narrowAm", amPmMarkersNarrow.get(), 0);
-  setStringField(env, localeData, "narrowPm", amPmMarkersNarrow.get(), 1);
-  return true;
-}
-
-static bool getDateTimePatterns(JNIEnv* env, jobject localeData, const char* locale_name) {
-  UErrorCode status = U_ZERO_ERROR;
-  ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle calendar(ures_getByKey(root.get(), "calendar", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle gregorian(ures_getByKey(calendar.get(), "gregorian", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  ScopedResourceBundle dateTimePatterns(ures_getByKey(gregorian.get(), "DateTimePatterns", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-  setStringField(env, localeData, "fullTimeFormat", dateTimePatterns.get(), 0);
-  setStringField(env, localeData, "longTimeFormat", dateTimePatterns.get(), 1);
-  setStringField(env, localeData, "mediumTimeFormat", dateTimePatterns.get(), 2);
-  setStringField(env, localeData, "shortTimeFormat", dateTimePatterns.get(), 3);
-  setStringField(env, localeData, "fullDateFormat", dateTimePatterns.get(), 4);
-  setStringField(env, localeData, "longDateFormat", dateTimePatterns.get(), 5);
-  setStringField(env, localeData, "mediumDateFormat", dateTimePatterns.get(), 6);
-  setStringField(env, localeData, "shortDateFormat", dateTimePatterns.get(), 7);
-  return true;
-}
-
-static bool getYesterdayTodayAndTomorrow(JNIEnv* env, jobject localeData, const icu::Locale& locale, const char* locale_name) {
-  UErrorCode status = U_ZERO_ERROR;
-  ScopedResourceBundle root(ures_open(NULL, locale_name, &status));
-  ScopedResourceBundle fields(ures_getByKey(root.get(), "fields", NULL, &status));
-  ScopedResourceBundle day(ures_getByKey(fields.get(), "day", NULL, &status));
-  ScopedResourceBundle relative(ures_getByKey(day.get(), "relative", NULL, &status));
-  if (U_FAILURE(status)) {
-    return false;
-  }
-
-  icu::UnicodeString yesterday(icu::ures_getUnicodeStringByKey(relative.get(), "-1", &status));
-  icu::UnicodeString today(icu::ures_getUnicodeStringByKey(relative.get(), "0", &status));
-  icu::UnicodeString tomorrow(icu::ures_getUnicodeStringByKey(relative.get(), "1", &status));
-  if (U_FAILURE(status)) {
-    ALOGE("Error getting yesterday/today/tomorrow for %s: %s", locale_name, u_errorName(status));
-    return false;
-  }
-
-  // We title-case the strings so they have consistent capitalization (http://b/14493853).
-  std::unique_ptr<icu::BreakIterator> brk(icu::BreakIterator::createSentenceInstance(locale, status));
-  if (U_FAILURE(status)) {
-    ALOGE("Error getting yesterday/today/tomorrow break iterator for %s: %s", locale_name, u_errorName(status));
-    return false;
-  }
-  yesterday.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
-  today.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
-  tomorrow.toTitle(brk.get(), locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
-
-  setStringField(env, localeData, "yesterday", yesterday);
-  setStringField(env, localeData, "today", today);
-  setStringField(env, localeData, "tomorrow", tomorrow);
-  return true;
-}
-
-static jboolean ICU_initLocaleDataNative(JNIEnv* env, jclass, jstring javaLanguageTag, jobject localeData) {
-    ScopedUtfChars languageTag(env, javaLanguageTag);
-    if (languageTag.c_str() == NULL) {
-        return JNI_FALSE;
-    }
-    if (languageTag.size() >= ULOC_FULLNAME_CAPACITY) {
-        return JNI_FALSE; // ICU has a fixed-length limit.
-    }
-
-    ScopedIcuLocale icuLocale(env, javaLanguageTag);
-    if (!icuLocale.valid()) {
-      return JNI_FALSE;
-    }
-
-    // Get the DateTimePatterns.
-    UErrorCode status = U_ZERO_ERROR;
-    bool foundDateTimePatterns = false;
-    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
-      if (getDateTimePatterns(env, localeData, it.Get())) {
-          foundDateTimePatterns = true;
-          break;
-      }
-    }
-    if (!foundDateTimePatterns) {
-        ALOGE("Couldn't find ICU DateTimePatterns for %s", languageTag.c_str());
-        return JNI_FALSE;
-    }
-
-    // Get the "Yesterday", "Today", and "Tomorrow" strings.
-    bool foundYesterdayTodayAndTomorrow = false;
-    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
-      if (getYesterdayTodayAndTomorrow(env, localeData, icuLocale.locale(), it.Get())) {
-        foundYesterdayTodayAndTomorrow = true;
-        break;
-      }
-    }
-    if (!foundYesterdayTodayAndTomorrow) {
-      ALOGE("Couldn't find ICU yesterday/today/tomorrow for %s", languageTag.c_str());
-      return JNI_FALSE;
-    }
-
-    // Get the narrow "AM" and "PM" strings.
-    bool foundAmPmMarkersNarrow = false;
-    for (LocaleNameIterator it(icuLocale.locale().getBaseName(), status); it.HasNext(); it.Up()) {
-      if (getAmPmMarkersNarrow(env, localeData, it.Get())) {
-        foundAmPmMarkersNarrow = true;
-        break;
-      }
-    }
-    if (!foundAmPmMarkersNarrow) {
-      ALOGE("Couldn't find ICU AmPmMarkersNarrow for %s", languageTag.c_str());
-      return JNI_FALSE;
-    }
-
-    status = U_ZERO_ERROR;
-    std::unique_ptr<icu::Calendar> cal(icu::Calendar::createInstance(icuLocale.locale(), status));
-    if (U_FAILURE(status)) {
-        return JNI_FALSE;
-    }
-    if (!setIntegerField(env, localeData, "firstDayOfWeek", cal->getFirstDayOfWeek())) {
-      return JNI_FALSE;
-    }
-    if (!setIntegerField(env, localeData, "minimalDaysInFirstWeek", cal->getMinimalDaysInFirstWeek())) {
-      return JNI_FALSE;
-    }
-
-    // Get DateFormatSymbols.
-    status = U_ZERO_ERROR;
-    icu::DateFormatSymbols dateFormatSym(icuLocale.locale(), status);
-    if (U_FAILURE(status)) {
-        return JNI_FALSE;
-    }
-
-    // Get AM/PM and BC/AD.
-    int32_t count = 0;
-    const icu::UnicodeString* amPmStrs = dateFormatSym.getAmPmStrings(count);
-    setStringArrayField(env, localeData, "amPm", amPmStrs, count);
-    const icu::UnicodeString* erasStrs = dateFormatSym.getEras(count);
-    setStringArrayField(env, localeData, "eras", erasStrs, count);
-
-    const icu::UnicodeString* longMonthNames =
-       dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::WIDE);
-    setStringArrayField(env, localeData, "longMonthNames", longMonthNames, count);
-    const icu::UnicodeString* shortMonthNames =
-        dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::ABBREVIATED);
-    setStringArrayField(env, localeData, "shortMonthNames", shortMonthNames, count);
-    const icu::UnicodeString* tinyMonthNames =
-        dateFormatSym.getMonths(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::NARROW);
-    setStringArrayField(env, localeData, "tinyMonthNames", tinyMonthNames, count);
-    const icu::UnicodeString* longWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::WIDE);
-    setStringArrayField(env, localeData, "longWeekdayNames", longWeekdayNames, count);
-    const icu::UnicodeString* shortWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::ABBREVIATED);
-    setStringArrayField(env, localeData, "shortWeekdayNames", shortWeekdayNames, count);
-    const icu::UnicodeString* tinyWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::FORMAT, icu::DateFormatSymbols::NARROW);
-    setStringArrayField(env, localeData, "tinyWeekdayNames", tinyWeekdayNames, count);
-
-    const icu::UnicodeString* longStandAloneMonthNames =
-        dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::WIDE);
-    setStringArrayField(env, localeData, "longStandAloneMonthNames", longStandAloneMonthNames, count);
-    const icu::UnicodeString* shortStandAloneMonthNames =
-        dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::ABBREVIATED);
-    setStringArrayField(env, localeData, "shortStandAloneMonthNames", shortStandAloneMonthNames, count);
-    const icu::UnicodeString* tinyStandAloneMonthNames =
-        dateFormatSym.getMonths(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::NARROW);
-    setStringArrayField(env, localeData, "tinyStandAloneMonthNames", tinyStandAloneMonthNames, count);
-    const icu::UnicodeString* longStandAloneWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::WIDE);
-    setStringArrayField(env, localeData, "longStandAloneWeekdayNames", longStandAloneWeekdayNames, count);
-    const icu::UnicodeString* shortStandAloneWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::ABBREVIATED);
-    setStringArrayField(env, localeData, "shortStandAloneWeekdayNames", shortStandAloneWeekdayNames, count);
-    const icu::UnicodeString* tinyStandAloneWeekdayNames =
-        dateFormatSym.getWeekdays(count, icu::DateFormatSymbols::STANDALONE, icu::DateFormatSymbols::NARROW);
-    setStringArrayField(env, localeData, "tinyStandAloneWeekdayNames", tinyStandAloneWeekdayNames, count);
-
-    status = U_ZERO_ERROR;
-
-    // For numberPatterns and symbols.
-    setNumberPatterns(env, localeData, icuLocale.locale());
-    setDecimalFormatSymbolsData(env, localeData, icuLocale.locale());
-
-    jstring countryCode = env->NewStringUTF(icuLocale.locale().getCountry());
-    jstring internationalCurrencySymbol = ICU_getCurrencyCode(env, NULL, countryCode);
-    env->DeleteLocalRef(countryCode);
-    countryCode = NULL;
-
-    jstring currencySymbol = NULL;
-    if (internationalCurrencySymbol != NULL) {
-        currencySymbol = getCurrencyName(env, javaLanguageTag, internationalCurrencySymbol, UCURR_SYMBOL_NAME);
-    } else {
-        internationalCurrencySymbol = env->NewStringUTF("XXX");
-    }
-    if (currencySymbol == NULL) {
-        // This is the UTF-8 encoding of U+00A4 (CURRENCY SIGN).
-        currencySymbol = env->NewStringUTF("\xc2\xa4");
-    }
-    setStringField(env, localeData, "currencySymbol", currencySymbol);
-    setStringField(env, localeData, "internationalCurrencySymbol", internationalCurrencySymbol);
-
-    return JNI_TRUE;
-}
-
-static jstring ICU_getBestDateTimePatternNative(JNIEnv* env, jclass, jstring javaSkeleton, jstring javaLanguageTag) {
-  ScopedIcuULoc icuLocale(env, javaLanguageTag);
-  if (!icuLocale.valid()) {
-    return NULL;
-  }
-
-  UErrorCode status = U_ZERO_ERROR;
-  std::unique_ptr<UDateTimePatternGenerator, decltype(&udatpg_close)> generator(
-    udatpg_open(icuLocale.locale(), &status), &udatpg_close);
-  if (maybeThrowIcuException(env, "udatpg_open", status)) {
-    return NULL;
-  }
-
-  const ScopedStringChars skeletonHolder(env, javaSkeleton);
-  // Convert jchar* to UChar* with the inline-able utility provided by char16ptr.h
-  // which prevents certain compiler optimization than reinterpret_cast.
-  icu::ConstChar16Ptr skeletonPtr(skeletonHolder.get());
-  const UChar* skeleton = icu::toUCharPtr(skeletonPtr.get());
-
-  int32_t patternLength;
-  // Try with fixed-size buffer. 128 chars should be enough for most patterns.
-  // If the buffer is not sufficient, run the below case of U_BUFFER_OVERFLOW_ERROR.
-  #define PATTERN_BUFFER_SIZE 128
-  {
-    UChar buffer[PATTERN_BUFFER_SIZE];
-    status = U_ZERO_ERROR;
-    patternLength = udatpg_getBestPattern(generator.get(), skeleton,
-      skeletonHolder.size(), buffer, PATTERN_BUFFER_SIZE, &status);
-    if (U_SUCCESS(status)) {
-      return jniCreateString(env, buffer, patternLength);
-    } else if (status != U_BUFFER_OVERFLOW_ERROR) {
-      maybeThrowIcuException(env, "udatpg_getBestPattern", status);
-      return NULL;
-    }
-  }
-  #undef PATTERN_BUFFER_SIZE
-
-  // Case U_BUFFER_OVERFLOW_ERROR
-  std::unique_ptr<UChar[]> buffer(new UChar[patternLength+1]);
-  status = U_ZERO_ERROR;
-  patternLength = udatpg_getBestPattern(generator.get(), skeleton,
-      skeletonHolder.size(), buffer.get(), patternLength+1, &status);
-  if (maybeThrowIcuException(env, "udatpg_getBestPattern", status)) {
-    return NULL;
-  }
-
-  return jniCreateString(env, buffer.get(), patternLength);
-}
-
-static void ICU_setDefaultLocale(JNIEnv* env, jclass, jstring javaLanguageTag) {
-  ScopedIcuULoc icuLocale(env, javaLanguageTag);
-  if (!icuLocale.valid()) {
-    return;
-  }
-
-  UErrorCode status = U_ZERO_ERROR;
-  uloc_setDefault(icuLocale.locale(), &status);
-  maybeThrowIcuException(env, "uloc_setDefault", status);
-}
-
 static jstring ICU_getDefaultLocale(JNIEnv* env, jclass) {
   return env->NewStringUTF(uloc_getDefault());
 }
 
+static jstring versionString(JNIEnv* env, const UVersionInfo& version) {
+    char versionString[U_MAX_VERSION_STRING_LENGTH];
+    u_versionToString(const_cast<UVersionInfo&>(version), &versionString[0]);
+    return env->NewStringUTF(versionString);
+}
+
+static jstring ICU_getCldrVersion(JNIEnv* env, jclass) {
+  UErrorCode status = U_ZERO_ERROR;
+  UVersionInfo cldrVersion;
+  ulocdata_getCLDRVersion(cldrVersion, &status);
+  return versionString(env, cldrVersion);
+}
+
+static jstring ICU_getIcuVersion(JNIEnv* env, jclass) {
+    UVersionInfo icuVersion;
+    u_getVersion(icuVersion);
+    return versionString(env, icuVersion);
+}
+
+static jstring ICU_getUnicodeVersion(JNIEnv* env, jclass) {
+    UVersionInfo unicodeVersion;
+    u_getUnicodeVersion(unicodeVersion);
+    return versionString(env, unicodeVersion);
+}
+
 static JNINativeMethod gMethods[] = {
     NATIVE_METHOD(ICU, getAvailableLocalesNative, "()[Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, getBestDateTimePatternNative, "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, getCurrencyCode, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(ICU, getCldrVersion, "()Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getDefaultLocale, "()Ljava/lang/String;"),
+    NATIVE_METHOD(ICU, getIcuVersion, "()Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISO3Country, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISO3Language, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISOCountriesNative, "()[Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getISOLanguagesNative, "()[Ljava/lang/String;"),
     NATIVE_METHOD(ICU, getScript, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(ICU, initLocaleDataNative, "(Ljava/lang/String;Llibcore/icu/LocaleData;)Z"),
-    NATIVE_METHOD(ICU, setDefaultLocale, "(Ljava/lang/String;)V"),
+    NATIVE_METHOD(ICU, getUnicodeVersion, "()Ljava/lang/String;"),
 };
 
-//
-// Global initialization & Teardown for ICU Setup
-//   - Contains handlers for JNI_OnLoad and JNI_OnUnload
-//
-
-// Init ICU, configuring it and loading the data files.
 void register_libcore_icu_ICU(JNIEnv* env) {
-  androidicuinit::IcuRegistration::Register();
-
   jniRegisterNativeMethods(env, "libcore/icu/ICU", gMethods, NELEM(gMethods));
 }
 
-// De-init ICU, unloading the data files. Do the opposite of the above function.
 void unregister_libcore_icu_ICU() {
   // Skip unregistering JNI methods explicitly, class unloading takes care of
   // it.
-
-  androidicuinit::IcuRegistration::Deregister();
 }
diff --git a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp b/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
deleted file mode 100644
index db4c6f2..0000000
--- a/luni/src/main/native/libcore_icu_TimeZoneNames.cpp
+++ /dev/null
@@ -1,105 +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.
- */
-
-#define LOG_TAG "TimeZoneNames"
-
-#include <memory>
-
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedLocalRef.h>
-#include <nativehelper/ScopedUtfChars.h>
-#include <nativehelper/jni_macros.h>
-
-#include "IcuUtilities.h"
-#include "JniException.h"
-#include "ScopedIcuLocale.h"
-#include "ScopedJavaUnicodeString.h"
-#include "unicode/calendar.h"
-#include "unicode/timezone.h"
-#include "unicode/tznames.h"
-
-static bool setStringArrayElement(JNIEnv* env, jobjectArray array, int i, const icu::UnicodeString& s) {
-  // Don't use "GMT" string, for backwards compatibility.
-  static const icu::UnicodeString kGmt("GMT", 3, US_INV);
-  if (!s.isBogus() && !s.startsWith(kGmt)) {
-    ScopedLocalRef<jstring> javaString(env, jniCreateString(env, s.getBuffer(), s.length()));
-    if (javaString.get() == NULL) {
-      return false;
-    }
-    env->SetObjectArrayElement(array, i, javaString.get());
-  }
-  return true;
-}
-
-static void TimeZoneNames_fillZoneStrings(JNIEnv* env, jclass, jstring javaLocaleName, jobjectArray result) {
-  ScopedIcuLocale icuLocale(env, javaLocaleName);
-  if (!icuLocale.valid()) {
-    return;
-  }
-
-  UErrorCode status = U_ZERO_ERROR;
-  std::unique_ptr<icu::TimeZoneNames> names(icu::TimeZoneNames::createInstance(icuLocale.locale(), status));
-  if (maybeThrowIcuException(env, "TimeZoneNames::createInstance", status)) {
-    return;
-  }
-
-  const UDate now(icu::Calendar::getNow());
-
-  size_t id_count = env->GetArrayLength(result);
-  for (size_t i = 0; i < id_count; ++i) {
-    ScopedLocalRef<jobjectArray> java_row(env,
-                                          reinterpret_cast<jobjectArray>(env->GetObjectArrayElement(result, i)));
-    ScopedLocalRef<jstring> java_zone_id(env,
-                                         reinterpret_cast<jstring>(env->GetObjectArrayElement(java_row.get(), 0)));
-    ScopedJavaUnicodeString zone_id(env, java_zone_id.get());
-    if (!zone_id.valid()) {
-      return;
-    }
-
-    // Canonicalize the zone ID to the one known by ICU.
-    icu::UnicodeString lookup_id;
-    icu::TimeZone::getCanonicalID(zone_id.unicodeString(), lookup_id, status);
-    if (status != U_ZERO_ERROR) {
-      // Unknown ID - just use the zone ID we have.
-      lookup_id = zone_id.unicodeString();
-    }
-
-    icu::UnicodeString long_std;
-    names->getDisplayName(lookup_id, UTZNM_LONG_STANDARD, now, long_std);
-    icu::UnicodeString short_std;
-    names->getDisplayName(lookup_id, UTZNM_SHORT_STANDARD, now, short_std);
-    icu::UnicodeString long_dst;
-    names->getDisplayName(lookup_id, UTZNM_LONG_DAYLIGHT, now, long_dst);
-    icu::UnicodeString short_dst;
-    names->getDisplayName(lookup_id, UTZNM_SHORT_DAYLIGHT, now, short_dst);
-
-    bool okay =
-        setStringArrayElement(env, java_row.get(), 1, long_std) &&
-        setStringArrayElement(env, java_row.get(), 2, short_std) &&
-        setStringArrayElement(env, java_row.get(), 3, long_dst) &&
-        setStringArrayElement(env, java_row.get(), 4, short_dst);
-    if (!okay) {
-      return;
-    }
-  }
-}
-
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(TimeZoneNames, fillZoneStrings, "(Ljava/lang/String;[[Ljava/lang/String;)V"),
-};
-void register_libcore_icu_TimeZoneNames(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "libcore/icu/TimeZoneNames", gMethods, NELEM(gMethods));
-}
diff --git a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
index 55803b8..e99edd6 100644
--- a/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
+++ b/luni/src/main/native/libcore_io_AsynchronousCloseMonitor.cpp
@@ -16,7 +16,7 @@
 
 #define LOG_TAG "AsynchronousCloseMonitor"
 
-#include <nativehelper/JNIHelp.h>
+#include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/jni_macros.h>
 
 #include "AsynchronousCloseMonitor.h"
diff --git a/luni/src/main/native/libcore_io_Linux.cpp b/luni/src/main/native/libcore_io_Linux.cpp
old mode 100644
new mode 100755
index 9e44e63..d7b6c22
--- a/luni/src/main/native/libcore_io_Linux.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -29,6 +29,7 @@
 #include <pwd.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/capability.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
@@ -58,8 +59,7 @@
 #include <android-base/macros.h>
 #include <android-base/strings.h>
 #include <log/log.h>
-#include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedBytes.h>
+#include <nativehelper/JNIPlatformHelp.h>
 #include <nativehelper/ScopedLocalRef.h>
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/ScopedUtfChars.h>
@@ -72,6 +72,10 @@
 #include "JniException.h"
 #include "NetworkUtilities.h"
 #include "Portability.h"
+#include "ScopedBytes.h"
+#include "ScopedByteBufferArray.h"
+#include "ScopedMsghdr.h"
+
 
 #ifndef __unused
 #define __unused __attribute__((__unused__))
@@ -256,12 +260,7 @@
 
 static void throwErrnoException(JNIEnv* env, const char* functionName) {
     int error = errno;
-    jclass errnoExceptionClass = JniConstants::GetErrnoExceptionClass(env);
-    static jmethodID ctor3 = env->GetMethodID(errnoExceptionClass,
-            "<init>", "(Ljava/lang/String;ILjava/lang/Throwable;)V");
-    static jmethodID ctor2 = env->GetMethodID(errnoExceptionClass,
-            "<init>", "(Ljava/lang/String;I)V");
-    throwException(env, errnoExceptionClass, ctor3, ctor2, functionName, error);
+    jniThrowErrnoException(env, functionName, error);
 }
 
 static void throwGaiException(JNIEnv* env, const char* functionName, int error) {
@@ -349,6 +348,18 @@
     std::vector<ScopedT*> mScopedBuffers;
 };
 
+static jobject createFileDescriptorIfOpen(JNIEnv* env, int fd) {
+    if (fd == -1) {
+        return NULL;
+    }
+    jobject jifd = jniCreateFileDescriptor(env, fd);
+    if (jifd == NULL) {
+        // OOME prevented allocation of j.i.FileDescriptor instance, close fd to avoid leak.
+        close(fd);
+    }
+    return jifd;
+}
+
 /**
  * Returns a jbyteArray containing the sockaddr_un.sun_path from ss. As per unix(7) sa_len should be
  * the length of ss as returned by getsockname(2), getpeername(2), or accept(2).
@@ -604,6 +615,30 @@
     return true;
 }
 
+#if __has_include(<linux/vm_sockets.h>)
+static bool fillVmSocketAddress(JNIEnv* env, jobject javaVmSocketAddress,
+        const sockaddr_storage& ss) {
+    static jfieldID portFid = env->GetFieldID(
+            JniConstants::GetVmSocketAddressClass(env), "svmPort", "I");
+    static jfieldID cidFid = env->GetFieldID(
+            JniConstants::GetVmSocketAddressClass(env), "svmCid", "I");
+
+    if (javaVmSocketAddress == NULL) {
+        return true;
+    }
+
+    if (ss.ss_family != AF_VSOCK) {
+        return false;
+    }
+
+    const sockaddr_vm& svm = reinterpret_cast<const sockaddr_vm&>(ss);
+    env->SetIntField(javaVmSocketAddress, portFid, svm.svm_port);
+    env->SetIntField(javaVmSocketAddress, cidFid, svm.svm_cid);
+
+    return true;
+}
+#endif
+
 static bool fillSocketAddress(JNIEnv* env, jobject javaSocketAddress, const sockaddr_storage& ss,
         const socklen_t& sa_len) {
     if (javaSocketAddress == NULL) {
@@ -614,6 +649,10 @@
         return fillInetSocketAddress(env, javaSocketAddress, ss);
     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetUnixSocketAddressClass(env))) {
         return fillUnixSocketAddress(env, javaSocketAddress, ss, sa_len);
+#if __has_include(<linux/vm_sockets.h>)
+    } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetVmSocketAddressClass(env))) {
+        return fillVmSocketAddress(env, javaSocketAddress, ss);
+#endif
     }
     jniThrowException(env, "java/lang/UnsupportedOperationException",
             "unsupported SocketAddress subclass");
@@ -719,6 +758,24 @@
     return true;
 }
 
+#if __has_include(<linux/vm_sockets.h>)
+static bool javaVmSocketAddressToSockaddr(
+        JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
+    static jfieldID portFid = env->GetFieldID(
+            JniConstants::GetVmSocketAddressClass(env), "svmPort", "I");
+    static jfieldID cidFid = env->GetFieldID(
+            JniConstants::GetVmSocketAddressClass(env), "svmCid", "I");
+
+    sockaddr_vm& svm = reinterpret_cast<sockaddr_vm&>(ss);
+    svm.svm_family = AF_VSOCK;
+    svm.svm_port = env->GetIntField(javaSocketAddress, portFid);
+    svm.svm_cid = env->GetIntField(javaSocketAddress, cidFid);
+
+    sa_len = sizeof(svm);
+    return true;
+}
+#endif
+
 static bool javaSocketAddressToSockaddr(
         JNIEnv* env, jobject javaSocketAddress, sockaddr_storage& ss, socklen_t& sa_len) {
     if (javaSocketAddress == NULL) {
@@ -734,6 +791,11 @@
         return javaPacketSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
     } else if (env->IsInstanceOf(javaSocketAddress, JniConstants::GetUnixSocketAddressClass(env))) {
         return javaUnixSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
+#if __has_include(<linux/vm_sockets.h>)
+    } else if (env->IsInstanceOf(javaSocketAddress,
+                                 JniConstants::GetVmSocketAddressClass(env))) {
+        return javaVmSocketAddressToSockaddr(env, javaSocketAddress, ss, sa_len);
+#endif
     }
     jniThrowException(env, "java/lang/UnsupportedOperationException",
             "unsupported SocketAddress subclass");
@@ -965,7 +1027,7 @@
         close(clientFd);
         return NULL;
     }
-    return (clientFd != -1) ? jniCreateFileDescriptor(env, clientFd) : NULL;
+    return createFileDescriptorIfOpen(env, clientFd);
 }
 
 static jboolean Linux_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
@@ -1111,7 +1173,9 @@
     jniSetFileDescriptorOfFD(env, javaFd, -1);
 
 #if defined(__BIONIC__)
-    jlong ownerId = jniGetOwnerIdFromFileDescriptor(env, javaFd);
+    static jmethodID getOwnerId = env->GetMethodID(JniConstants::GetFileDescriptorClass(env),
+                                                   "getOwnerId$", "()J");
+    jlong ownerId = env->CallLongMethod(javaFd, getOwnerId);
 
     // 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));
@@ -1193,13 +1257,13 @@
 static jobject Linux_dup(JNIEnv* env, jobject, jobject javaOldFd) {
     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
     int newFd = throwIfMinusOne(env, "dup", TEMP_FAILURE_RETRY(dup(oldFd)));
-    return (newFd != -1) ? jniCreateFileDescriptor(env, newFd) : NULL;
+    return createFileDescriptorIfOpen(env, newFd);
 }
 
 static jobject Linux_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
     int fd = throwIfMinusOne(env, "dup2", TEMP_FAILURE_RETRY(dup2(oldFd, newFd)));
-    return (fd != -1) ? jniCreateFileDescriptor(env, fd) : NULL;
+    return createFileDescriptorIfOpen(env, fd);
 }
 
 static jobjectArray Linux_environ(JNIEnv* env, jobject) {
@@ -1737,16 +1801,12 @@
     return sockaddrToInetAddress(env, reinterpret_cast<sockaddr_storage&>(req.ifr_addr), NULL);
 }
 
-static jint Linux_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
-    // This is complicated because ioctls may return their result by updating their argument
-    // or via their return value, so we need to support both.
+static jint Linux_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
+    // Result is being stored in arg, thus simply returning it
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
-    jint arg = env->GetIntField(javaArg, int32RefValueFid);
-    int rc = throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, cmd, &arg)));
-    if (!env->ExceptionCheck()) {
-        env->SetIntField(javaArg, int32RefValueFid, arg);
-    }
-    return rc;
+    jint arg = 0;
+    throwIfMinusOne(env, "ioctl", TEMP_FAILURE_RETRY(ioctl(fd, cmd, &arg)));
+    return arg;
 }
 
 static jint Linux_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
@@ -1845,7 +1905,7 @@
     }
 
     int fd = throwIfMinusOne(env, "memfd_create", memfd_create(name.c_str(), flags));
-    return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
+    return createFileDescriptorIfOpen(env, fd);
 #else
     UNUSED(env, javaName, flags);
     return NULL;
@@ -1914,7 +1974,7 @@
         return NULL;
     }
     int fd = throwIfMinusOne(env, "open", TEMP_FAILURE_RETRY(open(path.c_str(), flags, mode)));
-    return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
+    return createFileDescriptorIfOpen(env, fd);
 }
 
 static jobjectArray Linux_pipe2(JNIEnv* env, jobject, jint flags __unused) {
@@ -1929,11 +1989,10 @@
     }
     for (int i = 0; i < 2; ++i) {
         ScopedLocalRef<jobject> fd(env, jniCreateFileDescriptor(env, fds[i]));
-        if (fd.get() == NULL) {
-            return NULL;
-        }
         env->SetObjectArrayElement(result, i, fd.get());
-        if (env->ExceptionCheck()) {
+        if (fd.get() == NULL || env->ExceptionCheck()) {
+            close(fds[0]);
+            close(fds[1]);
             return NULL;
         }
     }
@@ -2124,6 +2183,62 @@
     return recvCount;
 }
 
+static jint Linux_recvmsg(JNIEnv* env, jobject, jobject javaFd, jobject structMsghdr, jint flags) {
+    ssize_t rc = -1;
+    ScopedMsghdr scopedMsghdrValue;
+    ScopedByteBufferArray scopedBytesArray(env, true);
+    sockaddr_storage ss = {};
+
+    static jfieldID msgNameFid = env->GetFieldID(JniConstants::GetStructMsghdrClass(env),
+                                                  "msg_name", "Ljava/net/SocketAddress;");
+    if (!msgNameFid) {
+        return -1;
+    }
+
+    // Initialize msghdr with everything from StructCMsghdr except msg_name.
+    if (msghdrJavaToC(env, structMsghdr, scopedMsghdrValue.getObject(),
+                           scopedBytesArray) == false) {
+        return -1;
+    }
+
+    jobject javaSocketAddress = env->GetObjectField(structMsghdr, msgNameFid);
+    if (javaSocketAddress) {
+        // client want to get source address, then set msg_name and msg_namelen.
+        scopedMsghdrValue.setMsgNameAndLen(reinterpret_cast<sockaddr*>(&ss),
+                                              sizeof(sockaddr_in6));
+    }
+
+    rc = NET_FAILURE_RETRY(env, ssize_t, recvmsg, javaFd, \
+                               &scopedMsghdrValue.getObject(), flags);
+
+    if (rc < 0) {
+        return rc;
+    }
+
+    if (javaSocketAddress) {
+        sockaddr_storage* interfaceAddr = NULL;
+        if (!scopedMsghdrValue.isNameLenValid()) {
+            jniThrowException(env, "java/net/SocketException",
+                                   "unknown socket address type");
+                return -1;
+        }
+
+        interfaceAddr = reinterpret_cast<sockaddr_storage*>(scopedMsghdrValue.getObject().msg_name);
+        if (fillSocketAddress(env, javaSocketAddress, *interfaceAddr,
+                scopedMsghdrValue.getObject().msg_namelen) == false) {
+            return -1;
+        }
+    }
+
+    if (msghdrCToJava(env, structMsghdr, scopedMsghdrValue.getObject(),
+                            scopedBytesArray) == false) {
+        return -1;
+    }
+
+    return rc;
+}
+
+
 static void Linux_remove(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
@@ -2180,6 +2295,66 @@
     return result;
 }
 
+static jint Linux_sendmsg(JNIEnv* env, jobject, jobject javaFd, jobject structMsghdr, jint flags) {
+
+    ssize_t rc = -1;
+    ScopedMsghdr scopedMsghdrValue = {};
+    ScopedByteBufferArray scopedBytesArray(env, false);
+    static jfieldID msgNameFid = env->GetFieldID(JniConstants::GetStructMsghdrClass(env),
+                                                  "msg_name",
+                                                  "Ljava/net/SocketAddress;");
+    if (!msgNameFid) {
+        return -1;
+    }
+
+    jobject sockAddrObj = env->GetObjectField(structMsghdr, msgNameFid);
+
+    // Initialize structMsghdr with everything from C msghdr except msg_name.
+    if (msghdrJavaToC(env, structMsghdr, scopedMsghdrValue.getObject(),
+                           scopedBytesArray) == false) {
+        return -1;
+    }
+
+    sockaddr_storage ss = {};
+    socklen_t sa_len = 0;
+    if (sockAddrObj && javaSocketAddressToSockaddr(env, sockAddrObj, ss, sa_len) == false) {
+        return -1;
+    }
+
+    sockaddr* _sa = sa_len ? reinterpret_cast<sockaddr*>(&ss) : NULL;
+    scopedMsghdrValue.setMsgNameAndLen(_sa, sa_len);
+    rc  = NET_FAILURE_RETRY(env, ssize_t, sendmsg, javaFd, \
+                                 &(scopedMsghdrValue.getObject()), flags);
+
+    if (sockAddrObj &&
+        !env->IsInstanceOf(sockAddrObj, JniConstants::GetInetSocketAddressClass(env))) {
+        // non InetSockAddress case, return now;
+        return rc;
+    }
+
+    // InetSocket and IPv6 didn't work, fallback to IPv4.
+    if (rc  == -1 && errno == EAFNOSUPPORT && sa_len && isIPv4MappedAddress(_sa)) {
+        env->ExceptionClear();
+
+        jobject javaInetAddress;
+        jint port = 0;
+        javaInetSocketAddressToInetAddressAndPort(env, sockAddrObj, javaInetAddress, port);
+
+        // Get IPv4 sockaddr.
+        if (!inetAddressToSockaddrVerbatim(env, javaInetAddress, port, ss, sa_len)) {
+            return rc;
+        }
+
+        // Use IPv4 msghdr.msg_name.
+        _sa = sa_len ? reinterpret_cast<sockaddr*>(&ss) : NULL;
+        scopedMsghdrValue.setMsgNameAndLen(_sa, sa_len);
+        rc = NET_FAILURE_RETRY(env, ssize_t, sendmsg, javaFd, \
+                                    &(scopedMsghdrValue.getObject()), flags);
+    }
+
+    return rc;
+}
+
 static jint Linux_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
@@ -2386,7 +2561,7 @@
         protocol = htons(protocol);  // Packet sockets specify the protocol in host byte order.
     }
     int fd = throwIfMinusOne(env, "socket", TEMP_FAILURE_RETRY(socket(domain, type, protocol)));
-    return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
+    return createFileDescriptorIfOpen(env, fd);
 }
 
 static void Linux_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
@@ -2470,7 +2645,7 @@
 
 static jstring Linux_strerror(JNIEnv* env, jobject, jint errnum) {
     char buffer[BUFSIZ];
-    const char* message = jniStrError(errnum, buffer, sizeof(buffer));
+    const char* message = strerror_r(errnum, buffer, sizeof(buffer));
     return env->NewStringUTF(message);
 }
 
@@ -2628,7 +2803,7 @@
     NATIVE_METHOD(Linux, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
     NATIVE_METHOD(Linux, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
     NATIVE_METHOD(Linux, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
-    NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/system/Int32Ref;)I"),
+    NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;I)I"),
     NATIVE_METHOD(Linux, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
     NATIVE_METHOD(Linux, isatty, "(Ljava/io/FileDescriptor;)Z"),
     NATIVE_METHOD(Linux, kill, "(II)V"),
@@ -2659,10 +2834,12 @@
     NATIVE_METHOD(Linux, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
     NATIVE_METHOD(Linux, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
     NATIVE_METHOD(Linux, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
+    NATIVE_METHOD(Linux, recvmsg, "(Ljava/io/FileDescriptor;Landroid/system/StructMsghdr;I)I"),
     NATIVE_METHOD(Linux, remove, "(Ljava/lang/String;)V"),
     NATIVE_METHOD(Linux, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
     NATIVE_METHOD(Linux, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
     NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/system/Int64Ref;J)J"),
+    NATIVE_METHOD(Linux, sendmsg, "(Ljava/io/FileDescriptor;Landroid/system/StructMsghdr;I)I"),
     NATIVE_METHOD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
     NATIVE_METHOD_OVERLOAD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
     NATIVE_METHOD(Linux, setegid, "(I)V"),
diff --git a/luni/src/main/native/libcore_io_Memory.cpp b/luni/src/main/native/libcore_io_Memory.cpp
index a5b7b72..b8a8845 100644
--- a/luni/src/main/native/libcore_io_Memory.cpp
+++ b/luni/src/main/native/libcore_io_Memory.cpp
@@ -22,12 +22,13 @@
 #include <sys/mman.h>
 
 #include <nativehelper/JNIHelp.h>
-#include <nativehelper/ScopedBytes.h>
+
 #include <nativehelper/ScopedPrimitiveArray.h>
 #include <nativehelper/jni_macros.h>
 
 #include "JniConstants.h"
 #include "Portability.h"
+#include "ScopedBytes.h"
 
 // Use packed structures for access to unaligned data on targets with alignment restrictions.
 // The compiler will generate appropriate code to access these structures without
diff --git a/luni/src/main/native/libcore_math_NativeBN.cpp b/luni/src/main/native/libcore_math_NativeBN.cpp
new file mode 100644
index 0000000..dc4b9473
--- /dev/null
+++ b/luni/src/main/native/libcore_math_NativeBN.cpp
@@ -0,0 +1,178 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "NativeBN"
+
+#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);
+  }
+};
+typedef std::unique_ptr<BN_CTX, BN_CTX_Deleter> Unique_BN_CTX;
+
+static BIGNUM* toBigNum(jlong address) {
+  return reinterpret_cast<BIGNUM*>(static_cast<uintptr_t>(address));
+}
+
+// Exception handling: We follow the usual JNI convention of "throwing" an
+// exception if anything goes wrong, and returning junk, typically null.
+// The NativeBN_ routines should only be called from Java, or from code
+// that immediately returns the result to Java, and thus the
+// Java exception should be thrown before we ever see the junk.
+// This null BNs should never become visible, and we do not have to deal with
+// junk (nulls) as input.
+static void throwException(JNIEnv* env) {
+  long error = ERR_get_error();
+  // OpenSSL's error queue may contain multiple errors. Clean up after them.
+  ERR_clear_error();
+
+  if (error == 0) {
+    // An operation failed but did not push to the error queue. Throw a default
+    // exception.
+    jniThrowException(env, "java/lang/ArithmeticException", "Operation failed");
+    return;
+  }
+
+  char message[256];
+  ERR_error_string_n(error, message, sizeof(message));
+  int reason = ERR_GET_REASON(error);
+  if (reason == BN_R_DIV_BY_ZERO) {
+    jniThrowException(env, "java/lang/ArithmeticException", "BigInteger division by zero");
+  } else if (reason == BN_R_NO_INVERSE) {
+    jniThrowException(env, "java/lang/ArithmeticException", "BigInteger not invertible");
+  } else if (reason == ERR_R_MALLOC_FAILURE) {
+    jniThrowOutOfMemoryError(env, message);
+  } else {
+    jniThrowException(env, "java/lang/ArithmeticException", message);
+  }
+}
+
+static jlong NativeBN_BN_new(JNIEnv* env, jclass) {
+  jlong result = static_cast<jlong>(reinterpret_cast<uintptr_t>(BN_new()));
+  if (!result) {
+    throwException(env);
+  }
+  return result;
+}
+
+static void NativeBN_BN_free(JNIEnv*, jclass, jlong a) {
+  // Do nothing on a zero argument.
+  BN_free(toBigNum(a));
+}
+
+static void NativeBN_litEndInts2bn(JNIEnv* env, jclass, jintArray arr, int len, jboolean neg, jlong ret0) {
+  BIGNUM* ret = toBigNum(ret0);
+
+  ScopedIntArrayRO scopedArray(env, arr);
+
+  if (scopedArray.get() == NULL) {
+    return;
+  }
+
+  // We can simply interpret the little-endian integer stream as a
+  // little-endian byte stream and use BN_le2bn.
+  const uint8_t* tmpBytes = reinterpret_cast<const uint8_t *>(scopedArray.get());
+  size_t numBytes = len * sizeof(int);
+
+  if (!BN_le2bn(tmpBytes, numBytes, ret)) {
+    throwException(env);
+  }
+
+  BN_set_negative(ret, neg);
+}
+
+static jintArray NativeBN_bn2litEndInts(JNIEnv* env, jclass, jlong a0) {
+  BIGNUM* a = toBigNum(a0);
+
+  // The number of integers we need is BN_num_bytes(a) / sizeof(int), rounded up
+  int intLen = (BN_num_bytes(a) + sizeof(int) - 1) / sizeof(int);
+
+  // Allocate our result with the JNI boilerplate
+  jintArray result = env->NewIntArray(intLen);
+
+  if (result == NULL) {
+    throwException(env);
+    return NULL;
+  }
+
+  ScopedIntArrayRW ints(env, result);
+
+  unsigned int* uints = reinterpret_cast<unsigned int*>(ints.get());
+  if (uints == NULL) {
+    throwException(env);
+    return NULL;
+  }
+
+  // We can simply interpret a little-endian byte stream as a little-endian integer stream.
+  if (!BN_bn2le_padded(reinterpret_cast<uint8_t*>(uints), intLen * sizeof(int), a)) {
+    throwException(env);
+    return NULL;
+  }
+
+  return result;
+}
+
+static void NativeBN_BN_mul(JNIEnv* env, jclass, jlong r, jlong a, jlong b) {
+  Unique_BN_CTX ctx(BN_CTX_new());
+  BN_CTX* ctxp = ctx.get();
+  if (!ctxp || !BN_mul(toBigNum(r), toBigNum(a), toBigNum(b), ctxp)) {
+    throwException(env);
+  }
+}
+
+static void NativeBN_BN_div(JNIEnv* env, jclass, jlong q, jlong rem, jlong num, jlong divisor) {
+  Unique_BN_CTX ctx(BN_CTX_new());
+  BN_CTX* ctxp = ctx.get();
+  if (!ctxp || !BN_div(toBigNum(q), toBigNum(rem), toBigNum(num), toBigNum(divisor), ctxp)) {
+    throwException(env);
+  }
+}
+
+static void NativeBN_BN_mod_exp(JNIEnv* env, jclass, jlong r, jlong a, jlong p, jlong m) {
+  Unique_BN_CTX ctx(BN_CTX_new());
+  BN_CTX* ctxp = ctx.get();
+  if (!ctxp || !BN_mod_exp(toBigNum(r), toBigNum(a), toBigNum(p), toBigNum(m), ctxp)) {
+    throwException(env);
+  }
+}
+
+static JNINativeMethod gMethods[] = {
+   NATIVE_METHOD(NativeBN, BN_div, "(JJJJ)V"),
+   NATIVE_METHOD(NativeBN, BN_free, "(J)V"),
+   NATIVE_METHOD(NativeBN, BN_mod_exp, "(JJJJ)V"),
+   NATIVE_METHOD(NativeBN, BN_mul, "(JJJ)V"),
+   NATIVE_METHOD(NativeBN, BN_new, "()J"),
+   NATIVE_METHOD(NativeBN, bn2litEndInts, "(J)[I"),
+   NATIVE_METHOD(NativeBN, litEndInts2bn, "([IIZJ)V"),
+};
+void register_libcore_math_NativeBN(JNIEnv* env) {
+    jniRegisterNativeMethods(env, "libcore/math/NativeBN", gMethods, NELEM(gMethods));
+}
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 6df5bdd..fdabcf7 100644
--- a/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
+++ b/luni/src/main/native/org_apache_harmony_xml_ExpatParser.cpp
@@ -31,10 +31,11 @@
 #include <nativehelper/ScopedUtfChars.h>
 #include <nativehelper/jni_macros.h>
 
+#include <unicode/char16ptr.h>
+#include <unicode/ustring.h>
+
 #include "JniConstants.h"
 #include "JniException.h"
-#include "unicode/char16ptr.h"
-#include "unicode/ustring.h"
 
 #define BUCKET_COUNT 128
 
diff --git a/luni/src/module/java/module-info.java b/luni/src/module/java/module-info.java
index 6c2bc12..2d40ebb 100644
--- a/luni/src/module/java/module-info.java
+++ b/luni/src/module/java/module-info.java
@@ -106,7 +106,6 @@
     exports sun.util.resources;
     // non-oj
     exports android.system;
-    exports android.icu.impl;
     exports android.icu.math;
     exports android.icu.text;
     exports android.icu.util;
@@ -120,7 +119,6 @@
     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/annotations/Android.bp b/luni/src/test/annotations/Android.bp
index 437d7c4..ae79505 100644
--- a/luni/src/test/annotations/Android.bp
+++ b/luni/src/test/annotations/Android.bp
@@ -17,6 +17,14 @@
 //
 // Included as a resource by //libcore:core-tests and loaded into its own
 // class loader by libcore.java.lang.reflect.annotations.RetentionPolicyTest.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
 java_library {
     name: "annotations-test",
     visibility: [
diff --git a/luni/src/test/etc/loading-test-jar/README.txt b/luni/src/test/etc/loading-test-jar/README.txt
index c2fb191..9da43c2 100644
--- a/luni/src/test/etc/loading-test-jar/README.txt
+++ b/luni/src/test/etc/loading-test-jar/README.txt
@@ -3,6 +3,6 @@
 files are used for testing the various class loaders.
 
 The Android build system doesn't support dynamically producing
-resources in any sane way. To update the resource, use the script
+resources in any practical way. To update the resource, use the script
 build.sh in this directory, which copies resulting files into the luni
 test resources directory.
diff --git a/luni/src/test/etc/loading-test2-jar/README.txt b/luni/src/test/etc/loading-test2-jar/README.txt
index e1d8bbb..87aaa82 100644
--- a/luni/src/test/etc/loading-test2-jar/README.txt
+++ b/luni/src/test/etc/loading-test2-jar/README.txt
@@ -3,6 +3,6 @@
 files are used for testing the various class loaders.
 
 The Android build system doesn't support dynamically producing
-resources in any sane way. To update the resource, use the script
+resources in any practical way. To update the resource, use the script
 build.sh in this directory, which copies resulting files into the luni
 test resources directory.
diff --git a/luni/src/test/filesystems/Android.bp b/luni/src/test/filesystems/Android.bp
index 83cb936..3910028 100644
--- a/luni/src/test/filesystems/Android.bp
+++ b/luni/src/test/filesystems/Android.bp
@@ -16,6 +16,14 @@
 //
 // Included as a resource by //libcore:core-tests and loaded into its own
 // class loader by libcore.java.nio.file.FileSystemsTest.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
 java_library {
     name: "filesystemstest",
     visibility: [
diff --git a/luni/src/test/java/libcore/android/system/OsTest.java b/luni/src/test/java/libcore/android/system/OsTest.java
old mode 100644
new mode 100755
index 35019db..56487a7
--- a/luni/src/test/java/libcore/android/system/OsTest.java
+++ b/luni/src/test/java/libcore/android/system/OsTest.java
@@ -22,11 +22,14 @@
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.PacketSocketAddress;
+import android.system.StructCmsghdr;
+import android.system.StructMsghdr;
 import android.system.StructRlimit;
 import android.system.StructStat;
 import android.system.StructTimeval;
 import android.system.StructUcred;
 import android.system.UnixSocketAddress;
+import android.system.VmSocketAddress;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -45,23 +48,40 @@
 import java.net.SocketAddress;
 import java.net.SocketException;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Enumeration;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicReference;
-
-import junit.framework.TestCase;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import libcore.io.IoUtils;
 import libcore.testing.io.TestIoUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
 import static android.system.OsConstants.*;
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assume.assumeNoException;
+import static org.junit.Assume.assumeTrue;
 
-public class OsTest extends TestCase {
+@RunWith(JUnit4.class)
+public class OsTest {
 
+    @Test
     public void testIsSocket() throws Exception {
         File f = new File("/dev/null");
         FileInputStream fis = new FileInputStream(f);
@@ -73,6 +93,7 @@
         s.close();
     }
 
+    @Test
     public void testFcntlInt() throws Exception {
         File f = File.createTempFile("OsTest", "tst");
         FileInputStream fis = null;
@@ -87,6 +108,7 @@
         }
     }
 
+    @Test
     public void testFcntlInt_udpSocket() throws Exception {
         final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
         try {
@@ -104,6 +126,7 @@
         }
     }
 
+    @Test
     public void testFcntlInt_invalidCmd() throws Exception {
         final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
         try {
@@ -117,7 +140,8 @@
         }
     }
 
-    public void testFcntlInt_nullFd() throws Exception {
+    @Test
+    public void testFcntlInt_nullFd() {
         try {
             Os.fcntlInt(null, F_SETFL, O_NONBLOCK);
             fail("Expected failure due to null file descriptor");
@@ -126,17 +150,20 @@
         }
     }
 
+    @Test
     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);
     }
 
+    @Test
     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);
     }
 
+    @Test
     public void testUnixDomainSocket_unnamed() throws Exception {
         final FileDescriptor fd = Os.socket(AF_UNIX, SOCK_STREAM, 0);
         // unix(7) says an unbound socket is unnamed.
@@ -170,8 +197,8 @@
                     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");
+                    String s = new String(request, StandardCharsets.UTF_8);
+                    byte[] response = s.toUpperCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8);
                     Os.write(clientFd, response, 0, response.length);
 
                     Os.close(clientFd);
@@ -189,13 +216,13 @@
 
         String string = "hello, world!";
 
-        byte[] request = string.getBytes("UTF-8");
+        byte[] request = string.getBytes(StandardCharsets.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"));
+        assertEquals(string.toUpperCase(Locale.ROOT), new String(response, StandardCharsets.UTF_8));
 
         Os.close(clientFd);
     }
@@ -221,16 +248,17 @@
         checkNoName((UnixSocketAddress) Os.getsockname(fd));
     }
 
-    public void test_strsignal() throws Exception {
+    @Test
+    public void test_strsignal() {
         assertEquals("Killed", Os.strsignal(9));
         assertEquals("Unknown signal -1", Os.strsignal(-1));
     }
 
+    @Test
     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);
+        final byte[] contents = "goodbye, cruel world".getBytes(StandardCharsets.US_ASCII);
         ByteBuffer byteBuffer = ByteBuffer.wrap(contents);
 
         byteBuffer.position(0);
@@ -256,6 +284,7 @@
         fos.close();
     }
 
+    @Test
     public void test_byteBufferPositions_read_pread() throws Exception {
         FileInputStream fis = new FileInputStream(new File("/dev/zero"));
         FileDescriptor fd = fis.getFD();
@@ -284,7 +313,7 @@
         fis.close();
     }
 
-    static void checkByteBufferPositions_sendto_recvfrom(
+    private 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);
@@ -292,29 +321,27 @@
 
         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);
+        final Thread server = new Thread(() -> {
+            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());
+                // 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());
+                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);
-                }
+                Os.close(clientFd);
+            } catch (Exception ex) {
+                throw new RuntimeException(ex);
             }
         });
 
@@ -344,9 +371,8 @@
         Os.close(clientFd);
     }
 
-    interface ExceptionalRunnable {
-
-        public void run() throws Exception;
+    private interface ExceptionalRunnable {
+        void run() throws Exception;
     }
 
     /**
@@ -375,7 +401,7 @@
     }
 
     private static void expectBindException(FileDescriptor socket, SocketAddress addr,
-            Class exClass, Integer expectedErrno) {
+            Class<? extends Exception> exClass, Integer expectedErrno) {
         String msg = String.format("bind(%s, %s)", socket, addr);
         expectException(() -> {
             Os.bind(socket, addr);
@@ -383,7 +409,7 @@
     }
 
     private static void expectConnectException(FileDescriptor socket, SocketAddress addr,
-            Class exClass, Integer expectedErrno) {
+            Class<? extends Exception> exClass, Integer expectedErrno) {
         String msg = String.format("connect(%s, %s)", socket, addr);
         expectException(() -> {
             Os.connect(socket, addr);
@@ -391,13 +417,13 @@
     }
 
     private static void expectSendtoException(FileDescriptor socket, SocketAddress addr,
-            Class exClass, Integer expectedErrno) {
+        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);
+            ErrnoException.class, expectedErrno, msg);
     }
 
     private static void expectBindConnectSendtoSuccess(FileDescriptor socket, String socketDesc,
@@ -422,7 +448,7 @@
 
                     assertEquals(addrISA.getAddress(), socknameISA.getAddress());
                     assertEquals(0, addrISA.getPort());
-                    assertFalse(0 == socknameISA.getPort());
+                    assertNotEquals(0, socknameISA.getPort());
                     addr = socknameISA;
                 }
 
@@ -432,8 +458,9 @@
                 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);
+                expectSendtoException(socket, null, null);
+                expectSendtoException(null, null, EBADF);
+                expectSendtoException(null, addr, EBADF);
 
                 // Expect that connect throws when any of its arguments are null.
                 expectConnectException(null, addr, ErrnoException.class, EBADF);
@@ -512,6 +539,7 @@
         return Os.socket(AF_UNIX, SOCK_DGRAM, 0);
     }
 
+    @Test
     public void testCrossFamilyBindConnectSendto() throws Exception {
         SocketAddress addrIpv4 = new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0);
         SocketAddress addrIpv6 = new InetSocketAddress(InetAddress.getByName("::1"), 0);
@@ -537,6 +565,7 @@
         expectBindConnectSendtoSuccess(makeUnixSocket(), "unix", addrUnix);
     }
 
+    @Test
     public void testUnknownSocketAddressSubclass() throws Exception {
         class MySocketAddress extends SocketAddress {
 
@@ -575,6 +604,7 @@
         }
     }
 
+    @Test
     public void test_NetlinkSocket() throws Exception {
         FileDescriptor nlSocket = Os.socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
         try {
@@ -597,8 +627,10 @@
     // This test is excluded from CTS via the knownfailures.txt because it requires extra
     // permissions not available in CTS. To run it you have to use an -eng build and use a tool like
     // vogar that runs the Android runtime as a privileged user.
+    @Test
     public void test_PacketSocketAddress() throws Exception {
         NetworkInterface lo = NetworkInterface.getByName("lo");
+        assertNotNull(lo);
         FileDescriptor fd = Os.socket(AF_PACKET, SOCK_DGRAM, ETH_P_IPV6);
         PacketSocketAddress addr =
                 new PacketSocketAddress(ETH_P_IPV6, lo.getIndex(), null /* sll_addr */);
@@ -612,6 +644,7 @@
 
         // 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
+        assertNotNull(bound.sll_addr);
         assertEquals(6, bound.sll_addr.length);
         for (int i = 0; i < 6; i++) {
             assertEquals(0, bound.sll_addr[i]);
@@ -661,18 +694,101 @@
         Os.close(fd);
     }
 
+    @Test
+    public void test_VmSocketAddress() {
+        try {
+            final VmSocketAddress addr = new VmSocketAddress(111, 222);
+            assertEquals(111, addr.getSvmPort());
+            assertEquals(222, addr.getSvmCid());
+        } catch (UnsupportedOperationException ignore) {
+            assumeNoException(ignore);  // the platform does not support virtio-vsock
+        }
+    }
+
+    private static Thread createVmSocketEchoServer(final FileDescriptor serverFd) {
+        return new Thread(new Runnable() {
+            public void run() {
+                final VmSocketAddress peer =
+                    new VmSocketAddress(VMADDR_PORT_ANY, VMADDR_CID_ANY);
+
+                try {
+                    final FileDescriptor clientFd = Os.accept(serverFd, peer);
+                    try {
+                        final byte[] requestBuf = new byte[256];
+                        final int len = Os.read(clientFd, requestBuf, 0, requestBuf.length);
+                        final String request =
+                            new String(requestBuf, 0, len, StandardCharsets.UTF_8);
+                        final byte[] responseBuf =
+                            request.toUpperCase(Locale.ROOT).getBytes(StandardCharsets.UTF_8);
+                        Os.write(clientFd, responseBuf, 0, responseBuf.length);
+                    } finally {
+                        Os.close(clientFd);
+                    }
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+    }
+
+    @Test
+    public void test_VmSocket() throws Exception {
+        try {
+            final VmSocketAddress serverAddr = new VmSocketAddress(12345, VMADDR_CID_LOCAL);
+
+            final FileDescriptor serverFd = Os.socket(AF_VSOCK, SOCK_STREAM, 0);
+
+            try {
+                Os.bind(serverFd, serverAddr);
+                Os.listen(serverFd, 3);
+
+                final Thread server = createVmSocketEchoServer(serverFd);
+                server.start();
+
+                final FileDescriptor clientFd = Os.socket(AF_VSOCK, SOCK_STREAM, 0);
+                try {
+                    Os.connect(clientFd, serverAddr);
+
+                    final String request = "hello, world!";
+                    final byte[] requestBuf = request.getBytes(StandardCharsets.UTF_8);
+
+                    assertEquals(requestBuf.length,
+                                 Os.write(clientFd, requestBuf, 0, requestBuf.length));
+
+                    final byte[] responseBuf = new byte[requestBuf.length];
+                    assertEquals(responseBuf.length,
+                                 Os.read(clientFd, responseBuf, 0, responseBuf.length));
+
+                    final String response = new String(responseBuf, StandardCharsets.UTF_8);
+
+                    assertEquals(request.toUpperCase(Locale.ROOT), response);
+                } finally {
+                    Os.close(clientFd);
+                }
+            } finally {
+                Os.close(serverFd);
+            }
+        } catch (UnsupportedOperationException ignore) {
+            assumeNoException(ignore);  // the platform does not support virtio-vsock
+        } catch (ErrnoException e) {
+            // the platform does not support vsock
+            assumeTrue(e.errno != EAFNOSUPPORT && e.errno != EACCES);
+            throw e;
+        }
+    }
+
     private static byte[] getIPv6AddressBytesAtOffset(byte[] packet, int offsetIndex) {
         byte[] address = new byte[16];
-        for (int i = 0; i < 16; i++) {
-            address[i] = packet[i + offsetIndex];
-        }
+        System.arraycopy(packet, offsetIndex, address, 0, 16);
         return address;
     }
 
+    @Test
     public void test_byteBufferPositions_sendto_recvfrom_af_inet() throws Exception {
         checkByteBufferPositions_sendto_recvfrom(AF_INET, InetAddress.getByName("127.0.0.1"));
     }
 
+    @Test
     public void test_byteBufferPositions_sendto_recvfrom_af_inet6() throws Exception {
         checkByteBufferPositions_sendto_recvfrom(AF_INET6, InetAddress.getByName("::1"));
     }
@@ -685,7 +801,8 @@
 
         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");
+        byte[] msg = ("Hello, I'm going to a socket address: " + to.toString()).getBytes(
+            StandardCharsets.UTF_8);
         int len = msg.length;
 
         assertEquals(len, Os.sendto(sendFd, msg, 0, len, 0, to));
@@ -695,14 +812,273 @@
         assertEquals(loopback, from.getAddress());
     }
 
+    @Test
     public void test_sendtoSocketAddress_af_inet() throws Exception {
         checkSendToSocketAddress(AF_INET, InetAddress.getByName("127.0.0.1"));
     }
 
+    @Test
     public void test_sendtoSocketAddress_af_inet6() throws Exception {
         checkSendToSocketAddress(AF_INET6, InetAddress.getByName("::1"));
     }
 
+    /*
+     * Test case for sendmsg with/without GSO in loopback iface,
+     * recvmsg/gro would not happen since in loopback
+     */
+    private void checkSendmsgSocketAddress(int family, InetSocketAddress loopbackAddr,
+            StructMsghdr sendmsgHdr, StructMsghdr recvmsgHdr, int sendSize) throws Exception {
+
+        FileDescriptor sendFd = Os.socket(family, SOCK_DGRAM, 0);
+        FileDescriptor recvFd = Os.socket(family, SOCK_DGRAM, 0);
+        int rc = 0;
+
+        //recvmsg cleanup data
+        if (loopbackAddr.getAddress() instanceof Inet6Address) {
+            Os.bind(recvFd, Inet6Address.ANY, loopbackAddr.getPort());
+        } else {
+            Os.bind(recvFd, Inet4Address.ANY, loopbackAddr.getPort());
+        }
+
+        StructTimeval tv = StructTimeval.fromMillis(20);
+        Os.setsockoptTimeval(recvFd, SOL_SOCKET, SO_RCVTIMEO, tv);
+        Os.setsockoptInt(recvFd, IPPROTO_UDP, UDP_GRO, 1); //enable GRO
+        Os.setsockoptInt(recvFd, SOL_SOCKET, SO_RCVBUF, 1024 * 1024);
+
+        try {
+            assertEquals(sendSize, Os.sendmsg(sendFd, sendmsgHdr, 0));
+            rc = 0;
+            do {
+                int temp_rc = Os.recvmsg(recvFd, recvmsgHdr, OsConstants.MSG_TRUNC);
+                rc += temp_rc;
+                if (recvmsgHdr.msg_control != null && recvmsgHdr.msg_control.length > 0) {
+                    byte[] sendCmsgByte = sendmsgHdr.msg_control[0].cmsg_data;
+                    byte[] recvCmsgByte = recvmsgHdr.msg_control[0].cmsg_data;
+                    /* Note:
+                     * GSO: is set with Short(2Byte) values;
+                     * GRO: IP stack return with Int(4Bytes) value;
+                     */
+                    assertEquals(
+                            ByteBuffer.wrap(sendCmsgByte).order(
+                                    ByteOrder.nativeOrder()).getShort(0),
+                            ByteBuffer.wrap(recvCmsgByte).order(
+                                    ByteOrder.nativeOrder()).getInt(0));
+                }
+
+                recvmsgHdr = new StructMsghdr(recvmsgHdr.msg_name, recvmsgHdr.msg_iov,
+                                              null,
+                                              recvmsgHdr.msg_flags);
+            }while(rc < sendSize);
+        } finally {
+            Os.close(sendFd);
+            Os.close(recvFd);
+        }
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_4K() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        //sendmsg/recvmsg with 1*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[1];
+        ByteBuffer[] bufferArrayRecv = new ByteBuffer[1];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArrayRecv[0] = ByteBuffer.allocate(4096);
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr,
+                                                   bufferArray,
+                                                   cmsg, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(new InetSocketAddress(),
+                                                   bufferArrayRecv,
+                                                   null, 0);
+
+        checkSendmsgSocketAddress(AF_INET, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet6_4K() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("::1"), 10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        //sendmsg/recvmsg with 1*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[1];
+        ByteBuffer[] bufferArrayRecv = new ByteBuffer[1];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArrayRecv[0] = ByteBuffer.allocate(4096);
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr,
+                                                   bufferArray,
+                                                   cmsg, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(new InetSocketAddress(),
+                                                   bufferArrayRecv,
+                                                   null, 0);
+
+        checkSendmsgSocketAddress(AF_INET6, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet6_4K_directBuffer() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                               10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        //sendmsg/recvmsg with 1*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[1];
+        ByteBuffer[] bufferArrayRecv = new ByteBuffer[1];
+        bufferArray[0] = ByteBuffer.allocateDirect(4096); // DirectBuffer
+        bufferArrayRecv[0] = ByteBuffer.allocateDirect(4096); // DirectBuffer
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr,
+                                                   bufferArray,
+                                                   cmsg, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(new InetSocketAddress(),
+                                                   bufferArrayRecv,
+                                                   null, 0);
+
+        checkSendmsgSocketAddress(AF_INET6, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_16K_recvparts() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                               10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        //sendmsg with 4*4K ByteBuffer, recv with 1*4K ByteBuffer(already with MSG_TRUNC option)
+        ByteBuffer[] bufferArray = new ByteBuffer[4];
+        ByteBuffer[] bufferArrayRecv = new ByteBuffer[1];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArray[1] = ByteBuffer.allocate(4096);
+        bufferArray[2] = ByteBuffer.allocate(4096);
+        bufferArray[3] = ByteBuffer.allocate(4096);
+        bufferArrayRecv[0] = ByteBuffer.allocate(4096); //receive only part of data
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr,
+                                                   bufferArray,
+                                                   cmsg, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(new InetSocketAddress(),
+                                                   bufferArrayRecv,
+                                                   null, 0);
+
+        checkSendmsgSocketAddress(AF_INET, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096 * 4);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_16K_reciveall() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                               10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        // Create sendmsg/recvmsg with 4*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[4];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArray[1] = ByteBuffer.allocate(4096);
+        bufferArray[2] = ByteBuffer.allocate(4096);
+        bufferArray[3] = ByteBuffer.allocate(4096);
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr, bufferArray, cmsg, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(new InetSocketAddress(), bufferArray, null, 0);
+
+        checkSendmsgSocketAddress(AF_INET, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096 * 4);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_16K_receiveall_without_recv_msgname() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                               10234);
+        StructCmsghdr[] cmsg = new StructCmsghdr[1];
+        cmsg[0] = new StructCmsghdr(SOL_UDP, UDP_SEGMENT, (short) 1400);
+
+        // Create sendmsg/recvmsg with 4*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[4];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArray[1] = ByteBuffer.allocate(4096);
+        bufferArray[2] = ByteBuffer.allocate(4096);
+        bufferArray[3] = ByteBuffer.allocate(4096);
+
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr, bufferArray, cmsg, 0);
+        // msg_name is unnecessary.
+        StructMsghdr recvmsgHdr = new StructMsghdr(null, bufferArray, null, 0);
+
+        checkSendmsgSocketAddress(AF_INET, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096 * 4);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_16K_without_send_msgcontrl() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        InetSocketAddress loopbackAddr = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                               10234);
+
+        // Create sendmsg/recvmsg with 4*4K ByteBuffer
+        ByteBuffer[] bufferArray = new ByteBuffer[4];
+        bufferArray[0] = ByteBuffer.allocate(4096);
+        bufferArray[1] = ByteBuffer.allocate(4096);
+        bufferArray[2] = ByteBuffer.allocate(4096);
+        bufferArray[3] = ByteBuffer.allocate(4096);
+
+        // GSO will not happen without msgcontrol.
+        StructMsghdr sendmsgHdr = new StructMsghdr(loopbackAddr, bufferArray, null, 0);
+        StructMsghdr recvmsgHdr = new StructMsghdr(null, bufferArray, null, 0);
+
+        checkSendmsgSocketAddress(AF_INET, loopbackAddr, sendmsgHdr, recvmsgHdr, 4096 * 4);
+    }
+
+    @Test
+    public void test_sendmsg_af_inet_abnormal() throws Exception {
+        //sendmsg socket set
+        InetSocketAddress address = new InetSocketAddress(InetAddress.getByName("127.0.0.1"),
+                                                          10234);
+        FileDescriptor sendFd = Os.socket(AF_INET, SOCK_DGRAM, 0);
+
+        ByteBuffer[] bufferArray = new ByteBuffer[1];
+        bufferArray[0] = ByteBuffer.allocate(8192);
+
+        try {
+            StructMsghdr msgHdr = new StructMsghdr(address, null, null, 0);
+            Os.sendmsg(sendFd, msgHdr, 0);
+            fail("Expected NullPointerException due to invalid StructMsghdr.msg_iov(NULL)");
+        } catch (NullPointerException expected) {
+        }
+
+        try {
+            StructMsghdr msgHdr = new StructMsghdr(null, bufferArray, null, 0);
+            Os.sendmsg(sendFd, msgHdr, 0);
+            fail("Expected ErrnoException due to invalid StructMsghdr.msg_name(NULL)");
+        } catch (ErrnoException expected) {
+            assertEquals("Expected EDESTADDRREQ binding IPv4 socket to ::", EDESTADDRREQ,
+                    expected.errno);
+        }
+
+    }
+
+    @Test
     public void test_socketFamilies() throws Exception {
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
         Os.bind(fd, InetAddress.getByName("::"), 0);
@@ -727,11 +1103,6 @@
         }
     }
 
-    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;
@@ -753,12 +1124,13 @@
         assertEquals(received[5], (byte) (icmpId & 0xff));
 
         received = Arrays.copyOf(received, len);
-        received[0] = (byte) type;
+        received[0] = type;
         received[2] = received[3] = 0;  // Checksum.
         received[4] = received[5] = 0;  // ICMP ID.
         assertArrayEquals(packet, received);
     }
 
+    @Test
     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;
@@ -777,6 +1149,7 @@
         checkSocketPing(fd, ipv4Loopback, packet, ICMP_ECHO, ICMP_ECHOREPLY, false);
     }
 
+    @Test
     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
@@ -794,6 +1167,7 @@
         }
     }
 
+    @Test
     public void test_unlink() throws Exception {
         File f = File.createTempFile("OsTest", "tst");
         assertTrue(f.exists());
@@ -809,6 +1183,7 @@
     }
 
     // b/27294715
+    @Test
     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);
@@ -816,22 +1191,20 @@
         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() {
+        final AtomicReference<Exception> killerThreadException = new AtomicReference<>(
+            null);
+        final Thread killer = new Thread(() -> {
+            try {
+                Thread.sleep(2000);
                 try {
-                    Thread.sleep(2000);
-                    try {
-                        Os.shutdown(serverFd, SHUT_RDWR);
-                    } catch (ErrnoException expected) {
-                        if (OsConstants.ENOTCONN != expected.errno) {
-                            killerThreadException.set(expected);
-                        }
+                    Os.shutdown(serverFd, SHUT_RDWR);
+                } catch (ErrnoException expected) {
+                    if (OsConstants.ENOTCONN != expected.errno) {
+                        killerThreadException.set(expected);
                     }
-                } catch (Exception ex) {
-                    killerThreadException.set(ex);
                 }
+            } catch (Exception ex) {
+                killerThreadException.set(ex);
             }
         });
         killer.start();
@@ -839,13 +1212,14 @@
         ByteBuffer buffer = ByteBuffer.allocate(16);
         InetSocketAddress srcAddress = new InetSocketAddress();
         int received = Os.recvfrom(serverFd, buffer, 0, srcAddress);
-        assertTrue(received == 0);
+        assertEquals(0, received);
         Os.close(serverFd);
 
         killer.join();
         assertNull(killerThreadException.get());
     }
 
+    @Test
     public void test_xattr() throws Exception {
         final String NAME_TEST = "user.meow";
 
@@ -897,6 +1271,7 @@
         }
     }
 
+    @Test
     public void test_xattr_NPE() throws Exception {
         File file = File.createTempFile("xattr", "test");
         final String path = file.getAbsolutePath();
@@ -952,7 +1327,8 @@
         }
     }
 
-    public void test_xattr_Errno() throws Exception {
+    @Test
+    public void test_xattr_Errno() {
         final String NAME_TEST = "user.meow";
         final byte[] VALUE_CAKE = "cake cake cake".getBytes(StandardCharsets.UTF_8);
 
@@ -1014,6 +1390,7 @@
         }
     }
 
+    @Test
     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
@@ -1044,10 +1421,57 @@
         }
     }
 
+    private int[] getKernelVersion() {
+        // Example:
+        // 4.9.29-g958411d --> 4.9
+        String release = Os.uname().release;
+        Matcher m = Pattern.compile("^(\\d+)\\.(\\d+)").matcher(release);
+        assertTrue("No pattern in release string: " + release, m.find());
+        return new int[]{ Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)) };
+    }
+
+    private boolean kernelIsAtLeast(int major, int minor) {
+        int[] version = getKernelVersion();
+        return version[0] > major || (version[0] == major && version[1] >= minor);
+    }
+
+    @Test
+    public void test_socket_udpGro_setAndGet() throws Exception {
+        // UDP GRO not required to be enabled on kernels prior to 5.4
+        assumeTrue(kernelIsAtLeast(5, 4));
+
+        final FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, 0);
+        try {
+            final int setValue = 1;
+            Os.setsockoptInt(fd, IPPROTO_UDP, UDP_GRO, setValue);
+            // getsockopt(IPPROTO_UDP, UDP_GRO) is not implemented.
+        } finally {
+            Os.close(fd);
+        }
+    }
+
+    @Test
+    public void test_socket_udpGso_set() throws Exception {
+        // UDP GSO not required to be enabled on kernels prior to 4.19.
+        assumeTrue(kernelIsAtLeast(4, 19));
+
+        final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
+        try {
+            assertEquals(0, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT));
+
+            final int setValue = 1452;
+            Os.setsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT, setValue);
+            assertEquals(setValue, Os.getsockoptInt(fd, IPPROTO_UDP, UDP_SEGMENT));
+        } finally {
+            Os.close(fd);
+        }
+    }
+
     /**
      * Tests that TCP_USER_TIMEOUT can be set on a TCP socket, but doesn't test
      * that it behaves as expected.
      */
+    @Test
     public void test_socket_tcpUserTimeout_setAndGet() throws Exception {
         final FileDescriptor fd = Os.socket(AF_INET, SOCK_STREAM, 0);
         try {
@@ -1068,6 +1492,7 @@
         }
     }
 
+    @Test
     public void test_socket_tcpUserTimeout_doesNotWorkOnDatagramSocket() throws Exception {
         final FileDescriptor fd = Os.socket(AF_INET, SOCK_DGRAM, 0);
         try {
@@ -1081,6 +1506,7 @@
         }
     }
 
+    @Test
     public void test_socket_sockoptTimeval_readWrite() throws Exception {
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
         try {
@@ -1102,9 +1528,13 @@
         }
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_effective() throws Exception {
-        int timeoutValueMillis = 50;
-        int allowedTimeoutMillis = 500;
+        // b/176104885 Older devices can return a few ms early, add a tolerance for them
+        long timeoutTolerance = kernelIsAtLeast(3, 18) ? 0 : 10;
+
+        int timeoutValueMillis = 250;
+        int allowedTimeoutMillis = 3000;
 
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
         try {
@@ -1116,20 +1546,27 @@
             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);
+            long durationMillis = Duration.ofNanos(System.nanoTime() - startTime).toMillis();
+            assertTrue("Timeout of " + timeoutValueMillis + "ms returned after "
+                    + durationMillis +"ms",
+                durationMillis >= timeoutValueMillis - timeoutTolerance);
+            assertTrue("Timeout of " + timeoutValueMillis + "ms failed to return within "
+                    + allowedTimeoutMillis  + "ms",
+                durationMillis < allowedTimeoutMillis);
         } finally {
             Os.close(fd);
         }
     }
 
-    public void test_socket_setSockoptTimeval_nullFd() throws Exception {
+    @Test
+    public void test_socket_setSockoptTimeval_nullFd() {
         StructTimeval tv = StructTimeval.fromMillis(500);
         expectException(
                 () -> Os.setsockoptTimeval(null, SOL_SOCKET, SO_RCVTIMEO, tv),
                 ErrnoException.class, EBADF, "setsockoptTimeval(null, ...)");
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_fileFd() throws Exception {
         File testFile = createTempFile("test_socket_setSockoptTimeval_invalidFd", "");
         try (FileInputStream fis = new FileInputStream(testFile)) {
@@ -1142,6 +1579,7 @@
         }
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_badFd() throws Exception {
         StructTimeval tv = StructTimeval.fromMillis(500);
         FileDescriptor invalidFd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1152,6 +1590,7 @@
                 ErrnoException.class, EBADF, "setsockoptTimeval(<closed fd>, ...)");
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_invalidLevel() throws Exception {
         StructTimeval tv = StructTimeval.fromMillis(500);
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1165,6 +1604,7 @@
         }
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_invalidOpt() throws Exception {
         StructTimeval tv = StructTimeval.fromMillis(500);
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
@@ -1178,6 +1618,7 @@
         }
     }
 
+    @Test
     public void test_socket_setSockoptTimeval_nullTimeVal() throws Exception {
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
         try {
@@ -1189,6 +1630,7 @@
         }
     }
 
+    @Test
     public void test_socket_getSockoptTimeval_invalidOption() throws Exception {
         FileDescriptor fd = Os.socket(AF_INET6, SOCK_STREAM, 0);
         try {
@@ -1201,19 +1643,22 @@
         }
     }
 
+    @Test
     public void test_if_nametoindex_if_indextoname() throws Exception {
-        List<NetworkInterface> nis = Collections.list(NetworkInterface.getNetworkInterfaces());
+        Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
+        assertNotNull(networkInterfaces);
+        List<NetworkInterface> nis = Collections.list(networkInterfaces);
 
         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(Os.if_indextoname(index), name);
         }
 
         assertEquals(0, Os.if_nametoindex("this-interface-does-not-exist"));
-        assertEquals(null, Os.if_indextoname(-1000));
+        assertNull(Os.if_indextoname(-1000));
 
         try {
             Os.if_nametoindex(null);
@@ -1231,6 +1676,7 @@
         }
     }
 
+    @Test
     public void test_readlink() throws Exception {
         File path = new File(TestIoUtils.createTemporaryDirectory("test_readlink"), "symlink");
 
@@ -1241,17 +1687,18 @@
         // 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 = "";
+        StringBuilder xs = new StringBuilder();
         for (int i = 0; i < size - 1; ++i) {
-            xs += "x";
+            xs.append("x");
         }
 
-        Os.symlink(xs, path.getPath());
+        Os.symlink(xs.toString(), path.getPath());
 
-        assertEquals(xs, Os.readlink(path.getPath()));
+        assertEquals(xs.toString(), Os.readlink(path.getPath()));
     }
 
     // Address should be correctly set for empty packets. http://b/33481605
+    @Test
     public void test_recvfrom_EmptyPacket() throws Exception {
         try (DatagramSocket ds = new DatagramSocket();
              DatagramSocket srcSock = new DatagramSocket()) {
@@ -1267,6 +1714,7 @@
         }
     }
 
+    @Test
     public void test_fstat_times() throws Exception {
         File file = File.createTempFile("OsTest", "fstattest");
         FileOutputStream fos = new FileOutputStream(file);
@@ -1285,6 +1733,7 @@
         assertEquals(0, structStat1.st_atim.compareTo(structStat2.st_atim));
     }
 
+    @Test
     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
@@ -1295,7 +1744,8 @@
     }
 
     // http://b/65051835
-    public void test_pipe2_errno() throws Exception {
+    @Test
+    public void test_pipe2_errno() {
         try {
             // flag=-1 is not a valid value for pip2, will EINVAL
             Os.pipe2(-1);
@@ -1305,7 +1755,8 @@
     }
 
     // http://b/65051835
-    public void test_sendfile_errno() throws Exception {
+    @Test
+    public void test_sendfile_errno() {
         try {
             // FileDescriptor.out is not open for input, will cause EBADF
             Int64Ref offset = new Int64Ref(10);
@@ -1315,6 +1766,7 @@
         }
     }
 
+    @Test
     public void test_sendfile_null() throws Exception {
         File in = createTempFile("test_sendfile_null", "Hello, world!");
         try {
@@ -1325,6 +1777,7 @@
         }
     }
 
+    @Test
     public void test_sendfile_offset() throws Exception {
         File in = createTempFile("test_sendfile_offset", "Hello, world!");
         try {
@@ -1364,6 +1817,7 @@
         return f;
     }
 
+    @Test
     public void test_odirect() throws Exception {
         File testFile = createTempFile("test_odirect", "");
         try {
@@ -1380,6 +1834,7 @@
         }
     }
 
+    @Test
     public void test_splice() throws Exception {
         FileDescriptor[] pipe = Os.pipe2(0);
         File in = createTempFile("splice1", "foobar");
@@ -1412,6 +1867,7 @@
         Os.close(pipe[1]);
     }
 
+    @Test
     public void test_splice_errors() throws Exception {
         File in = createTempFile("splice3", "");
         File out = createTempFile("splice4", "");
@@ -1452,6 +1908,7 @@
         Os.close(pipe[1]);
     }
 
+    @Test
     public void testCloseNullFileDescriptor() throws Exception {
         try {
             Os.close(null);
@@ -1460,6 +1917,7 @@
         }
     }
 
+    @Test
     public void testSocketpairNullFileDescriptor1() throws Exception {
         try {
             Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, new FileDescriptor());
@@ -1468,6 +1926,7 @@
         }
     }
 
+    @Test
     public void testSocketpairNullFileDescriptor2() throws Exception {
         try {
             Os.socketpair(AF_UNIX, SOCK_STREAM, 0, new FileDescriptor(), null);
@@ -1476,6 +1935,7 @@
         }
     }
 
+    @Test
     public void testSocketpairNullFileDescriptorBoth() throws Exception {
         try {
             Os.socketpair(AF_UNIX, SOCK_STREAM, 0, null, null);
@@ -1484,30 +1944,35 @@
         }
     }
 
+    @Test
     public void testInetPtonIpv4() {
         String srcAddress = "127.0.0.1";
         InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
         assertEquals(srcAddress, inetAddress.getHostAddress());
     }
 
+    @Test
     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());
     }
 
+    @Test
     public void testInetPtonInvalidFamily() {
         String srcAddress = "127.0.0.1";
         InetAddress inetAddress = Os.inet_pton(AF_UNIX, srcAddress);
         assertNull(inetAddress);
     }
 
+    @Test
     public void testInetPtonWrongFamily() {
         String srcAddress = "127.0.0.1";
         InetAddress inetAddress = Os.inet_pton(AF_INET6, srcAddress);
         assertNull(inetAddress);
     }
 
+    @Test
     public void testInetPtonInvalidData() {
         String srcAddress = "10.1";
         InetAddress inetAddress = Os.inet_pton(AF_INET, srcAddress);
@@ -1517,6 +1982,7 @@
     /**
      * Verifies the {@link OsConstants#MAP_ANONYMOUS}.
      */
+    @Test
     public void testMapAnonymous() throws Exception {
         final long size = 4096;
         final long address = Os.mmap(0, size, PROT_READ,
@@ -1525,6 +1991,7 @@
         Os.munmap(address, size);
     }
 
+    @Test
     public void testMemfdCreate() throws Exception {
         FileDescriptor fd = null;
         try {
@@ -1553,6 +2020,7 @@
         }
     }
 
+    @Test
     public void testMemfdCreateFlags() throws Exception {
         FileDescriptor fd = null;
 
@@ -1562,8 +2030,8 @@
             assertNotNull(fd);
             assertTrue(fd.valid());
             int flags = Os.fcntlVoid(fd, F_GETFD);
-            assertTrue("Expected flags to not include " + FD_CLOEXEC + ", actual value: " + flags,
-                    0 == (flags & FD_CLOEXEC));
+            assertEquals("Expected flags to not include " + FD_CLOEXEC + ", actual value: " + flags,
+                0, (flags & FD_CLOEXEC));
         } finally {
             if (fd != null) {
                 Os.close(fd);
@@ -1585,7 +2053,8 @@
         }
     }
 
-    public void testMemfdCreateErrno() throws Exception {
+    @Test
+    public void testMemfdCreateErrno() {
         expectException(() -> Os.memfd_create(null, 0), NullPointerException.class, null,
                 "memfd_create(null, 0)");
 
diff --git a/luni/src/test/java/libcore/android/system/StructTimevalTest.java b/luni/src/test/java/libcore/android/system/StructTimevalTest.java
index f427980..b5ca9e5 100644
--- a/luni/src/test/java/libcore/android/system/StructTimevalTest.java
+++ b/luni/src/test/java/libcore/android/system/StructTimevalTest.java
@@ -42,6 +42,8 @@
         // An array of { testMillisValue, expectedSeconds, expectedMicros }
         return new Object[][] {
                 { 0L, 0L, 0L },
+                { 1000L, 1L, 0L },
+                { -1000L, -1L, 0L },
 
                 // +ve and -ve cases close to zero seconds.
                 { 23L, 0L, 23L * US_PER_MS /* 23000 */ },
diff --git a/luni/src/test/java/libcore/dalvik/system/ClassLoaderTestSupport.java b/luni/src/test/java/libcore/dalvik/system/ClassLoaderTestSupport.java
index 4adb4b6..27f5d7c 100644
--- a/luni/src/test/java/libcore/dalvik/system/ClassLoaderTestSupport.java
+++ b/luni/src/test/java/libcore/dalvik/system/ClassLoaderTestSupport.java
@@ -58,15 +58,17 @@
             return;
         }
 
-        File[] files = dir.listFiles();
-        for (File file : files) {
-            if (file.isDirectory()) {
-                cleanUpDir(file);
-            } else {
-                assertTrue(file.delete());
+        // The runtime may create files in the background. Loop until we remove all such files.
+        while (!dir.delete()) {
+            File[] files = dir.listFiles();
+            for (File file : files) {
+                if (file.isDirectory()) {
+                    cleanUpDir(file);
+                } else {
+                    assertTrue(file.delete());
+                }
             }
         }
-        assertTrue(dir.delete());
     }
 
     /**
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java
new file mode 100644
index 0000000..d611807
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/DateFormatTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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.highmemorytest.java.text;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Tests {@link DateFormat} but runs in a separate java package because loading data in all locales
+ * creates a lot of garbage / permanent heap growth in ICU4J and causes gcstress test failing
+ * in ART test environment. See http://b/161420453. No known users/apps load all locale data like
+ * this test.
+ */
+@RunWith(Parameterized.class)
+public class DateFormatTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    // 1 January 2022 00:00:00 GMT+00:00
+    private static final Date TEST_DATE = new Date(1640995200000L);
+
+    /**
+     * Test {@link DateFormat#format(Date)} does not crash on available locales.
+     */
+    @Test
+    public void test_format_allLocales() {
+        for (int formatStyle = DateFormat.FULL; formatStyle <= DateFormat.SHORT;
+                formatStyle++) {
+            try {
+                assertNonEmpty(DateFormat.getDateInstance(formatStyle, locale).format(TEST_DATE));
+                assertNonEmpty(DateFormat.getTimeInstance(formatStyle, locale).format(TEST_DATE));
+                assertNonEmpty(DateFormat.getDateTimeInstance(formatStyle, formatStyle, locale)
+                        .format(TEST_DATE));
+            } catch (RuntimeException cause) {
+                throw new RuntimeException("locale:" + locale +
+                        " formatStyle:" + formatStyle, cause);
+            }
+        }
+    }
+
+    /**
+     * Test {@link SimpleDateFormat#toPattern()} contains only supported symbols.
+     */
+    @Test
+    public void test_toPattern_allLocales() {
+        for (int formatStyle = DateFormat.FULL; formatStyle <= DateFormat.SHORT;
+                formatStyle++) {
+            try {
+                assertSupportedSymbols(DateFormat.getDateInstance(formatStyle, locale), locale);
+                assertSupportedSymbols(DateFormat.getTimeInstance(formatStyle, locale), locale);
+                assertSupportedSymbols(DateFormat.getDateTimeInstance(
+                        formatStyle, formatStyle, locale), locale);
+            } catch (RuntimeException cause) {
+                throw new RuntimeException("locale:" + locale +
+                        " formatStyle:" + formatStyle, cause);
+            }
+        }
+    }
+
+    private static final Set<Character> SUPPORTED_SYMBOLS = "GyYMLwWDdFEuaHkKhmsSzZXLc".chars()
+            .mapToObj(c -> (char)c)
+            .collect(Collectors.toSet());
+
+    private static void assertSupportedSymbols(DateFormat dateFormat, Locale locale) {
+        SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormat;
+        String pattern = simpleDateFormat.toPattern();
+        // The string in the quotation is not interpreted.
+        boolean inQuotation = false;
+        for (int i = 0; i < pattern.length(); i++) {
+            char curr = pattern.charAt(i);
+            if (curr == '\'') {
+                inQuotation = !inQuotation;
+                continue;
+            }
+            if (inQuotation) {
+                continue;
+            }
+
+            if ((curr >= 'a' && curr <= 'z') || (curr >= 'A' && curr <= 'Z')) { // ASCII alphabets
+                assertTrue("Locale:" + locale + " Pattern:" + pattern + " has unsupported symbol "
+                                + curr, SUPPORTED_SYMBOLS.contains(curr));
+            }
+        }
+    }
+
+    private static void assertNonEmpty(String s) {
+        assertNotNull(s);
+        assertTrue(s.length() > 0);
+    }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java
new file mode 100644
index 0000000..9baf972
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/DecimalFormatTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.highmemorytest.java.text;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.Currency;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class DecimalFormatTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    /**
+     * Test no extra spacing between currency symbol and the numeric amount
+     */
+    @Test
+    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));
+    }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java
new file mode 100644
index 0000000..63ec023
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/text/SimpleDateFormatTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.highmemorytest.java.text;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * Tests {@link SimpleDateFormat} but runs in a separate java package because loading data in all
+ * locales creates a lot of garbage / permanent heap growth in ICU4J and causes gcstress test
+ * failing in ART test environment. See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class SimpleDateFormatTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    @Test
+    public void testLocales() {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz", locale);
+        sdf.format(new Date(0));
+    }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java b/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java
new file mode 100644
index 0000000..e2d28ec
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/time/format/DateTimeFormatterTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2021 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.highmemorytest.java.time.format;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.time.Instant;
+import java.time.ZoneOffset;
+import java.time.chrono.Chronology;
+import java.time.format.DateTimeFormatter;
+import java.time.format.FormatStyle;
+import java.time.temporal.TemporalAccessor;
+import java.util.Locale;
+
+/**
+ * Additional tests for {@link DateTimeFormatter}. Runs in a separate java package because
+ * loading data in all locales creates a lot of garbage / permanent heap growth in ICU4J and
+ * causes gcstress test failing in ART test environment. See http://b/161420453.
+ *
+ * @see tck.java.time.format.TCKDateTimeFormatter
+ * @see test.java.time.format.TestDateTimeFormatter
+ * @see libcore.java.time.format.DateTimeFormatterTest
+ */
+@RunWith(Parameterized.class)
+public class DateTimeFormatterTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter
+    public Locale locale;
+
+    // 1 January 2022 00:00:00 GMT+00:00
+    private static final Instant TEST_INSTANT = Instant.ofEpochSecond(1640995200L);
+
+    /**
+     * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales.
+     */
+    @Test
+    public void test_format_allLocales() {
+        for (FormatStyle formatStyle : FormatStyle.values()) {
+            try {
+                DateTimeFormatter.ofLocalizedTime(formatStyle)
+                        .withLocale(locale)
+                        .withZone(ZoneOffset.UTC)
+                        .format(TEST_INSTANT);
+
+                DateTimeFormatter.ofLocalizedDate(formatStyle)
+                        .withLocale(locale)
+                        .withZone(ZoneOffset.UTC)
+                        .format(TEST_INSTANT);
+
+                DateTimeFormatter.ofLocalizedDateTime(formatStyle)
+                        .withLocale(locale)
+                        .withZone(ZoneOffset.UTC)
+                        .format(TEST_INSTANT);
+            } catch (RuntimeException cause) {
+                throw new RuntimeException("formatStyle:" + formatStyle.name(), cause);
+            }
+        }
+    }
+
+    /**
+     * Test {@link DateTimeFormatter#format(TemporalAccessor)} does not crash on available locales
+     * with all possible Chronologies.
+     */
+    @Test
+    public void test_format_allLocales_allChronologies() {
+        for (Chronology chronology : Chronology.getAvailableChronologies()) {
+            for (FormatStyle formatStyle : FormatStyle.values()) {
+                try {
+                    DateTimeFormatter.ofLocalizedTime(formatStyle)
+                            .withLocale(locale)
+                            .withChronology(chronology)
+                            .withZone(ZoneOffset.UTC)
+                            .format(TEST_INSTANT);
+
+                    DateTimeFormatter.ofLocalizedDate(formatStyle)
+                            .withLocale(locale)
+                            .withChronology(chronology)
+                            .withZone(ZoneOffset.UTC)
+                            .format(TEST_INSTANT);
+
+                    DateTimeFormatter.ofLocalizedDateTime(formatStyle)
+                            .withLocale(locale)
+                            .withChronology(chronology)
+                            .withZone(ZoneOffset.UTC)
+                            .format(TEST_INSTANT);
+                } catch (RuntimeException cause) {
+                    throw new RuntimeException("Chronology:" + chronology +
+                            " formatStyle:" + formatStyle.name(), cause);
+                }
+            }
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java b/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java
new file mode 100644
index 0000000..036ed9f
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/util/CalendarTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.highmemorytest.java.util;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class CalendarTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    /**
+     * 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() {
+        assertTrue("Default calendar should be Gregorian: " + locale,
+                Calendar.getInstance(locale) instanceof GregorianCalendar);
+    }
+
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java b/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java
new file mode 100644
index 0000000..d1cbf5e
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/java/util/CurrencyTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.highmemorytest.java.util;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Currency;
+import java.util.Locale;
+
+/**
+ * Runs in a separate java package because loading data in all locales creates a lot of garbage /
+ * permanent heap growth in ICU4J and causes gcstress test failing in ART test environment.
+ * See http://b/161420453.
+ */
+@RunWith(Parameterized.class)
+public class CurrencyTest {
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    @Test
+    public void test_currencyCodeIcuConsistency() {
+        Currency javaCurrency = getCurrency(locale);
+        if (javaCurrency == null) {
+            return;
+        }
+        assertEquals("Currency code is not consistent:" + locale,
+                android.icu.util.Currency.getInstance(locale).getCurrencyCode(),
+                javaCurrency.getCurrencyCode());
+    }
+
+    private static Currency getCurrency(Locale l) {
+        try {
+            return Currency.getInstance(l);
+        } catch (IllegalArgumentException e) {
+            // The locale could have no country or does not have currency for other reasons.
+            return null;
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java
new file mode 100644
index 0000000..ab396f9
--- /dev/null
+++ b/luni/src/test/java/libcore/highmemorytest/libcore/icu/LocaleDataTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.highmemorytest.libcore.icu;
+
+import static org.junit.Assert.assertTrue;
+
+import libcore.icu.LocaleData;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+import java.util.Locale;
+
+@RunWith(Parameterized.class)
+public class LocaleDataTest {
+
+    @Parameterized.Parameters(name = "{0}")
+    public static Locale[] getAllLocales() {
+        return Locale.getAvailableLocales();
+    }
+
+    @Parameterized.Parameter(0)
+    public Locale locale;
+
+    @Test
+    public void testLongDateTimeFormat() {
+        LocaleData d = LocaleData.get(locale);
+        int dateLength = d.longDateFormat.length();
+        assertTrue("LocaleData.longDateFormat has zero length: " + dateLength, dateLength != 0);
+        int timeLength = d.longTimeFormat.length();
+        assertTrue("LocaleData.longTimeFormat has zero length: " + timeLength, timeLength != 0);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/awt/font/NumericShaperTest.java b/luni/src/test/java/libcore/java/awt/font/NumericShaperTest.java
new file mode 100644
index 0000000..0fedceb
--- /dev/null
+++ b/luni/src/test/java/libcore/java/awt/font/NumericShaperTest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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.awt.font;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.awt.font.NumericShaper;
+import java.awt.font.NumericShaper.Range;
+import java.util.EnumSet;
+
+@RunWith(JUnit4.class)
+public class NumericShaperTest {
+
+    @Test
+    public void testShape() {
+        NumericShaper ns = NumericShaper.getShaper(Range.ARABIC);
+        String input = "abc 123";
+        String expected = "abc \u0661\u0662\u0663";
+
+        char[] chars = input.toCharArray();
+        ns.shape(chars, 0, chars.length);
+        assertEquals(expected, new String(chars));
+
+        chars = input.toCharArray();
+        ns.shape(chars, 0, chars.length, NumericShaper.EUROPEAN);
+        assertEquals(expected, new String(chars));
+
+        chars = input.toCharArray();
+        ns.shape(chars, 0, chars.length, Range.EUROPEAN);
+        assertEquals(expected, new String(chars));
+    }
+
+    @Test
+    public void testGetRanges() {
+        NumericShaper ns = NumericShaper.getContextualShaper(NumericShaper.ARABIC);
+        assertEquals(NumericShaper.ARABIC, ns.getRanges());
+    }
+
+    @Test
+    public void testGetRangeSet() {
+        NumericShaper ns = NumericShaper.getContextualShaper(
+                NumericShaper.ARABIC | NumericShaper.DEVANAGARI);
+        assertEquals(EnumSet.of(Range.ARABIC, Range.DEVANAGARI), ns.getRangeSet());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/io/FileInputStreamTest.java b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
index e722b4f..dbc8a02 100644
--- a/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/io/FileInputStreamTest.java
@@ -16,17 +16,7 @@
 
 package libcore.java.io;
 
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
 import android.system.ErrnoException;
-import android.system.Int32Ref;
 import android.system.Os;
 import android.system.OsConstants;
 import android.system.StructStatVfs;
@@ -40,6 +30,15 @@
 import org.junit.Rule;
 import org.junit.rules.TestRule;
 
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
 public final class FileInputStreamTest extends TestCaseWithRules {
     @Rule
     public TestRule guardRule = ResourceLeakageDetector.getRule();
@@ -224,7 +223,7 @@
         }
 
         try (FileInputStream input = new FileInputStream(file)) {
-            android.system.Os.ioctlInt(input.getFD(), OsConstants.FIONREAD, new Int32Ref(0));
+            android.system.Os.ioctlInt(input.getFD(), OsConstants.FIONREAD);
             fail();
         } catch (ErrnoException expected) {
             assertEquals("FIONREAD should have returned ENOTTY for the file. If it doesn't return"
diff --git a/luni/src/test/java/libcore/java/io/OldObjectStreamFieldTest.java b/luni/src/test/java/libcore/java/io/OldObjectStreamFieldTest.java
index ee09221..71dd4046 100644
--- a/luni/src/test/java/libcore/java/io/OldObjectStreamFieldTest.java
+++ b/luni/src/test/java/libcore/java/io/OldObjectStreamFieldTest.java
@@ -23,7 +23,7 @@
 
 public class OldObjectStreamFieldTest extends junit.framework.TestCase {
 
-    static class DummyClass implements Serializable {
+    static class FakeClass implements Serializable {
         private static final long serialVersionUID = 999999999999998L;
 
         boolean bField = true;
@@ -170,7 +170,7 @@
     }
 
     protected void setUp() {
-        osc = ObjectStreamClass.lookup(DummyClass.class);
+        osc = ObjectStreamClass.lookup(FakeClass.class);
         bamField = osc.getField("bam");
         samField = osc.getField("sam");
         hamField = osc.getField("ham");
diff --git a/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java b/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java
new file mode 100644
index 0000000..613ad00
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/BootstrapMethodErrorTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BootstrapMethodErrorTest {
+
+    private final String causeMessage = "Cause";
+    private final String errorMessage = "Error message";
+
+    @Test
+    public void constructor() {
+        BootstrapMethodError error = new BootstrapMethodError();
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+
+    @Test
+    public void constructorLString() {
+        BootstrapMethodError error = new BootstrapMethodError(errorMessage);
+
+        assertEquals(errorMessage, error.getMessage());
+        assertNull(error.getCause());
+    }
+
+    @Test
+    public void constructorLString_withNull() {
+        BootstrapMethodError error = new BootstrapMethodError((String) null);
+
+        assertNull(error.getMessage());
+        assertNull(error.getCause());
+    }
+
+    @Test
+    public void constructorLString_LThrowable() {
+        Exception cause = new Exception(causeMessage);
+        BootstrapMethodError error = new BootstrapMethodError(errorMessage, cause);
+
+        assertEquals(cause, error.getCause());
+        assertEquals(errorMessage, error.getMessage());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_nullMessage() {
+        Exception cause = new Exception(causeMessage);
+        BootstrapMethodError error = new BootstrapMethodError(null, cause);
+
+        assertNull(error.getMessage());
+        assertEquals(cause, error.getCause());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_nullCause() {
+        BootstrapMethodError error = new BootstrapMethodError(errorMessage, null /* cause */);
+
+        assertNull(error.getCause());
+        assertEquals(errorMessage, error.getMessage());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_bothArgumentsNull() {
+        BootstrapMethodError error = new BootstrapMethodError(null, null);
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+
+    @Test
+    public void constructorLThrowable() {
+        Exception cause = new Exception(causeMessage);
+        BootstrapMethodError error = new BootstrapMethodError(cause);
+
+        assertEquals(cause, error.getCause());
+        assertEquals(cause.toString(), error.getMessage());
+    }
+
+    @Test
+    public void constructorLThrowable_withNull() {
+        BootstrapMethodError error = new BootstrapMethodError((Throwable) null /* cause */);
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/ByteTest.java b/luni/src/test/java/libcore/java/lang/ByteTest.java
index f051b91..821d060 100644
--- a/luni/src/test/java/libcore/java/lang/ByteTest.java
+++ b/luni/src/test/java/libcore/java/lang/ByteTest.java
@@ -57,4 +57,37 @@
             assertEquals(b, Long.valueOf(b).byteValue());
         }
     }
+
+    public void testCompareUnsigned() {
+        // Ascending order of unsigned(value)
+        final byte a = 0;
+        final byte b = 3;
+        final byte y = -2; // 254
+        final byte z = -1; // 255
+
+        assertTrue(Byte.compareUnsigned(a, b) < 0);
+        assertTrue(Byte.compareUnsigned(a, y) < 0);
+        assertTrue(Byte.compareUnsigned(a, z) < 0);
+        assertTrue(Byte.compareUnsigned(b, y) < 0);
+        assertTrue(Byte.compareUnsigned(b, z) < 0);
+        assertTrue(Byte.compareUnsigned(y, z) < 0);
+
+        assertTrue(Byte.compareUnsigned(b, a) > 0);
+        assertTrue(Byte.compareUnsigned(y, a) > 0);
+        assertTrue(Byte.compareUnsigned(y, b) > 0);
+        assertTrue(Byte.compareUnsigned(z, a) > 0);
+        assertTrue(Byte.compareUnsigned(z, b) > 0);
+        assertTrue(Byte.compareUnsigned(z, y) > 0);
+
+        assertTrue(Byte.compareUnsigned(a, a) == 0);
+        assertTrue(Byte.compareUnsigned(b, b) == 0);
+        assertTrue(Byte.compareUnsigned(y, y) == 0);
+        assertTrue(Byte.compareUnsigned(z, z) == 0);
+
+        assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, (byte)128) == 0);
+        assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, (byte)127) == 0);
+        assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, Byte.MAX_VALUE) > 0);
+        assertTrue(Byte.compareUnsigned(Byte.MIN_VALUE, z) < 0);
+        assertTrue(Byte.compareUnsigned(Byte.MAX_VALUE, z) < 0);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/ErrorTest.java b/luni/src/test/java/libcore/java/lang/ErrorTest.java
new file mode 100644
index 0000000..1962b07
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/ErrorTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ErrorTest {
+
+    @Test
+    public void withNonWritableStackTrace_getStackTraceIsEmpty() {
+        Error error = new TestError("message", null /* cause */,
+                false /* enableSuppression */,
+                false /* writableStackTrace */);
+
+        assertEquals(0, error.getStackTrace().length);
+    }
+
+    @Test
+    public void withWritableStackTrace_nonEmptyGetStackTrace() {
+        Error error = new TestError("message", null /* cause */,
+                false /* enableSuppression */,
+                true /* writableStackTrace */);
+
+        assertNotEquals(0, error.getStackTrace().length);
+
+        StackTraceElement topStackTraceElement = error.getStackTrace()[0];
+        assertEquals("withWritableStackTrace_nonEmptyGetStackTrace",
+                topStackTraceElement.getMethodName());
+    }
+
+    @Test
+    public void whenSuppressionDisabled_addSuppressHasNoEffect() {
+        Error error = new TestError("Message", null, false /* enableSuppression */, true);
+
+        assertEquals(0, error.getSuppressed().length);
+        error.addSuppressed(new Exception("suppressed exception"));
+        assertEquals(0, error.getSuppressed().length);
+    }
+
+    @Test
+    public void whenSuppressionEnabled_addsSuppressed() {
+        Error error = new TestError("message", null /* cause */, true /* enableSuppression */,
+                true /* writableStackTrace */);
+
+        assertEquals(0, error.getSuppressed().length);
+
+        Exception suppressed = new Exception("suppressed");
+        error.addSuppressed(suppressed);
+        assertArrayEquals(new Throwable[] {suppressed}, error.getSuppressed());
+    }
+
+
+    private static final class TestError extends Error {
+        protected TestError(String message, Throwable cause, boolean enableSuppression,
+                boolean writableStackTrace) {
+            super(message, cause, enableSuppression, writableStackTrace);
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java b/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java
new file mode 100644
index 0000000..afba40a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/InheritableThreadLocalTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class InheritableThreadLocalTest {
+
+    @Test
+    public void childValue_shouldReturnInputArgument() {
+        TestInheritableThreadLocal<Object> threadLocal = new TestInheritableThreadLocal<>();
+
+        assertNull(threadLocal.childValue(null));
+        Object parentValue = new Object();
+        assertEquals(parentValue, threadLocal.childValue(parentValue));
+    }
+
+    private static final class TestInheritableThreadLocal<T> extends InheritableThreadLocal<T> {
+
+        @Override
+        public T childValue(T parentValue) {
+            return super.childValue(parentValue);
+        }
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/InternalErrorTest.java b/luni/src/test/java/libcore/java/lang/InternalErrorTest.java
new file mode 100644
index 0000000..acf588e
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/InternalErrorTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class InternalErrorTest {
+
+    @Test
+    public void constructorLThrowable() {
+        Throwable cause = new Exception("cause");
+        InternalError error = new InternalError(cause);
+
+        assertEquals(cause, error.getCause());
+        assertEquals("java.lang.Exception: cause", error.getMessage());
+    }
+
+    @Test
+    public void constructorLThrowable_withNull() {
+        InternalError error = new InternalError((Throwable) null);
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java b/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
index 7fb29e6..2e15d33 100644
--- a/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
+++ b/luni/src/test/java/libcore/java/lang/LambdaImplementationTest.java
@@ -302,7 +302,7 @@
     private static void assertMultipleDefinitionCharacteristics(
             Callable<String> r1, Callable<String> r2) throws Exception {
 
-        // Sanity check that the lambdas do the same thing.
+        // Check that the lambdas do the same thing.
         assertEquals(r1.call(), r2.call());
 
         // Two lambdas from different definitions can share the same class or may not so there are
@@ -324,7 +324,7 @@
     private static void assertMultipleInstanceCharacteristics(
             Callable<String> r1, Callable<String> r2) throws Exception {
 
-        // Sanity check that the lambdas do the same thing.
+        // Check that the lambdas do the same thing.
         assertEquals(r1.call(), r2.call());
 
         // There doesn't appear to be anything else that is safe to assert here. Two lambdas
diff --git a/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java b/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java
new file mode 100644
index 0000000..2a853d7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/LinkageErrorTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class LinkageErrorTest {
+
+    private final String errorMessage = "error message";
+
+    @Test
+    public void constructorLString_LThrowable() {
+        Exception cause = new Exception();
+        LinkageError error = new LinkageError(errorMessage, cause);
+
+        assertEquals(cause, error.getCause());
+        assertEquals(errorMessage, error.getMessage());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_nullMessage() {
+        Exception cause = new Exception();
+        LinkageError error = new LinkageError(null, cause);
+
+        assertNull(error.getMessage());
+        assertEquals(cause, error.getCause());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_nullCause() {
+        LinkageError error = new LinkageError(errorMessage, null /* cause */);
+
+        assertEquals(errorMessage, error.getMessage());
+        assertNull(error.getCause());
+    }
+
+    @Test
+    public void constructorLString_LThrowable_bothArgumentsNull() {
+        LinkageError error = new LinkageError(null, null);
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/MathTest.java b/luni/src/test/java/libcore/java/lang/MathTest.java
index f7ebaa6..ee0dd73 100644
--- a/luni/src/test/java/libcore/java/lang/MathTest.java
+++ b/luni/src/test/java/libcore/java/lang/MathTest.java
@@ -300,4 +300,37 @@
             }
         }
     }
+
+    private static long multiplyFullBigInt(int x, int y) {
+        return BigInteger.valueOf(x).multiply(BigInteger.valueOf(y)).longValue();
+    }
+
+    public void testMultiplyFull() {
+        int[][] v = new int[][]{
+            {0, 0},
+            {-1, 0},
+            {0, -1},
+            {1, 0},
+            {0, 1},
+            {-1, -1},
+            {-1, 1},
+            {1, -1},
+            {1, 1},
+            {Integer.MAX_VALUE, Integer.MAX_VALUE},
+            {Integer.MAX_VALUE, -Integer.MAX_VALUE},
+            {-Integer.MAX_VALUE, Integer.MAX_VALUE},
+            {-Integer.MAX_VALUE, -Integer.MAX_VALUE},
+            {Integer.MAX_VALUE, Integer.MIN_VALUE},
+            {Integer.MIN_VALUE, Integer.MAX_VALUE},
+            {Integer.MIN_VALUE, Integer.MIN_VALUE}
+        };
+
+        for (int[] xy : v) {
+            int x = xy[0];
+            int y = xy[1];
+            long p1 = multiplyFullBigInt(x, y);
+            long p2 = Math.multiplyFull(x, y);
+            assertEquals(p1, p2);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/OldClassTest.java b/luni/src/test/java/libcore/java/lang/OldClassTest.java
index f5bc787..a4af7d1 100644
--- a/luni/src/test/java/libcore/java/lang/OldClassTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldClassTest.java
@@ -306,7 +306,7 @@
         }
     }
 
-    // AndroidOnly: Class.forName method throws ClassNotFoundException on Android.
+    // Android-note: Class.forName method throws ClassNotFoundException on Android.
     public void test_forNameLjava_lang_StringLbooleanLClassLoader_AndroidOnly() throws Exception {
 
         // Android doesn't support loading class files from a jar.
@@ -460,7 +460,7 @@
         assertEquals(AbstractList.class, type.getRawType());
     }
 
-    // AndroidOnly: Uses dalvik.system.PathClassLoader.
+    // Android-note: Uses dalvik.system.PathClassLoader.
     // Different behavior between cts host and run-core-test")
     public void test_getPackage() {
 
@@ -469,7 +469,7 @@
                       thisPackage.getName());
 
       Package stringPackage = String.class.getPackage();
-      assertNotNull("java.lang", stringPackage.getName());
+      assertEquals("java.lang", stringPackage.getName());
 
       String hyts_package_name = "hyts_package_dex.jar";
       File resources = Support_Resources.createTempFolder();
@@ -517,6 +517,66 @@
       }
     }
 
+    // Android-note: Uses dalvik.system.PathClassLoader.
+    // Different behavior between cts host and run-core-test")
+    public void test_getPackageName() {
+
+      String thisPackage = getClass().getPackageName();
+      assertEquals("libcore.java.lang", thisPackage);
+
+      String stringPackage = String.class.getPackageName();
+      assertEquals("java.lang", stringPackage);
+  
+      String stringArrayPackage = String[].class.getPackageName();
+      assertEquals("java.lang", stringArrayPackage);
+
+      String stringArrayArrayPackage = String[][].class.getPackageName();
+      assertEquals("java.lang", stringArrayArrayPackage);
+
+      String intPackage = int.class.getPackageName();
+      assertEquals("java.lang", intPackage);
+
+      String intArrayPackage = int[].class.getPackageName();
+      assertEquals("java.lang", intPackage);
+
+      String hyts_package_name = "hyts_package_dex.jar";
+      File resources = Support_Resources.createTempFolder();
+      Support_Resources.copyFile(resources, "Package", hyts_package_name);
+
+      String resPath = resources.toString();
+      if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\')
+          resPath = resPath.substring(1);
+
+      try {
+
+          URL resourceURL = new URL("file:/" + resPath + "/Package/"
+                  + hyts_package_name);
+
+          ClassLoader cl = Support_ClassLoader.getInstance(resourceURL,
+                  getClass().getClassLoader());
+
+          Class clazz = cl.loadClass("C");
+          assertEquals("", clazz.getPackageName());
+
+          clazz = Class.forName("[LC;", false, cl);
+          assertEquals("", clazz.getPackageName());
+
+          clazz = Class.forName("[[LC;", false, cl);
+          assertEquals("", clazz.getPackageName());
+
+          clazz = cl.loadClass("a.b.C");
+          assertEquals("a.b", clazz.getPackageName());
+
+          clazz = Class.forName("[La.b.C;", false, cl);
+          assertEquals("a.b", clazz.getPackageName());
+
+          clazz = Class.forName("[[La.b.C;", false, cl);
+          assertEquals("a.b", clazz.getPackageName());
+      } catch(Exception e) {
+          fail("Unexpected exception was thrown: " + e.toString());
+      }
+    }
+
     public void test_getSigners() {
         assertNull(void.class.getSigners());
         assertNull(PublicTestClass.class.getSigners());
diff --git a/luni/src/test/java/libcore/java/lang/OldThreadGroupTest.java b/luni/src/test/java/libcore/java/lang/OldThreadGroupTest.java
index 35e366e..4b74cec 100644
--- a/luni/src/test/java/libcore/java/lang/OldThreadGroupTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldThreadGroupTest.java
@@ -278,7 +278,7 @@
     public void test_resume() {
         ThreadGroup group = new ThreadGroup("Foo");
 
-        Thread thread = launchFiveSecondDummyThread(group);
+        Thread thread = launchFiveSecondFakeThread(group);
 
         try {
             Thread.sleep(1000);
@@ -293,7 +293,7 @@
         }
     }
 
-    private Thread launchFiveSecondDummyThread(ThreadGroup group) {
+    private Thread launchFiveSecondFakeThread(ThreadGroup group) {
         Thread thread = new Thread(group, "Bar") {
             public void run() {
                 try {
diff --git a/luni/src/test/java/libcore/java/lang/OldThreadTest.java b/luni/src/test/java/libcore/java/lang/OldThreadTest.java
index 75b230d..ab3f7df 100644
--- a/luni/src/test/java/libcore/java/lang/OldThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/OldThreadTest.java
@@ -154,7 +154,7 @@
         }
     }
 
-    private Thread launchFiveSecondDummyThread() {
+    private Thread launchFiveSecondFakeThread() {
         Thread thread = new Thread() {
             public void run() {
                 try {
@@ -389,7 +389,7 @@
 
     @SuppressWarnings("deprecation")
     public void test_stop() {
-        Thread thread = launchFiveSecondDummyThread();
+        Thread thread = launchFiveSecondFakeThread();
 
         try {
             Thread.sleep(1000);
@@ -442,7 +442,7 @@
 
     @SuppressWarnings("deprecation")
     public void test_suspend() {
-        Thread thread = launchFiveSecondDummyThread();
+        Thread thread = launchFiveSecondFakeThread();
 
         try {
             Thread.sleep(1000);
diff --git a/luni/src/test/java/libcore/java/lang/PackageTest.java b/luni/src/test/java/libcore/java/lang/PackageTest.java
index 672af5d..ff1a9c3 100644
--- a/luni/src/test/java/libcore/java/lang/PackageTest.java
+++ b/luni/src/test/java/libcore/java/lang/PackageTest.java
@@ -17,6 +17,8 @@
 package libcore.java.lang;
 
 import dalvik.system.VMRuntime;
+
+import java.net.URL;
 import java.util.Arrays;
 import java.util.List;
 import libcore.junit.junit3.TestCaseWithRules;
@@ -24,6 +26,7 @@
 import libcore.junit.util.SwitchTargetSdkVersionRule.TargetSdkVersion;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
+import org.mockito.internal.matchers.Null;
 
 public final class PackageTest extends TestCaseWithRules {
 
@@ -46,6 +49,12 @@
         assertEquals(getClass().getPackage(), libcoreJavaLang);
     }
 
+    public void testGetPackageName() {
+        Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+        assertEquals("libcore.java.lang", getClass().getPackageName());
+        assertEquals(getClass().getPackageName(), libcoreJavaLang.getName());
+    }
+
     // http://b/28057303
     @TargetSdkVersion(24)
     public void test_toString_targetSdkVersion_24() throws Exception {
@@ -64,4 +73,137 @@
     public void testGetPackages() {
         assertTrue(packages.contains(getClass().getPackage()));
     }
+
+    public void testGetAnnotationsByType() {
+        Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+
+        assertEquals(1, libcoreJavaLang.getAnnotationsByType(TestPackageAnnotation.class).length);
+        assertEquals(0, libcoreJavaLang.getAnnotationsByType(Override.class).length);
+    }
+
+    public void testGetAnnotationsByType_shouldThrowNPE_whenNullIsPassed() {
+        Package libcoreJavaLang = Package.getPackage("libcore.java.lang");
+
+        try {
+            libcoreJavaLang.getAnnotationsByType(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    public void testIsSealed_nonSealedPackage() throws Exception {
+        TestClassLoader testClassLoader = new TestClassLoader();
+        Package nonSealedPackage = testClassLoader.definePackage(
+                "libcore.java.lang.nonsealed",
+                "spec title",
+                "spec version",
+                "spec vendor",
+                "impl title",
+                "impl version",
+                "impl vendor",
+                null /* sealBase */);
+
+        assertFalse(nonSealedPackage.isSealed());
+        assertFalse(nonSealedPackage.isSealed(new URL("file://libcore/java/lang/nonsealed")));
+    }
+
+    public void testIsSealed_sealedPackage() throws Exception {
+        TestClassLoader testClassLoader = new TestClassLoader();
+        URL sealBase = new URL("file://libcore/java/lang/sealed");
+        Package sealedPackage = testClassLoader.definePackage(
+                "libcore.java.lang.sealed",
+                "spec title",
+                "spec version",
+                "spec vendor",
+                "impl title",
+                "impl version",
+                "impl vendor",
+                sealBase);
+
+        assertTrue(sealedPackage.isSealed());
+        assertTrue(sealedPackage.isSealed(sealBase));
+        assertFalse(sealedPackage.isSealed(new URL("file://libcore/java/lang")));
+        try {
+            sealedPackage.isSealed(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    public void testGetSpecificationVendor() {
+        String specVendor = "specification vendor";
+        TestClassLoader testClassLoader = new TestClassLoader();
+        Package aPackage = testClassLoader.definePackage(
+                "libcore.java.lang.nonsealed",
+                "spec title",
+                "spec version",
+                specVendor,
+                "impl title",
+                "impl version",
+                "impl vendor",
+                null /* sealBase */);
+
+        assertEquals(specVendor, aPackage.getSpecificationVendor());
+    }
+
+    public void testGetSpecificationVersion() {
+        String specVersion = "specification version";
+        TestClassLoader testClassLoader = new TestClassLoader();
+        Package aPackage = testClassLoader.definePackage(
+                "libcore.java.lang.nonsealed",
+                "spec title",
+                specVersion,
+                "spec vendor",
+                "impl title",
+                "impl version",
+                "impl vendor",
+                null /* sealBase */);
+
+        assertEquals(specVersion, aPackage.getSpecificationVersion());
+    }
+
+    public void testIsCompatibleWith() {
+        String specVersion = "2.3.1";
+        TestClassLoader testClassLoader = new TestClassLoader();
+        Package aPackage = testClassLoader.definePackage(
+                "libcore.java.lang.nonsealed",
+                "spec title",
+                specVersion,
+                "spec vendor",
+                "impl title",
+                "impl version",
+                "impl vendor",
+                null /* sealBase */);
+
+        assertTrue(aPackage.isCompatibleWith(specVersion));
+        assertTrue(aPackage.isCompatibleWith("2.2.99.1"));
+        assertTrue(aPackage.isCompatibleWith("1.0"));
+        assertTrue(aPackage.isCompatibleWith("2.3.1.0"));
+        assertTrue(aPackage.isCompatibleWith("2.3"));
+        assertFalse(aPackage.isCompatibleWith("2.4"));
+        try {
+            aPackage.isCompatibleWith(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+
+    /**
+     * {@link java.lang.Package} constructors are package-private and
+     * {@link java.lang.ClassLoader#definePackage(String, String, String, String, String, String, String, URL)}
+     * is other way to create instance of {@link java.lang.Package}
+     */
+    private static final class TestClassLoader extends ClassLoader {
+        @Override
+        public Package definePackage(String name, String specTitle, String specVersion,
+                String specVendor, String implTitle, String implVersion, String implVendor,
+                URL sealBase) throws IllegalArgumentException {
+            return super.definePackage(name, specTitle, specVersion, specVendor, implTitle,
+                    implVersion, implVendor, sealBase);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
index 07ce6dd..1615188 100644
--- a/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
+++ b/luni/src/test/java/libcore/java/lang/ProcessBuilderTest.java
@@ -356,7 +356,7 @@
     }
 
     /**
-     * Tests that {@link Redirect}'s equals() and hashCode() is sane.
+     * Tests that {@link Redirect}'s equals() and hashCode() is useful.
      */
     public void testRedirect_equals() {
         File fileA = new File("/tmp/fileA");
diff --git a/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java b/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java
new file mode 100644
index 0000000..35ab3d4
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/RuntimeExceptionTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuntimeExceptionTest {
+
+    @Test
+    public void withNonWritableStackTrace_getStackTraceIsEmpty() {
+        RuntimeException exception = new TestRuntimeException("message", null /* cause */,
+                false /* enableSuppression */,
+                false /* writableStackTrace */);
+
+        assertEquals(0, exception.getStackTrace().length);
+    }
+
+    @Test
+    public void withWritableStackTrace_nonEmptyGetStackTrace() {
+        RuntimeException exception = new TestRuntimeException("message", null /* cause */,
+                false /* enableSuppression */,
+                true /* writableStackTrace */);
+
+        assertNotEquals(0, exception.getStackTrace().length);
+
+        StackTraceElement topStackTraceElement = exception.getStackTrace()[0];
+        assertEquals("withWritableStackTrace_nonEmptyGetStackTrace",
+                topStackTraceElement.getMethodName());
+    }
+
+    @Test
+    public void whenSuppressionDisabled_addSuppressHasNoEffect() {
+        RuntimeException exception = new TestRuntimeException("Message", null,
+                false /* enableSuppression */, true /* writableStackTrace */);
+
+        assertEquals(0, exception.getSuppressed().length);
+        exception.addSuppressed(new Exception("suppressed exception"));
+        assertEquals(0, exception.getSuppressed().length);
+    }
+
+    @Test
+    public void whenSuppressionEnabled_addsSuppressed() {
+        RuntimeException error = new TestRuntimeException("message", null /* cause */,
+                true /* enableSuppression */, true /* writableStackTrace */);
+
+        assertEquals(0, error.getSuppressed().length);
+
+        Exception suppressed = new Exception("suppressed");
+        error.addSuppressed(suppressed);
+        assertArrayEquals(new Throwable[] {suppressed}, error.getSuppressed());
+    }
+
+    private static final class TestRuntimeException extends RuntimeException {
+        TestRuntimeException(String message, Throwable cause, boolean enableSuppression,
+                boolean writableStackTrace) {
+            super(message, cause, enableSuppression, writableStackTrace);
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java b/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java
new file mode 100644
index 0000000..33c0898
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/RuntimePermissionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuntimePermissionTest {
+
+    @Test
+    public void constructorLString_LString() {
+        RuntimePermission runtimePermission = new RuntimePermission(null, null);
+        assertEquals("", runtimePermission.getActions());
+        assertEquals("", runtimePermission.getName());
+
+        runtimePermission = new RuntimePermission("non empty", "non empty");
+        assertEquals("", runtimePermission.getActions());
+        assertEquals("", runtimePermission.getName());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/SecurityManagerTest.java b/luni/src/test/java/libcore/java/lang/SecurityManagerTest.java
new file mode 100644
index 0000000..99af64d
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/SecurityManagerTest.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.FileDescriptor;
+import java.net.Inet4Address;
+import java.security.AllPermission;
+
+/**
+ * Android doesn't support SecurityManager. This test checks that the implementation does nothing
+ * or doesn't throw arbitrary exceptions.
+ */
+@RunWith(JUnit4.class)
+public class SecurityManagerTest {
+
+    private static final String SAMPLE_HOST = "www.example.com";
+    private static final int SAMPLE_PORT = 80;
+
+    /**
+     * Expose protected method from {@link SecurityManager} for test.
+     */
+    private static class TestSecurityManager extends SecurityManager {
+        @Override
+        protected Class[] getClassContext() {
+            return super.getClassContext();
+        }
+
+        @Override
+        protected boolean inClass(String name) {
+            return super.inClass(name);
+        }
+
+        @Override
+        protected boolean inClassLoader() {
+            return super.inClassLoader();
+        }
+
+        @Override
+        protected Class<?> currentLoadedClass() {
+            return super.currentLoadedClass();
+        }
+
+        @Override
+        protected ClassLoader currentClassLoader() {
+            return super.currentClassLoader();
+        }
+
+        @Override
+        protected int classDepth(String name) {
+            return super.classDepth(name);
+        }
+
+        @Override
+        protected int classLoaderDepth() {
+            return super.classLoaderDepth();
+        }
+    }
+
+    private TestSecurityManager sm = new TestSecurityManager();
+
+    @Test
+    public void testSystemSecurityManager() {
+        Assert.assertNull(System.getSecurityManager());
+        // Set null allowed
+        System.setSecurityManager(null);
+        try {
+            System.setSecurityManager(sm);
+            Assert.fail("System.setSecurityManager(sm) doesn't throw.");
+        } catch (SecurityException e) {
+            // expected
+        }
+        Assert.assertNull(System.getSecurityManager());
+    }
+
+    @Test
+    public void testCheckAccept() {
+        sm.checkAccept(SAMPLE_HOST, SAMPLE_PORT);
+    }
+
+    @Test
+    public void testCheckAccess() {
+        sm.checkAccess(Thread.currentThread());
+    }
+
+    @Test
+    public void testCheckAccessThreadGroup() {
+        sm.checkAccess(sm.getThreadGroup());
+    }
+
+    @Test
+    public void testCheckAwtEventQueueAccess() {
+        sm.checkAwtEventQueueAccess();
+    }
+
+    @Test
+    public void testCheckConnect() {
+        sm.checkConnect(SAMPLE_HOST, SAMPLE_PORT);
+    }
+
+    @Test
+    public void testCheckConnectWithObject() {
+        sm.checkConnect(SAMPLE_HOST, SAMPLE_PORT, null);
+    }
+
+    @Test
+    public void testCheckCreateClassLoader() {
+        sm.checkCreateClassLoader();
+    }
+
+    @Test
+    public void testCheckDelete() {
+        sm.checkDelete(null);
+        sm.checkDelete("/FILE_NOT_EXIST");
+    }
+
+    @Test
+    public void testCheckExec() {
+        sm.checkExec("invalid command");
+    }
+
+    @Test
+    public void testCheckExit() {
+        sm.checkExit(0);
+        sm.checkExit(1);
+        sm.checkExit(127);
+    }
+
+    @Test
+    public void testCheckLink() {
+        sm.checkLink("libinvalid.so");
+    }
+
+    @Test
+    public void testCheckListen() {
+        sm.checkListen(SAMPLE_PORT);
+    }
+
+    @Test
+    public void testCheckMemberAccess() {
+        sm.checkMemberAccess(System.class, 0);
+    }
+
+    @Test
+    public void testCheckMulticast() {
+        sm.checkMulticast(Inet4Address.LOOPBACK);
+    }
+
+    @Test
+    public void testCheckMulticastWithTtl() {
+        sm.checkMulticast(Inet4Address.LOOPBACK, (byte) 0);
+    }
+
+    @Test
+    public void testCheckPackageAccess() {
+        sm.checkPackageAccess("java.lang");
+        sm.checkPackageAccess("android.invalid.package");
+    }
+
+    @Test
+    public void testCheckPackageDefinition() {
+        sm.checkPackageDefinition("java.lang");
+        sm.checkPackageDefinition("android.invalid.package");
+    }
+
+    @Test
+    public void testCheckPermission() {
+        sm.checkPermission(new AllPermission(), this);
+    }
+
+    @Test
+    public void testCheckPrintJobAccess() {
+        sm.checkPrintJobAccess();
+    }
+
+    @Test
+    public void testCheckPropertiesAccess() {
+        sm.checkPropertiesAccess();
+    }
+
+    @Test
+    public void testCheckPropertyAccess() {
+        sm.checkPropertyAccess(null);
+        sm.checkPropertyAccess("system.invalid.property");
+    }
+
+    @Test
+    public void testCheckRead() {
+        sm.checkRead((FileDescriptor) null);
+        sm.checkRead(FileDescriptor.in);
+        sm.checkRead(FileDescriptor.out);
+        sm.checkRead(FileDescriptor.err);
+    }
+
+    @Test
+    public void testCheckReadPath() {
+        sm.checkRead((String) null);
+        sm.checkRead("/");
+        sm.checkRead("/invalid_path");
+    }
+
+    @Test
+    public void testCheckReadWithObject() {
+        sm.checkRead("/", this);
+        sm.checkRead("/invalid_path", this);
+    }
+
+    @Test
+    public void testCheckSecurityAccess() {
+        sm.checkSecurityAccess(null);
+        sm.checkSecurityAccess("");
+    }
+
+    @Test
+    public void testCheckSetFactory() {
+        sm.checkSetFactory();
+    }
+
+    @Test
+    public void testCheckSystemClipboardAccess() {
+        sm.checkSystemClipboardAccess();
+    }
+
+    @Test
+    public void testCheckTopLevelWindow() {
+        sm.checkTopLevelWindow(null);
+        sm.checkTopLevelWindow(this);
+    }
+
+    @Test
+    public void testCheckWrite() {
+        sm.checkWrite((FileDescriptor) null);
+        sm.checkWrite(FileDescriptor.in);
+        sm.checkWrite(FileDescriptor.out);
+        sm.checkWrite(FileDescriptor.err);
+    }
+
+    @Test
+    public void testCheckWriteWithPath() {
+        sm.checkWrite("/");
+        sm.checkWrite("/invalid path");
+    }
+
+    @Test
+    public void testClassDepth() {
+        sm.classDepth(null);
+    }
+
+    @Test
+    public void testClassLoaderDepth() {
+        sm.classLoaderDepth();
+    }
+
+    @Test
+    public void testCurrentClassLoader() {
+        sm.currentClassLoader();
+    }
+
+    @Test
+    public void testCurrentLoadedClass() {
+        sm.currentLoadedClass();
+    }
+
+    @Test
+    public void testGetInCheck() {
+        sm.getInCheck();
+    }
+
+    @Test
+    public void testGetSecurityContext() {
+        sm.getSecurityContext();
+    }
+
+    @Test
+    public void testInClass() {
+        sm.inClass(this.getClass().getName());
+    }
+
+    @Test
+    public void testInClassLoader() {
+        sm.inClassLoader();
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/ShortTest.java b/luni/src/test/java/libcore/java/lang/ShortTest.java
index a3db71a..d805f8e 100644
--- a/luni/src/test/java/libcore/java/lang/ShortTest.java
+++ b/luni/src/test/java/libcore/java/lang/ShortTest.java
@@ -57,4 +57,37 @@
             assertEquals(b, Long.valueOf(b).shortValue());
         }
     }
+
+    public void testCompareUnsigned() {
+        // Ascending order of unsigned(value)
+        final short a = 0;
+        final short b = 3;
+        final short y = -2; // 65534
+        final short z = -1; // 65535
+
+        assertTrue(Short.compareUnsigned(a, b) < 0);
+        assertTrue(Short.compareUnsigned(a, y) < 0);
+        assertTrue(Short.compareUnsigned(a, z) < 0);
+        assertTrue(Short.compareUnsigned(b, y) < 0);
+        assertTrue(Short.compareUnsigned(b, z) < 0);
+        assertTrue(Short.compareUnsigned(y, z) < 0);
+
+        assertTrue(Short.compareUnsigned(b, a) > 0);
+        assertTrue(Short.compareUnsigned(y, a) > 0);
+        assertTrue(Short.compareUnsigned(y, b) > 0);
+        assertTrue(Short.compareUnsigned(z, a) > 0);
+        assertTrue(Short.compareUnsigned(z, b) > 0);
+        assertTrue(Short.compareUnsigned(z, y) > 0);
+
+        assertTrue(Short.compareUnsigned(a, a) == 0);
+        assertTrue(Short.compareUnsigned(b, b) == 0);
+        assertTrue(Short.compareUnsigned(y, y) == 0);
+        assertTrue(Short.compareUnsigned(z, z) == 0);
+
+        assertTrue(Short.compareUnsigned(Short.MIN_VALUE, (short)32768) == 0);
+        assertTrue(Short.compareUnsigned(Short.MAX_VALUE, (short)32767) == 0);
+        assertTrue(Short.compareUnsigned(Short.MIN_VALUE, Short.MAX_VALUE) > 0);
+        assertTrue(Short.compareUnsigned(Short.MIN_VALUE, z) < 0);
+        assertTrue(Short.compareUnsigned(Short.MAX_VALUE, z) < 0);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/StrictMathTest.java b/luni/src/test/java/libcore/java/lang/StrictMathTest.java
index 2509af8..fc6701f 100644
--- a/luni/src/test/java/libcore/java/lang/StrictMathTest.java
+++ b/luni/src/test/java/libcore/java/lang/StrictMathTest.java
@@ -228,4 +228,37 @@
             }
         }
     }
+
+    private static long multiplyFullBigInt(int x, int y) {
+        return BigInteger.valueOf(x).multiply(BigInteger.valueOf(y)).longValue();
+    }
+
+    public void testMultiplyFull() {
+        int[][] v = new int[][]{
+            {0, 0},
+            {-1, 0},
+            {0, -1},
+            {1, 0},
+            {0, 1},
+            {-1, -1},
+            {-1, 1},
+            {1, -1},
+            {1, 1},
+            {Integer.MAX_VALUE, Integer.MAX_VALUE},
+            {Integer.MAX_VALUE, -Integer.MAX_VALUE},
+            {-Integer.MAX_VALUE, Integer.MAX_VALUE},
+            {-Integer.MAX_VALUE, -Integer.MAX_VALUE},
+            {Integer.MAX_VALUE, Integer.MIN_VALUE},
+            {Integer.MIN_VALUE, Integer.MAX_VALUE},
+            {Integer.MIN_VALUE, Integer.MIN_VALUE}
+        };
+
+        for (int[] xy : v) {
+            int x = xy[0];
+            int y = xy[1];
+            long p1 = multiplyFullBigInt(x, y);
+            long p2 = StrictMath.multiplyFull(x, y);
+            assertEquals(p1, p2);
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index 56b6558..258f8a1 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -160,7 +160,7 @@
     }
 
     public void testSystemProperties_immutable() {
-        // Android-specific: The RI does not have a concept of immutable properties.
+        // Android-note: The RI does not have a concept of immutable properties.
 
         // user.dir is an immutable property
         String userDir = System.getProperty("user.dir");
@@ -223,10 +223,10 @@
 
         System.setProperties(newProperties);
 
-        // Android-specific: The RI makes the setProperties() argument the system properties object,
+        // Android-note: The RI makes the setProperties() argument the system properties object.
         // Android makes a new Properties object and copies the properties.
         assertNotSame(newProperties, System.getProperties());
-        // Android-specific: The RI does not have a concept of immutable properties.
+        // Android-note: The RI does not have a concept of immutable properties.
         assertEquals(userDir, System.getProperty("user.dir"));
 
         assertEquals("v2", System.getProperty("p1"));
@@ -242,11 +242,26 @@
 
         properties.clear();
 
-        // Android-specific: The RI clears everything, Android resets to immutable defaults.
+        // Android-note: The RI clears everything, Android resets to immutable defaults.
         assertEquals(userDir, System.getProperty("user.dir"));
         assertNull(System.getProperty("p1"));
     }
 
+    /**
+     * Assert that the following ICU-related system properties exist
+     */
+    public void testSystemProperties_getProperties_icu() {
+        String icuVersion = System.getProperty("android.icu.library.version");
+        assertNotNull(icuVersion);
+        assertTrue(icuVersion.length() > 0);
+        String unicodeVersion = System.getProperty("android.icu.unicode.version");
+        assertNotNull(unicodeVersion);
+        assertTrue(unicodeVersion.length() > 0);
+        String cldrVersion = System.getProperty("android.icu.cldr.version");
+        assertNotNull(cldrVersion);
+        assertTrue(cldrVersion.length() > 0);
+    }
+
     public void testSystem_setSecurityManager_null_noException() {
         System.setSecurityManager(null);
     }
@@ -258,4 +273,12 @@
         } catch (SecurityException expected) {
         }
     }
+
+    /**
+     * Overall {@link System#console()} return value depends on how exactly runtime was started, but
+     * for Android apps it will be null.
+     */
+    public void testSystem_console() {
+        assertNull(System.console());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java b/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java
new file mode 100644
index 0000000..4076bd1
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/ThreadGroupTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(JUnit4.class)
+public class ThreadGroupTest {
+
+    private CountDownLatch mLatch;
+
+    @Before
+    public void setup() {
+        mLatch = new CountDownLatch(2);
+    }
+
+    @Test
+    public void interrupt_shouldInterruptAllThreadsInAGroup() throws Exception {
+        ThreadGroup group = new ThreadGroup("group under test");
+
+        Thread first = createHangThread(group);
+        Thread second = createHangThread(group);
+
+        first.start();
+        second.start();
+
+        group.interrupt();
+
+        assertTrue("Some thread was not interrupted", mLatch.await(5, TimeUnit.SECONDS));
+    }
+
+    @Test
+    public void interrupt_shouldInterruptThreadsInSubgroups() throws Exception {
+        ThreadGroup parentGroup = new ThreadGroup("parent thread group");
+        ThreadGroup childGroup = new ThreadGroup(parentGroup, "child thread group");
+
+        Thread first = createHangThread(parentGroup);
+        Thread second = createHangThread(childGroup);
+
+        first.start();
+        second.start();
+
+        parentGroup.interrupt();
+
+        assertTrue("Some thread was not interrupted", mLatch.await(5, TimeUnit.SECONDS));
+    }
+
+    @Test
+    public void interrupt_shouldNotInterruptThreadsInParentGroup() throws Exception {
+        ThreadGroup parentGroup = new ThreadGroup("parent thread group");
+        ThreadGroup childGroup = new ThreadGroup(parentGroup, "child thread group");
+
+        Thread first = createHangThread(parentGroup);
+        Thread second = createHangThread(childGroup);
+
+        first.start();
+        second.start();
+
+        childGroup.interrupt();
+
+        assertFalse("Both threads were interrupted", mLatch.await(5, TimeUnit.SECONDS));
+
+        assertEquals("Thread from parent group was interrupted", 1, mLatch.getCount());
+    }
+
+    @Test
+    public void suspend_shouldThrowUnsupportedOperationException() throws Exception {
+        ThreadGroup threadGroup = new ThreadGroup("test group");
+
+        Thread thread = createHangThread(threadGroup);
+        thread.start();
+
+        try {
+            threadGroup.suspend();
+            fail("suspend() didn't throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException ignored) {
+            // expected
+        } finally {
+            thread.join();
+        }
+    }
+
+    @Test
+    public void stop_shouldThrowUnsupportedOperationException() throws Exception {
+        ThreadGroup threadGroup = new ThreadGroup("test group");
+
+        Thread thread = createHangThread(threadGroup);
+        thread.start();
+
+        try {
+            threadGroup.stop();
+            fail("stop() didn't throw UnsupportedOperationException");
+        } catch (UnsupportedOperationException ignored) {
+            // expected
+        } finally {
+            thread.join();
+        }
+    }
+
+    private Thread createHangThread(ThreadGroup threadGroup) {
+        return new Thread(threadGroup, () -> {
+            try {
+                Thread.sleep(20_000);
+            } catch (InterruptedException e) {
+                mLatch.countDown();
+            }
+        });
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/lang/ThreadTest.java b/luni/src/test/java/libcore/java/lang/ThreadTest.java
index 4e60891..19ca2b6 100644
--- a/luni/src/test/java/libcore/java/lang/ThreadTest.java
+++ b/luni/src/test/java/libcore/java/lang/ThreadTest.java
@@ -16,6 +16,13 @@
 
 package libcore.java.lang;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
+
 import dalvik.system.InMemoryDexClassLoader;
 
 import java.io.InputStream;
@@ -31,13 +38,17 @@
 import junit.framework.Assert;
 import junit.framework.TestCase;
 
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 import org.mockito.InOrder;
 import org.mockito.Mockito;
 
 import libcore.io.Streams;
 import libcore.java.lang.ref.FinalizationTester;
 
-public final class ThreadTest extends TestCase {
+@RunWith(JUnit4.class)
+public final class ThreadTest {
     static {
         System.loadLibrary("javacoretests");
     }
@@ -46,12 +57,14 @@
      * getContextClassLoader returned a non-application class loader.
      * http://code.google.com/p/android/issues/detail?id=5697
      */
-    public void testJavaContextClassLoader() throws Exception {
+    @Test
+    public void javaContextClassLoader() throws Exception {
         Assert.assertNotNull("Must have a Java context ClassLoader",
                 Thread.currentThread().getContextClassLoader());
     }
 
-    public void testLeakingStartedThreads() {
+    @Test
+    public void leakingStartedThreads() {
         final AtomicInteger finalizedThreadsCount = new AtomicInteger();
         for (int i = 0; true; i++) {
             try {
@@ -64,7 +77,8 @@
         assertTrue("Started threads were never finalized!", finalizedThreadsCount.get() > 0);
     }
 
-    public void testLeakingUnstartedThreads() {
+    @Test
+    public void leakingUnstartedThreads() {
         final AtomicInteger finalizedThreadsCount = new AtomicInteger();
         for (int i = 0; true; i++) {
             try {
@@ -77,7 +91,8 @@
         assertTrue("Unstarted threads were never finalized!", finalizedThreadsCount.get() > 0);
     }
 
-    public void testThreadSleep() throws Exception {
+    @Test
+    public void threadSleep() throws Exception {
         int millis = 1000;
         long start = System.currentTimeMillis();
 
@@ -89,7 +104,8 @@
         assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250);
     }
 
-    public void testThreadInterrupted() throws Exception {
+    @Test
+    public void threadInterrupted() throws Exception {
         Thread.currentThread().interrupt();
         try {
             Thread.sleep(0);
@@ -99,7 +115,8 @@
         }
     }
 
-    public void testThreadSleepIllegalArguments() throws Exception {
+    @Test
+    public void threadSleepIllegalArguments() throws Exception {
 
         try {
             Thread.sleep(-1);
@@ -120,7 +137,8 @@
         }
     }
 
-    public void testThreadWakeup() throws Exception {
+    @Test
+    public void threadWakeup() throws Exception {
         WakeupTestThread t1 = new WakeupTestThread();
         WakeupTestThread t2 = new WakeupTestThread();
 
@@ -135,22 +153,26 @@
         assertTrue("Threads did not finish", t1.done && t2.done);
     }
 
-    public void testContextClassLoaderIsNotNull() {
+    @Test
+    public void contextClassLoaderIsNotNull() {
         assertNotNull(Thread.currentThread().getContextClassLoader());
     }
 
-    public void testContextClassLoaderIsInherited() {
+    @Test
+    public void contextClassLoaderIsInherited() {
         Thread other = new Thread();
         assertSame(Thread.currentThread().getContextClassLoader(), other.getContextClassLoader());
     }
 
-    public void testSetPriority_unstarted() throws Exception {
+    @Test
+    public void setPriority_unstarted() {
         Thread thread = new Thread();
         checkSetPriority_inBounds_succeeds(thread);
         checkSetPriority_outOfBounds_fails(thread);
     }
 
-    public void testSetPriority_starting() throws Exception {
+    @Test
+    public void setPriority_starting() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         Thread thread = new Thread("starting thread") {
             @Override public void run() { try { latch.await(); } catch (Exception e) { } }
@@ -167,7 +189,8 @@
         thread.join();
     }
 
-    public void testSetPriority_started() throws Exception {
+    @Test
+    public void setPriority_started() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
         Thread startedThread = new Thread("started thread") {
             @Override public void run() { try { latch.await(); } catch (Exception e) { } }
@@ -179,7 +202,8 @@
         startedThread.join();
     }
 
-    public void testSetPriority_joined() throws Exception {
+    @Test
+    public void setPriority_joined() throws Exception {
         Thread joinedThread = new Thread();
         joinedThread.start();
         joinedThread.join();
@@ -223,7 +247,8 @@
         assertEquals(oldPriority, thread.getPriority()); // priority shouldn't have changed
     }
 
-    public void testUncaughtExceptionPreHandler_calledBeforeDefaultHandler() {
+    @Test
+    public void uncaughtExceptionPreHandler_calledBeforeDefaultHandler() {
         UncaughtExceptionHandler initialHandler = Mockito.mock(UncaughtExceptionHandler.class);
         UncaughtExceptionHandler defaultHandler = Mockito.mock(UncaughtExceptionHandler.class);
         InOrder inOrder = Mockito.inOrder(initialHandler, defaultHandler);
@@ -245,7 +270,8 @@
         }
     }
 
-    public void testUncaughtExceptionPreHandler_noDefaultHandler() {
+    @Test
+    public void uncaughtExceptionPreHandler_noDefaultHandler() {
         UncaughtExceptionHandler initialHandler = Mockito.mock(UncaughtExceptionHandler.class);
         UncaughtExceptionHandler originalDefaultHandler
                 = Thread.getDefaultUncaughtExceptionHandler();
@@ -266,7 +292,8 @@
     /**
      * Thread.getStackTrace() is broken. http://b/1252043
      */
-    public void testGetStackTrace() throws Exception {
+    @Test
+    public void getStackTrace() throws Exception {
         Thread t1 = new Thread("t1") {
             @Override public void run() {
                 doSomething();
@@ -294,7 +321,8 @@
      * (source-filename, line number) hard-coded in a class loaded from
      * pre-built test resources.
      */
-    public void testGetStackTrace_debugInfo() throws Exception {
+    @Test
+    public void getStackTrace_debugInfo() throws Exception {
         StackTraceElement ste = getStackTraceElement("debugInfo");
 
         // Verify that this StackTraceElement appears as we expect it to
@@ -315,7 +343,8 @@
      * a line number when debug info is missing for a method; the method is
      * declared on a class loaded from pre-built test resources.
      */
-    public void testGetStackTrace_noDebugInfo() throws Exception {
+    @Test
+    public void getStackTrace_noDebugInfo() throws Exception {
         StackTraceElement ste = getStackTraceElement("noDebugInfo");
 
         // Verify that this StackTraceElement appears as we expect it to
@@ -360,14 +389,15 @@
         // - ThreadTestHelper.{debugInfo,noDebugInfo}
         StackTraceElement result = stes[3];
 
-        // Sanity check before we return
+        // Confidence check before we return
         assertEquals(result.getClassName(), className);
         assertEquals(result.getMethodName(), methodName);
         assertFalse(result.isNativeMethod());
         return result;
     }
 
-    public void testGetAllStackTracesIncludesAllGroups() throws Exception {
+    @Test
+    public void getAllStackTracesIncludesAllGroups() throws Exception {
         final AtomicInteger visibleTraces = new AtomicInteger();
         ThreadGroup group = new ThreadGroup("1");
         Thread t2 = new Thread(group, "t2") {
@@ -383,7 +413,8 @@
     }
 
     // http://b/27748318
-    public void testNativeThreadNames() throws Exception {
+    @Test
+    public void nativeThreadNames() {
         String testResult = nativeTestNativeThreadNames();
         // Not using assertNull here because this results in a better error message.
         if (testResult != null) {
@@ -392,7 +423,8 @@
     }
 
     // http://b/29746125
-    public void testParkUntilWithUnderflowValue() throws Exception {
+    @Test
+    public void parkUntilWithUnderflowValue() throws Exception {
         final Thread current = Thread.currentThread();
 
         // watchdog to unpark the tread in case it will be parked
@@ -424,11 +456,52 @@
         watchdog.join();
     }
 
+    private class LongParker {
+        long nanos;
+        Thread parkerThread;
+        volatile boolean shouldPark = true;
+        LongParker(long nanos) {
+            this.nanos = nanos;
+            parkerThread = new Thread() {
+                @Override public void run() {
+                    while (shouldPark) {
+                        LockSupport.parkNanos(nanos);
+                    }
+                }
+            };
+            parkerThread.start();
+        }
+        void quit() throws InterruptedException {
+            shouldPark = false;
+            LockSupport.unpark(parkerThread);
+            parkerThread.join();
+        }
+    }
+
+    /**
+     * Test that large timeout arguments don't cause crashes. b/161006928 .
+     */
+    @Test
+    public void parkNanosHugeTimeout() throws InterruptedException {
+        for (long i = 0; i < 5; ++i) {
+            LongParker p = new LongParker(Long.MAX_VALUE - 800_000_000L * i);
+            Thread.sleep(10);
+            p.quit();
+        }
+        for (long i = 0; i < 5; ++i) {
+            LongParker p = new LongParker(Long.MAX_VALUE - 800_000_000_000_000_000L * i);
+            Thread.sleep(10);
+            p.quit();
+        }
+    }
+
+
     /**
      * Check that call Thread.start for already started thread
      * throws {@code IllegalThreadStateException}
      */
-    public void testThreadDoubleStart() {
+    @Test
+    public void threadDoubleStart() {
         final ReentrantLock lock = new ReentrantLock();
         Thread thread = new Thread() {
             public void run() {
@@ -460,7 +533,8 @@
      * Check that call Thread.start for already finished thread
      * throws {@code IllegalThreadStateException}
      */
-    public void testThreadRestart() {
+    @Test
+    public void threadRestart() {
         Thread thread = new Thread();
         thread.start();
         try {
@@ -474,6 +548,18 @@
         }
     }
 
+    @Test
+    public void resume_shouldThrowUnsupportedOperationException() {
+        Thread thread = new Thread();
+
+        try {
+            thread.resume();
+            fail();
+        } catch (UnsupportedOperationException ignored) {
+            // expected
+        }
+    }
+
     // This method returns {@code null} if all tests pass, or a non-null String containing
     // failure details if an error occured.
     private static native String nativeTestNativeThreadNames();
@@ -489,7 +575,7 @@
     }
 
     private class WakeupTestThread extends Thread {
-        public boolean done;
+        public volatile boolean done;
 
         public void run() {
             done = false;
diff --git a/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java b/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java
new file mode 100644
index 0000000..1ea57ab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/UnicodeScriptTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.Character.UnicodeScript;
+
+@RunWith(JUnit4.class)
+public class UnicodeScriptTest {
+
+    @Test
+    public void forName_shouldThrowIllegalArgumentException_whenNameIsUnknown() {
+        try {
+            UnicodeScript.forName("NON EXISTING SCRIPT NAME");
+            fail();
+        } catch (IllegalArgumentException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void forName_shouldThrowNPE_whenNullIsPassed() {
+        try {
+            UnicodeScript.forName(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void forName_shouldAcceptAllEnumValues() {
+        for (UnicodeScript unicodeScript : UnicodeScript.values()) {
+            assertEquals(unicodeScript, UnicodeScript.forName(unicodeScript.name()));
+        }
+    }
+
+    @Test
+    public void of_shouldThrowIllegalArgumentException_whenInvalidUnicodePointPassed() {
+        try {
+            UnicodeScript.of(-1);
+            fail();
+        } catch (IllegalArgumentException ignored) {
+            // expected
+        }
+
+        try {
+            UnicodeScript.of(Character.MAX_CODE_POINT + 1);
+            fail();
+        } catch (IllegalArgumentException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void of_onWellKnownScripts() {
+        int asciiZero = '\u0030';
+        assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiZero));
+        int asciiA = '\u0041';
+        assertEquals(UnicodeScript.LATIN, UnicodeScript.of(asciiA));
+        int asciiTilda = '\u007E';
+        assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiTilda));
+        int asciiGbp = '\u00A3';
+        assertEquals(UnicodeScript.COMMON, UnicodeScript.of(asciiGbp));
+        int greekCapitalAlpha = '\u0391';
+        assertEquals(UnicodeScript.GREEK, UnicodeScript.of(greekCapitalAlpha));
+        int cyrillicCapitalA = '\u0410';
+        assertEquals(UnicodeScript.CYRILLIC, UnicodeScript.of(cyrillicCapitalA));
+        assertEquals(UnicodeScript.HAN, UnicodeScript.of('\u4E00'));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java b/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java
new file mode 100644
index 0000000..268584f
--- /dev/null
+++ b/luni/src/test/java/libcore/java/lang/VirtualMachineErrorTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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.lang;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class VirtualMachineErrorTest {
+    @Test
+    public void constructorLThrowable() {
+        Throwable cause = new Exception("cause");
+        VirtualMachineError error = new TestVirtualMachineError(cause);
+
+        assertEquals(cause, error.getCause());
+        assertEquals("java.lang.Exception: cause", error.getMessage());
+    }
+
+    @Test
+    public void constructorLThrowable_withNull() {
+        VirtualMachineError error = new TestVirtualMachineError(null /* cause */);
+
+        assertNull(error.getCause());
+        assertNull(error.getMessage());
+    }
+
+    private static final class TestVirtualMachineError extends VirtualMachineError {
+        public TestVirtualMachineError(Throwable cause) {
+            super(cause);
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java b/luni/src/test/java/libcore/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
index 7e3e982..c428fda 100644
--- a/luni/src/test/java/libcore/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
+++ b/luni/src/test/java/libcore/java/lang/annotation/AnnotationTypeMismatchExceptionTest.java
@@ -29,18 +29,4 @@
         assertSame(m, ex.element());
         assertEquals("poop", ex.foundType());
     }
-
-    public void testSerialization() throws Exception {
-        Method m = String.class.getMethod("length");
-        AnnotationTypeMismatchException original = new AnnotationTypeMismatchException(m, "poop");
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        try {
-            // AnnotationTypeMismatchException is broken: it's Serializable but has a non-transient
-            // non-serializable field of type Method.
-            new ObjectOutputStream(out).writeObject(original);
-            fail();
-        } catch (NotSerializableException expected) {
-        }
-    }
 }
diff --git a/luni/src/test/java/libcore/java/lang/invoke/CallSitesTest.java b/luni/src/test/java/libcore/java/lang/invoke/CallSitesTest.java
index 5ba87f9..5debdcb 100644
--- a/luni/src/test/java/libcore/java/lang/invoke/CallSitesTest.java
+++ b/luni/src/test/java/libcore/java/lang/invoke/CallSitesTest.java
@@ -69,7 +69,7 @@
         MutableCallSite site = new MutableCallSite(type);
         assertEquals(type, site.type());
         try {
-            int dummy = (int) site.getTarget().invokeExact(1, 1);
+            int fake = (int) site.getTarget().invokeExact(1, 1);
             fail();
         } catch (IllegalStateException e) {
             assertEquals("uninitialized call site", e.getMessage());
@@ -85,7 +85,7 @@
         VolatileCallSite site = new VolatileCallSite(type);
         assertEquals(type, site.type());
         try {
-            int dummy = (int) site.getTarget().invokeExact(1, 1);
+            int fake = (int) site.getTarget().invokeExact(1, 1);
             fail();
         } catch (IllegalStateException e) {
             assertEquals("uninitialized call site", e.getMessage());
diff --git a/luni/src/test/java/libcore/java/lang/invoke/MethodHandleCombinersTest.java b/luni/src/test/java/libcore/java/lang/invoke/MethodHandleCombinersTest.java
index a8cfa24..aa3e983 100644
--- a/luni/src/test/java/libcore/java/lang/invoke/MethodHandleCombinersTest.java
+++ b/luni/src/test/java/libcore/java/lang/invoke/MethodHandleCombinersTest.java
@@ -1357,7 +1357,7 @@
         } catch (WrongMethodTypeException expected) {
         }
 
-        // Sanity checks on other array types.
+        // Checks on other array types.
 
         MethodHandle target = MethodHandles.lookup().findStatic(
                 MethodHandleCombinersTest.class, "collectBoolean",
diff --git a/luni/src/test/java/libcore/java/lang/invoke/MethodHandlesTest.java b/luni/src/test/java/libcore/java/lang/invoke/MethodHandlesTest.java
index 8e08a59..973c994 100644
--- a/luni/src/test/java/libcore/java/lang/invoke/MethodHandlesTest.java
+++ b/luni/src/test/java/libcore/java/lang/invoke/MethodHandlesTest.java
@@ -1212,14 +1212,14 @@
 
         // boolean -> int
         try {
-            int dummy = (int) mh.invoke("True");
+            int fake = (int) mh.invoke("True");
             fail();
         } catch (WrongMethodTypeException expected) {
         }
 
         // boolean -> Integer
         try {
-            Integer dummy = (Integer) mh.invoke("True");
+            Integer fake = (Integer) mh.invoke("True");
             fail();
         } catch (WrongMethodTypeException expected) {
         }
@@ -1232,14 +1232,14 @@
 
         // Boolean -> int
         try {
-            int dummy = (int) mh.invoke(false);
+            int fake = (int) mh.invoke(false);
             fail();
         } catch (WrongMethodTypeException expected) {
         }
 
         // Boolean -> Integer
         try {
-            Integer dummy = (Integer) mh.invoke("True");
+            Integer fake = (Integer) mh.invoke("True");
             fail();
         } catch (WrongMethodTypeException expected) {
         }
diff --git a/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java b/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
index fba4781..399b360 100644
--- a/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
+++ b/luni/src/test/java/libcore/java/lang/ref/ReferenceQueueTest.java
@@ -36,6 +36,19 @@
         }
     }
 
+    /**
+     * Check that an actual execution time in msecs is "close enough" to expected.
+     * In general things should not finish early, so we allow little slop in that direction.
+     * However things can easily get delayed, so we allow more slop in that direction.
+     */
+    private void checkDuration(long expected, long actual) {
+        // The main need for slack is because tasks may not get scheduled right
+        // away. This is independent of the sleep/wait time, so we're using
+        // absolute rather than relative tolerances here.
+        assertTrue("Duration too short: " + actual + "ms", actual > expected - 10);
+        assertTrue("Duration too long: " + actual + "ms", actual < expected + 450);
+    }
+
     public void testRemoveWithVeryLargeTimeout() throws Exception {
         ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
         enqueueLater(referenceQueue, 500);
@@ -53,11 +66,12 @@
             }
         }, 500);
 
-        long startNanos = System.nanoTime();
-        referenceQueue.remove(1000);
-        long durationNanos = System.nanoTime() - startNanos;
-        long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
-        assertTrue(durationMillis > 750 && durationMillis < 1250);
+        final long startNanos = System.nanoTime();
+        final long timeoutMsec = 1000L;
+        referenceQueue.remove(timeoutMsec);
+        final long durationNanos = System.nanoTime() - startNanos;
+        final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
+        checkDuration(timeoutMsec, durationMillis);
     }
 
     public void testRemoveWithImmediateResultAndNoTimeout() throws Exception {
@@ -74,22 +88,30 @@
 
     public void testRemoveWithDelayedResultAndNoTimeout() throws Exception {
         ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
-        enqueueLater(referenceQueue, 500);
-        long startNanos = System.nanoTime();
-        referenceQueue.remove();
-        long durationNanos = System.nanoTime() - startNanos;
-        long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
-        assertTrue(durationMillis > 250 && durationMillis < 750);
+        final long enqueueDelayMsec = 500L;
+        final long startNanos = System.nanoTime();
+        enqueueLater(referenceQueue, enqueueDelayMsec);
+        Object result = referenceQueue.remove();
+        assertNotNull(result);
+        final long durationNanos = System.nanoTime() - startNanos;
+        final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
+        checkDuration(enqueueDelayMsec, durationMillis);
     }
 
     public void testRemoveWithDelayedResultAndTimeout() throws Exception {
         ReferenceQueue<Object> referenceQueue = new ReferenceQueue<Object>();
-        enqueueLater(referenceQueue, 500);
-        long startNanos = System.nanoTime();
-        referenceQueue.remove(1000);
-        long durationNanos = System.nanoTime() - startNanos;
-        long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
-        assertTrue(durationMillis > 250 && durationMillis < 750);
+        final long enqueueDelayMsec = 500L;
+        final long startNanos = System.nanoTime();
+        enqueueLater(referenceQueue, enqueueDelayMsec);
+        Object result = referenceQueue.remove(1000);
+        if (result == null) {
+          // Also report the actual queue status.
+          assertNotNull(referenceQueue.poll());
+          assertNotNull(result);
+        }
+        final long durationNanos = System.nanoTime() - startNanos;
+        final long durationMillis = TimeUnit.NANOSECONDS.toMillis(durationNanos);
+        checkDuration(enqueueDelayMsec, durationMillis);
     }
 
     public void testCleanersCleaned() {
@@ -120,13 +142,13 @@
         assertTrue(countedDown);
     }
 
-    private void runLater(Runnable runnable, int delayMillis) {
-        ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
+    private void runLater(Runnable runnable, long delayMillis) {
+        final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
         executor.schedule(runnable, delayMillis, TimeUnit.MILLISECONDS);
         executor.shutdown();
     }
 
-    private void enqueueLater(final ReferenceQueue<Object> queue, int delayMillis) {
+    private void enqueueLater(final ReferenceQueue<Object> queue, long delayMillis) {
         runLater(new Runnable() {
             @Override public void run() {
                 enqueue(queue);
diff --git a/luni/src/test/java/libcore/java/math/BigIntegerTest.java b/luni/src/test/java/libcore/java/math/BigIntegerTest.java
index 6c1d11e..4cb5ced 100644
--- a/luni/src/test/java/libcore/java/math/BigIntegerTest.java
+++ b/luni/src/test/java/libcore/java/math/BigIntegerTest.java
@@ -199,14 +199,14 @@
     private void try_gcd_variants(BigInteger arg1, BigInteger arg2, BigInteger result)
             throws Exception {
         // Test both argument orders, and all 4 combinations of negation.
-        assertEquals(arg1.gcd(arg2), result);
-        assertEquals(arg2.gcd(arg1), result);
-        assertEquals(arg1.negate().gcd(arg2), result);
-        assertEquals(arg2.gcd(arg1.negate()), result);
-        assertEquals(arg1.gcd(arg2.negate()), result);
-        assertEquals(arg2.negate().gcd(arg1), result);
-        assertEquals(arg1.negate().gcd(arg2.negate()), result);
-        assertEquals(arg2.negate().gcd(arg1.negate()), result);
+        assertEquals(result, arg1.gcd(arg2));
+        assertEquals(result, arg2.gcd(arg1));
+        assertEquals(result, arg1.negate().gcd(arg2));
+        assertEquals(result, arg2.gcd(arg1.negate()));
+        assertEquals(result, arg1.gcd(arg2.negate()));
+        assertEquals(result, arg2.negate().gcd(arg1));
+        assertEquals(result, arg1.negate().gcd(arg2.negate()));
+        assertEquals(result, arg2.negate().gcd(arg1.negate()));
     }
 
     /**
@@ -226,4 +226,91 @@
         try_gcd_variants(large, BigInteger.valueOf(5), BigInteger.ONE);
         try_gcd_variants(large, BigInteger.ZERO, large);
     }
+
+    public void test_byteValueExact() throws Exception {
+        for (int i = -300; i != 300; i += 10) {
+            try {
+                assertEquals(i, BigInteger.valueOf(i).byteValueExact());
+                assertTrue("Missing byteValueExact exception on " + i,
+                        i >= Byte.MIN_VALUE && i <= Byte.MAX_VALUE);
+            } catch (ArithmeticException e) {
+                assertTrue("Unexpected byteValueExact exception on " + i,
+                        i < Byte.MIN_VALUE || i > Byte.MAX_VALUE);
+            }
+        }
+        try {
+            BigInteger.ONE.shiftLeft(1000).byteValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+        try {
+            BigInteger.ONE.negate().shiftLeft(1000).byteValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+    }
+
+    public void test_shortValueExact() throws Exception {
+        for (int i = -100_000; i != 100_000; i += 10_000) {
+            try {
+                assertEquals(i, BigInteger.valueOf(i).shortValueExact());
+                assertTrue("Missing shortValueExact exception on " + i,
+                        i >= Short.MIN_VALUE && i <= Short.MAX_VALUE);
+            } catch (ArithmeticException e) {
+                assertTrue("Unexpected shortValueExact exception on " + i,
+                        i < Short.MIN_VALUE || i > Short.MAX_VALUE);
+            }
+        }
+        try {
+            BigInteger.ONE.shiftLeft(1000).shortValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+        try {
+            BigInteger.ONE.negate().shiftLeft(1000).shortValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+    }
+
+    public void test_intValueExact() throws Exception {
+        for (long i = -10_000_000_000L; i != 10_000_000_000L; i += 1_000_000_000L) {
+            try {
+                assertEquals(i, BigInteger.valueOf(i).intValueExact());
+                assertTrue("Missing intValueExact exception on " + i,
+                        i >= Integer.MIN_VALUE && i <= Integer.MAX_VALUE);
+            } catch (ArithmeticException e) {
+                assertTrue("Unexpected intValueExact exception on " + i,
+                        i < Integer.MIN_VALUE || i > Integer.MAX_VALUE);
+            }
+        }
+        try {
+            BigInteger.ONE.shiftLeft(1000).intValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+        try {
+            BigInteger.ONE.negate().shiftLeft(1000).intValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+    }
+
+    public void test_longValueExact() throws Exception {
+        BigInteger min = BigInteger.valueOf(Long.MIN_VALUE);
+        BigInteger max = BigInteger.valueOf(Long.MAX_VALUE);
+        for (long i = -16; i != 16; ++i) {
+            BigInteger big = BigInteger.valueOf(i).shiftLeft(61);
+            try {
+                assertEquals(i << 61, big.longValueExact());
+                assertTrue("Missing longValueExact exception on " + i,
+                        big.compareTo(min) >= 0 && big.compareTo(max) <= 0);
+            } catch (ArithmeticException e) {
+                assertTrue("Unexpected longValueExact exception on " + i,
+                        big.compareTo(min) < 0 || big.compareTo(max) > 0);
+            }
+        }
+        try {
+            BigInteger.ONE.shiftLeft(1000).longValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+        try {
+            BigInteger.ONE.negate().shiftLeft(1000).longValueExact();
+            fail("Expected ArithmeticException");
+        } catch (ArithmeticException e) {}
+    }
 }
diff --git a/luni/src/test/java/libcore/java/net/AbstractCookiesTest.java b/luni/src/test/java/libcore/java/net/AbstractCookiesTest.java
index 77eb571..7c47206 100644
--- a/luni/src/test/java/libcore/java/net/AbstractCookiesTest.java
+++ b/luni/src/test/java/libcore/java/net/AbstractCookiesTest.java
@@ -1310,16 +1310,16 @@
                 new String[][] { cookies[0], cookies[1] }, responseHeaders,
                 null);
 
-        HashMap<String, List<String>> dummyMap = new HashMap<String, List<String>>();
+        HashMap<String, List<String>> fakeMap = new HashMap<String, List<String>>();
         Map<String, List<String>> map = manager.get(new URI("http://a.b.c/"),
-                dummyMap);
+                fakeMap);
 
         assertEquals(1, map.size());
         List<String> list = map.get("Cookie");
         assertEquals(1, list.size());
 
         // requires path of cookie is the prefix of uri
-        map = manager.get(new URI("http://a.b.c/te"), dummyMap);
+        map = manager.get(new URI("http://a.b.c/te"), fakeMap);
         list = map.get("Cookie");
         assertEquals(1, list.size());
         assertTrue(list.get(0).contains("PREF=test"));
@@ -1330,7 +1330,7 @@
         // ,no matter the value cookie-key
         responseHeaders = addCookie(new String[][] { cookies[2] });
         manager = store(new String[][] { cookies[2] }, responseHeaders, null);
-        map = manager.get(new URI("http://a.beg.com/test"), dummyMap);
+        map = manager.get(new URI("http://a.beg.com/test"), fakeMap);
         list = map.get("Cookie");
         assertEquals(1, list.size());
         assertTrue(list.get(0).startsWith("$Version=\"1\""));
@@ -1390,9 +1390,9 @@
      * @since 1.6
      */
     public void testCookieManager_LCookieStore_LCookiePolicy() {
-        class DummyStore implements CookieStore {
+        class FakeStore implements CookieStore {
             public String getName() {
-                return "A dummy store";
+                return "A fake store";
             }
 
             public void add(URI uri, HttpCookie cookie) {
@@ -1419,10 +1419,10 @@
                 return false;
             }
         }
-        CookieStore store = new DummyStore();
+        CookieStore store = new FakeStore();
         CookieManager cookieManager = new CookieManager(store,
                 CookiePolicy.ACCEPT_ALL);
-        assertEquals("A dummy store", ((DummyStore) cookieManager
+        assertEquals("A fake store", ((FakeStore) cookieManager
                 .getCookieStore()).getName());
         assertSame(store, cookieManager.getCookieStore());
     }
diff --git a/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
index 74948f6..b3855ec 100644
--- a/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
@@ -141,7 +141,7 @@
         URL fileUrl = addFileEntry(FILE_PATH, fileContents);
         URLConnection connection = fileUrl.openConnection(proxy);
         assertContents(fileContents, connection.getInputStream());
-        // Sanity check that NO_PROXY covers the Type.DIRECT case
+        // Check that NO_PROXY covers the Type.DIRECT case
         assertEquals(Proxy.Type.DIRECT, proxy.type());
     }
 
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index 6bbfe01..7d59ec0 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -266,9 +266,9 @@
     public void test_isReachable_neverThrows() throws Exception {
         InetAddress inetAddress = InetAddress.getByName("www.google.com");
 
-        final NetworkInterface netIf = NetworkInterface.getByName("dummy0");
+        final NetworkInterface netIf = NetworkInterface.getByName("fake0");
         if (netIf == null) {
-            System.logI("Skipping test_isReachable_neverThrows because dummy0 isn't available");
+            System.logI("Skipping test_isReachable_neverThrows because fake0 isn't available");
             return;
         }
 
diff --git a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
index f0f79ad..555654e 100644
--- a/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
+++ b/luni/src/test/java/libcore/java/net/NetworkInterfaceTest.java
@@ -17,6 +17,7 @@
 package libcore.java.net;
 
 import junit.framework.TestCase;
+import org.mockito.Mockito;
 
 import android.system.StructIfaddrs;
 import java.io.BufferedReader;
@@ -39,6 +40,7 @@
 import java.util.regex.Pattern;
 import libcore.io.IoUtils;
 import libcore.io.Libcore;
+import libcore.io.Os;
 
 import static android.system.OsConstants.AF_INET;
 import static android.system.OsConstants.IFF_LOOPBACK;
@@ -48,6 +50,7 @@
 import static android.system.OsConstants.IFF_UP;
 import static android.system.OsConstants.SOCK_DGRAM;
 import static java.net.NetworkInterface.getNetworkInterfaces;
+import static org.mockito.ArgumentMatchers.anyString;
 
 public class NetworkInterfaceTest extends TestCase {
     // http://code.google.com/p/android/issues/detail?id=13784
@@ -221,6 +224,29 @@
         assertEquals(ifaddrsNames, actualNiNames);
     }
 
+    // Validate that we don't fail to enumerate interfaces if there is virtual interface without parent interface present.
+    // b/159277702
+    public void testGetNetworkInterfaces_OrphanInterfaceDoesNotThrow() throws Exception {
+        Os originalOs = Libcore.getOs();
+        Os mockOs = Mockito.mock(Os.class);
+
+        try {    
+            Mockito.when(mockOs.getifaddrs()).thenReturn(new StructIfaddrs[] {
+                new StructIfaddrs("dummy0:1", 0, null, null, null, null),
+            });
+
+            Mockito.when(mockOs.if_nametoindex(anyString())).thenReturn(1);
+
+            assertTrue("Failed to swap OS implementation", Libcore.compareAndSetOs(originalOs, mockOs));
+
+            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
+            assertEquals(1, Collections.list(interfaces).size());
+        }
+        finally {
+            assertTrue("Failed to revert OS implementation", Libcore.compareAndSetOs(mockOs, originalOs));
+        }
+    }
+
     // Calling getSubInterfaces on interfaces with no subinterface should not throw NPE.
     // http://b/33844501
     public void testGetSubInterfaces() throws Exception {
diff --git a/luni/src/test/java/libcore/java/net/OldSocketTest.java b/luni/src/test/java/libcore/java/net/OldSocketTest.java
index 644fe52..f28edd0 100644
--- a/luni/src/test/java/libcore/java/net/OldSocketTest.java
+++ b/luni/src/test/java/libcore/java/net/OldSocketTest.java
@@ -1621,7 +1621,7 @@
         // run these tests. For now run on all platforms until we find those
         // that do not support urgent data
         String platform = System.getProperty("os.name");
-        if (!platform.equals("Dummy")) {
+        if (!platform.equals("Fake")) {
             // validate that when OOBInline is false that any urgent data
             // is silently ignored
             String urgentData = "U";
diff --git a/luni/src/test/java/libcore/java/net/ServerSocketConcurrentCloseTest.java b/luni/src/test/java/libcore/java/net/ServerSocketConcurrentCloseTest.java
index 4171062..397ad359 100644
--- a/luni/src/test/java/libcore/java/net/ServerSocketConcurrentCloseTest.java
+++ b/luni/src/test/java/libcore/java/net/ServerSocketConcurrentCloseTest.java
@@ -167,8 +167,8 @@
                         + "Server thread's stackTrace: " + serverStackTrace);
             }
             assertTrue(serverRunnable.isShutdown());
-            // Sanity check to ensure the threads don't live into the next iteration. This should
-            // be quick because we only get here if shutdownLatch reached 0 within the time limit.
+            // Ensure the threads don't live into the next iteration. This should be quick because
+            // we only get here if shutdownLatch reached 0 within the time limit.
             serverThread.join();
             clientThread.join();
             return serverRunnable.numSuccessfulConnections.get();
diff --git a/luni/src/test/java/libcore/java/net/SocketTest.java b/luni/src/test/java/libcore/java/net/SocketTest.java
index 3e1c1a6..df12a29 100644
--- a/luni/src/test/java/libcore/java/net/SocketTest.java
+++ b/luni/src/test/java/libcore/java/net/SocketTest.java
@@ -598,13 +598,12 @@
     public void testSocketTestAllAddresses() throws Exception {
         // Socket Ctor should try all sockets.
         //
-        // This test creates a server socket bound to 127.0.0.1 or ::1 only, and connects using a
+        // This test creates server sockets bound to 127.0.0.1 and ::1, and connects using a
         // hostname that resolves to both addresses. We should be able to connect to the server
         // socket in either setup.
         final String loopbackHost = ALL_LOOPBACK_HOSTNAME;
 
-        assertTrue("Loopback DNS record is unreachable or is invalid.", checkLoopbackHost(
-                loopbackHost));
+        checkLoopbackHost(loopbackHost);
 
         final int port = 9999;
         for (InetAddress addr : new InetAddress[]{ Inet4Address.LOOPBACK, Inet6Address.LOOPBACK }) {
@@ -622,15 +621,16 @@
         }
     }
 
-    /** Confirm the supplied hostname maps to only loopback addresses. */
-    private static boolean checkLoopbackHost(String host) {
-        try {
-            List<InetAddress> addrs = Arrays.asList(InetAddress.getAllByName(host));
-            return addrs.stream().allMatch(InetAddress::isLoopbackAddress) &&
-                    addrs.contains(Inet4Address.LOOPBACK) && addrs.contains(Inet6Address.LOOPBACK);
-        } catch (UnknownHostException e) {
-            return false;
-        }
+    /** Confirm the supplied hostname maps to only loopback addresses, both IPv4 and IPv6. */
+    private static void checkLoopbackHost(String host) throws UnknownHostException {
+        InetAddress[] addrArray = InetAddress.getAllByName(host);
+        final String addressesString = Arrays.toString(addrArray);
+        List<InetAddress> addrs = Arrays.asList(addrArray);
+        final String msg = ALL_LOOPBACK_HOSTNAME
+                + " must only return loopback addresses, both IPv4 and IPv6. Got: "
+                + addressesString;
+        assertTrue(msg, addrs.stream().allMatch(InetAddress::isLoopbackAddress)
+                && addrs.contains(Inet4Address.LOOPBACK) && addrs.contains(Inet6Address.LOOPBACK));
     }
 
     private static boolean canConnect(String host, int port) {
diff --git a/luni/src/test/java/libcore/java/net/URLConnectionTest.java b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
index ddd447a..aecc1ad 100644
--- a/luni/src/test/java/libcore/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/libcore/java/net/URLConnectionTest.java
@@ -900,9 +900,9 @@
 
     @Test public void getFileNameMap_compositeExtension_customMimeMap() {
         MimeMap testMimeMap = MimeMap.builder()
-                .put("text/html", "html")
-                .put("application/gzip", "gz")
-                .put("application/tar+gzip", "tar.gz")
+                .addMimeMapping("text/html", "html")
+                .addMimeMapping("application/gzip", "gz")
+                .addMimeMapping("application/tar+gzip", "tar.gz")
                 .build();
         MimeMap defaultMimeMap = MimeMap.getDefault();
         MimeMap.setDefaultSupplier(() -> testMimeMap);
@@ -3176,7 +3176,7 @@
      * Android has its own API / implementation for certificate pinning. We can't
      * easily test that there is *no* code path that would invoke OkHttp's certificate
      * pinning logic, so this test only covers the *common* code path of a
-     * HttpsURLConnection as a sanity check.
+     * HttpsURLConnection as a confidence check.
      *
      * <p>To check whether OkHttp performs certificate pinning under the hood, this
      * test disables two {@link Platform} methods. In OkHttp 2.7.5, these two methods
diff --git a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
index 24fdc74..a151da3 100644
--- a/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
+++ b/luni/src/test/java/libcore/java/nio/channels/DatagramChannelMulticastTest.java
@@ -36,6 +36,8 @@
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.concurrent.TimeUnit;
+import java.net.ProtocolFamily;
+import java.net.StandardProtocolFamily;
 
 import libcore.io.IoBridge;
 
@@ -83,7 +85,7 @@
     @Override
     protected void setUp() throws Exception {
         // The loopback interface isn't actually useful for sending/receiving multicast messages
-        // but it can be used as a dummy for tests where that does not matter.
+        // but it can be used as a fake for tests where that does not matter.
         loopbackInterface = NetworkInterface.getByInetAddress(InetAddress.getLoopbackAddress());
         assertNotNull(loopbackInterface);
         assertTrue(loopbackInterface.isLoopback());
@@ -219,25 +221,25 @@
     }
 
     public void test_joinAnySource_IPv4() throws Exception {
-        check_joinAnySource(GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4, ipv4NetworkInterface);
+        check_joinAnySource(GOOD_MULTICAST_IPv4, BAD_MULTICAST_IPv4, ipv4NetworkInterface, StandardProtocolFamily.INET);
     }
 
     public void test_joinAnySource_IPv6() throws Exception {
-        check_joinAnySource(GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6, ipv6NetworkInterface);
+        check_joinAnySource(GOOD_MULTICAST_IPv6, BAD_MULTICAST_IPv6, ipv6NetworkInterface, StandardProtocolFamily.INET6);
     }
 
     private void check_joinAnySource(InetAddress group, InetAddress group2,
-            NetworkInterface networkInterface) throws Exception {
+            NetworkInterface networkInterface, ProtocolFamily protocolFamily) throws Exception {
         if (!supportsMulticast) {
             return;
         }
         // Set up a receiver join the group on ipv4NetworkInterface
-        DatagramChannel receiverChannel = createReceiverChannel();
+        DatagramChannel receiverChannel = createReceiverChannel(protocolFamily);
         InetSocketAddress localAddress = (InetSocketAddress) receiverChannel.getLocalAddress();
         receiverChannel.join(group, networkInterface);
 
         String msg = "Hello World";
-        createChannelAndSendMulticastMessage(group, localAddress.getPort(), msg, networkInterface);
+        createChannelAndSendMulticastMessage(group, localAddress.getPort(), msg, networkInterface, protocolFamily);
 
         // now verify that we received the data as expected
         ByteBuffer recvBuffer = ByteBuffer.allocate(100);
@@ -247,7 +249,7 @@
         // now verify that we didn't receive the second message
         String msg2 = "Hello World - Different Group";
         createChannelAndSendMulticastMessage(
-                group2, localAddress.getPort(), msg2, networkInterface);
+                group2, localAddress.getPort(), msg2, networkInterface, protocolFamily);
         recvBuffer.position(0);
         checkNoDatagramReceived(receiverChannel);
 
@@ -396,6 +398,13 @@
         return dc;
     }
 
+    private DatagramChannel createReceiverChannel(ProtocolFamily protocolFamily) throws Exception {
+        DatagramChannel dc = DatagramChannel.open(protocolFamily);
+        dc.bind(null /* leave the OS to determine the port, and use the wildcard address */);
+        configureChannelForReceiving(dc);
+        return dc;
+    }
+
     public void test_joinAnySource_multiple_joins_IPv4()
             throws Exception {
         check_joinAnySource_multiple_joins(GOOD_MULTICAST_IPv4, ipv4NetworkInterface);
@@ -425,21 +434,21 @@
     }
 
     public void test_joinAnySource_multicastLoopOption_IPv4() throws Exception {
-        check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv4, ipv4NetworkInterface);
+        check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv4, ipv4NetworkInterface, StandardProtocolFamily.INET);
     }
 
     public void test_multicastLoopOption_IPv6() throws Exception {
-        check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv6, ipv6NetworkInterface);
+        check_joinAnySource_multicastLoopOption(GOOD_MULTICAST_IPv6, ipv6NetworkInterface, StandardProtocolFamily.INET6);
     }
 
     private void check_joinAnySource_multicastLoopOption(InetAddress group,
-            NetworkInterface networkInterface) throws Exception {
+            NetworkInterface networkInterface, ProtocolFamily protocolFamily) throws Exception {
         if (!supportsMulticast) {
             return;
         }
         final String message = "Hello, world!";
 
-        DatagramChannel dc = createReceiverChannel();
+        DatagramChannel dc = createReceiverChannel(protocolFamily);
         dc.setOption(StandardSocketOptions.IP_MULTICAST_LOOP, true /* enable loop */);
         dc.setOption(StandardSocketOptions.IP_MULTICAST_IF, networkInterface);
         configureChannelForReceiving(dc);
@@ -1290,6 +1299,17 @@
         dc.close();
     }
 
+
+    private static void createChannelAndSendMulticastMessage(
+            InetAddress group, int port, String msg, NetworkInterface sendingInterface, ProtocolFamily protocolFamily)
+            throws IOException {
+        // Any datagram socket can send to a group. It does not need to have joined the group.
+        DatagramChannel dc = DatagramChannel.open(protocolFamily);
+        BindableChannel channel = new BindableChannel(dc, sendingInterface);
+        channel.sendMulticastMessage(msg, new InetSocketAddress(group, port));
+        dc.close();
+    }
+
     /**
      * A {@link DatagramChannel} which is optionally bound to a {@link NetworkInterface}.
      */
diff --git a/luni/src/test/java/libcore/java/nio/file/LinkPermissionTest.java b/luni/src/test/java/libcore/java/nio/file/LinkPermissionTest.java
index a0e75fe..c289271 100644
--- a/luni/src/test/java/libcore/java/nio/file/LinkPermissionTest.java
+++ b/luni/src/test/java/libcore/java/nio/file/LinkPermissionTest.java
@@ -25,7 +25,7 @@
     public void test_constructor$String() {
         // Only "hard" and "symbolic" are the supported permission target names.
         LinkPermission linkPermission = new LinkPermission("hard");
-        // Sanity check that getName() doesn't throw.
+        // Check that getName() doesn't throw.
         linkPermission.getName();
 
         linkPermission = new LinkPermission("symbolic");
diff --git a/luni/src/test/java/libcore/java/nio/file/LinuxPathTest.java b/luni/src/test/java/libcore/java/nio/file/LinuxPathTest.java
index 458804c5..55e5f81f 100644
--- a/luni/src/test/java/libcore/java/nio/file/LinuxPathTest.java
+++ b/luni/src/test/java/libcore/java/nio/file/LinuxPathTest.java
@@ -59,35 +59,35 @@
     /**
      * CTS doesn't allow creating files in the test directory, however, Vogar allows creation of
      * new files in the test directory. Therefore, for the tests which don't require write
-     * permission, dummyPath would serve the purpose, however, for the others, {@link
+     * permission, fakePath would serve the purpose, however, for the others, {@link
      * FilesSetup#getTestDirPath()} should be used.
      */
-    private static final Path dummyPath = Paths.get("dummyPath");
+    private static final Path fakePath = Paths.get("fakePath");
 
     @Test
     public void test_getFileSystem() {
-        assertTrue(dummyPath.getFileSystem().provider() instanceof
+        assertTrue(fakePath.getFileSystem().provider() instanceof
                 sun.nio.fs.LinuxFileSystemProvider);
     }
 
     @Test
     public void test_isAbsolute() {
-        assertFalse(dummyPath.isAbsolute());
-        Path absolutePath = dummyPath.toAbsolutePath();
+        assertFalse(fakePath.isAbsolute());
+        Path absolutePath = fakePath.toAbsolutePath();
         assertTrue(absolutePath.isAbsolute());
     }
 
     @Test
     public void test_getRoot() {
-        assertEquals(Paths.get("/"), dummyPath.toAbsolutePath().getRoot());
-        assertNull(dummyPath.getRoot());
+        assertEquals(Paths.get("/"), fakePath.toAbsolutePath().getRoot());
+        assertNull(fakePath.getRoot());
     }
 
     @Test
     public void test_getFileName() {
-        assertEquals(dummyPath, dummyPath.getFileName());
-        assertEquals(dummyPath, dummyPath.toAbsolutePath().getFileName());
-        assertNull(dummyPath.getRoot());
+        assertEquals(fakePath, fakePath.getFileName());
+        assertEquals(fakePath, fakePath.toAbsolutePath().getFileName());
+        assertNull(fakePath.getRoot());
         assertEquals(Paths.get("data"), Paths.get("/data").getFileName());
         assertEquals(Paths.get("data"), Paths.get("/data/").getFileName());
         assertEquals(Paths.get(".."), Paths.get("/data/dir1/..").getFileName());
@@ -95,7 +95,7 @@
 
     @Test
     public void test_getParent() {
-        assertNull(dummyPath.getParent());
+        assertNull(fakePath.getParent());
         assertEquals(Paths.get("rootDir"), Paths.get("rootDir/dir").getParent());
     }
 
@@ -153,7 +153,7 @@
     @Test
     public void test_startsWith$String() {
         assertTrue(Paths.get("t1/t2").startsWith("t1"));
-        assertTrue(dummyPath.toAbsolutePath().startsWith("/"));
+        assertTrue(fakePath.toAbsolutePath().startsWith("/"));
         assertTrue(Paths.get("t1/t2/t3").startsWith("t1/t2"));
         assertFalse(Paths.get("t1/t2").startsWith("t2"));
     }
@@ -166,7 +166,7 @@
     @Test
     public void test_startsWith$Path() {
         assertTrue(Paths.get("t1/t2").startsWith(Paths.get("t1")));
-        assertTrue(dummyPath.toAbsolutePath().startsWith(Paths.get("/")));
+        assertTrue(fakePath.toAbsolutePath().startsWith(Paths.get("/")));
         assertTrue(Paths.get("t1/t2/t3").startsWith(Paths.get("t1/t2")));
         assertFalse(Paths.get("t1/t2").startsWith(Paths.get("t2")));
     }
@@ -226,7 +226,7 @@
 
     @Test(expected = NullPointerException.class)
     public void test_resolve$Path_NPE() {
-        dummyPath.resolve((Path)null);
+        fakePath.resolve((Path)null);
     }
 
     @Test
@@ -240,7 +240,7 @@
 
     @Test(expected = NullPointerException.class)
     public void test_resolve$String_NPE() {
-        dummyPath.resolve((String)null);
+        fakePath.resolve((String)null);
     }
 
     @Test
@@ -255,7 +255,7 @@
 
     @Test(expected = NullPointerException.class)
     public void test_resolveSibling$String_Path() {
-        dummyPath.resolveSibling((Path) null);
+        fakePath.resolveSibling((Path) null);
     }
 
     @Test
@@ -271,7 +271,7 @@
 
     @Test(expected = NullPointerException.class)
     public void test_resolveSibling$String_NPE() {
-        dummyPath.resolveSibling((String)null);
+        fakePath.resolveSibling((String)null);
     }
 
     @Test
@@ -296,12 +296,12 @@
 
     @Test(expected = NullPointerException.class)
     public void test_relativize_NPE() {
-        dummyPath.relativize(null);
+        fakePath.relativize(null);
     }
 
     @Test
     public void test_toURI() throws URISyntaxException {
-        assertEquals(new URI("file://" + dummyPath.toAbsolutePath().toString()), dummyPath.toUri());
+        assertEquals(new URI("file://" + fakePath.toAbsolutePath().toString()), fakePath.toUri());
         assertEquals(new URI("file:///"), Paths.get("/").toUri());
         assertEquals(new URI("file:///dir/.."), Paths.get(("/dir/..")).toUri());
         assertEquals(new URI("file:///../"), Paths.get(("/..")).toUri());
@@ -314,15 +314,15 @@
 
     @Test
     public void test_toAbsolutePath() {
-        assertFalse(dummyPath.isAbsolute());
-        assertTrue(dummyPath.toAbsolutePath().isAbsolute());
+        assertFalse(fakePath.isAbsolute());
+        assertTrue(fakePath.toAbsolutePath().isAbsolute());
     }
 
     @Test
     public void test_toRealPath() throws IOException {
         // When file doesn't exist.
         try {
-            dummyPath.toRealPath();
+            fakePath.toRealPath();
             fail();
         } catch (NoSuchFileException expected) {}
         Files.createFile(filesSetup.getTestPath());
@@ -356,8 +356,8 @@
 
     @Test
     public void test_toFile() {
-        File file = dummyPath.toFile();
-        assertEquals(dummyPath.toAbsolutePath().toString(), file.getAbsolutePath());
+        File file = fakePath.toFile();
+        assertEquals(fakePath.toAbsolutePath().toString(), file.getAbsolutePath());
     }
 
     @Test
diff --git a/luni/src/test/java/libcore/java/security/AccessControlExceptionTest.java b/luni/src/test/java/libcore/java/security/AccessControlExceptionTest.java
new file mode 100644
index 0000000..e12f8fa
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/AccessControlExceptionTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.AccessControlException;
+import java.security.AllPermission;
+import java.security.Permission;
+
+@RunWith(JUnit4.class)
+public class AccessControlExceptionTest {
+
+    @Test
+    public void testConstructor() {
+        String msg = "test message";
+        Permission permission = new AllPermission();
+
+        try {
+            throw new AccessControlException(msg);
+        } catch (AccessControlException e) {
+            assertEquals(msg, e.getMessage());
+        }
+
+        try {
+            throw new AccessControlException(msg, permission);
+        } catch (AccessControlException e) {
+            assertEquals(msg, e.getMessage());
+            assertSame(permission, e.getPermission());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/AccessControllerTest.java b/luni/src/test/java/libcore/java/security/AccessControllerTest.java
index 5746abd..678be72 100644
--- a/luni/src/test/java/libcore/java/security/AccessControllerTest.java
+++ b/luni/src/test/java/libcore/java/security/AccessControllerTest.java
@@ -16,25 +16,36 @@
 
 package libcore.java.security;
 
+import static org.junit.Assert.assertEquals;
+
 import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.DomainCombiner;
 import java.security.Permission;
 import java.security.Permissions;
 import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
 import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
 /**
  * Android doesn't fully support access controller. This tests that actions are
  * passed through without permission enforcement.
  */
-public final class AccessControllerTest extends TestCase {
+@RunWith(JUnit4.class)
+public final class AccessControllerTest {
 
-    public void testDoPrivilegedWithCombiner() {
-        final Permission permission = new RuntimePermission("do stuff");
+    @Test
+    public void testDoPrivilegedWithCombiner() throws Exception {
         final DomainCombiner union = new DomainCombiner() {
             @Override
             public ProtectionDomain[] combine(ProtectionDomain[] a, ProtectionDomain[] b) {
@@ -46,28 +57,61 @@
         AccessControlContext accessControlContext = new AccessControlContext(
                 new AccessControlContext(new ProtectionDomain[] { protectionDomain }), union);
 
+        assertActionRun(action -> AccessController.doPrivileged(
+                (PrivilegedAction<Void>) action::get));
+
+        assertActionRun(action -> AccessController.doPrivileged(
+                (PrivilegedAction<Void>) action::get, accessControlContext));
+
+        assertActionRun(action -> {
+            try {
+                AccessController.doPrivileged((PrivilegedExceptionAction<Void>) action::get);
+            } catch (PrivilegedActionException e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        assertActionRun(action -> {
+            try {
+                AccessController.doPrivileged(
+                        (PrivilegedExceptionAction<Void>) action::get, accessControlContext);
+            } catch (PrivilegedActionException e) {
+                throw new RuntimeException(e);
+            }
+        });
+
+        assertActionRun(action -> AccessController.doPrivilegedWithCombiner(
+                (PrivilegedAction<Void>) action::get));
+
+        assertActionRun(action -> {
+            try {
+                AccessController.doPrivilegedWithCombiner(
+                        (PrivilegedExceptionAction<Void>) action::get);
+            } catch (PrivilegedActionException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    private static void assertActionRun(Consumer<Supplier<Void>> runner) {
+        final Permission permission = new RuntimePermission("do stuff");
+
         final AtomicInteger actionCount = new AtomicInteger();
 
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            @Override
-            public Void run() {
+        runner.accept(() -> {
+            assertEquals(null, AccessController.getContext().getDomainCombiner());
+            AccessController.getContext().checkPermission(permission);
+
+            // Calling doPrivileged again would have exercised the combiner
+            runner.accept(() -> {
+                actionCount.incrementAndGet();
                 assertEquals(null, AccessController.getContext().getDomainCombiner());
                 AccessController.getContext().checkPermission(permission);
-
-                // Calling doPrivileged again would have exercised the combiner
-                AccessController.doPrivileged(new PrivilegedAction<Void>() {
-                    @Override
-                    public Void run() {
-                        actionCount.incrementAndGet();
-                        assertEquals(null, AccessController.getContext().getDomainCombiner());
-                        AccessController.getContext().checkPermission(permission);
-                        return null;
-                    }
-                });
-
                 return null;
-            }
-        }, accessControlContext);
+            });
+
+            return null;
+        });
 
         assertEquals(1, actionCount.get());
     }
diff --git a/luni/src/test/java/libcore/java/security/AllPermissionTest.java b/luni/src/test/java/libcore/java/security/AllPermissionTest.java
new file mode 100644
index 0000000..0d4f4b2
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/AllPermissionTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.AllPermission;
+
+@RunWith(JUnit4.class)
+public class AllPermissionTest {
+
+    @Test
+    public void testGetAction() {
+        String action = "test action";
+        AllPermission permission = new AllPermission("Test permission", action);
+        // Action value is discarded and returns null here.
+        assertNull(permission.getActions());
+    }
+
+    @Test
+    public void testImplies() {
+        AllPermission permission = new AllPermission();
+        AllPermission permission2 = new AllPermission();
+        assertTrue(permission.implies(null));
+        assertTrue(permission.implies(permission));
+        assertTrue(permission.implies(permission2));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/AuthProviderTest.java b/luni/src/test/java/libcore/java/security/AuthProviderTest.java
new file mode 100644
index 0000000..ecc7da8
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/AuthProviderTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.AuthProvider;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+
+@RunWith(JUnit4.class)
+public class AuthProviderTest {
+
+    private static class TestAuthProvider extends AuthProvider {
+        final String name;
+
+        protected TestAuthProvider(String name, double version, String info) {
+            super(name, version, info);
+            this.name = name;
+        }
+
+        @Override
+        public void login(Subject subject, CallbackHandler handler) {
+        }
+
+        @Override
+        public void logout() {
+        }
+
+        @Override
+        public void setCallbackHandler(CallbackHandler handler) {
+        }
+    }
+
+    @Test
+    public void testConstructor() {
+        TestAuthProvider provider = new TestAuthProvider("test", 1.0d, "info");
+        assertEquals("test", provider.name);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/BasicPermissionTest.java b/luni/src/test/java/libcore/java/security/BasicPermissionTest.java
new file mode 100644
index 0000000..e45c3ff
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/BasicPermissionTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.AllPermission;
+import java.security.BasicPermission;
+
+@RunWith(JUnit4.class)
+public class BasicPermissionTest {
+
+    private static class TestPermission extends BasicPermission {
+        public TestPermission(String name) {
+            super(name);
+        }
+    }
+
+    @Test
+    public void testImplies() {
+        BasicPermission permission = new TestPermission("name");
+        AllPermission permission2 = new AllPermission();
+        assertTrue(permission.implies(null));
+        assertTrue(permission.implies(permission));
+        assertTrue(permission.implies(permission2));
+    }
+
+    @Test
+    public void testCheckGuard_doesntThrow() {
+        BasicPermission permission = new TestPermission("name");
+        permission.checkGuard(null);
+        permission.checkGuard(new Object());
+        permission.checkGuard(permission);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/CodeSourceTest.java b/luni/src/test/java/libcore/java/security/CodeSourceTest.java
new file mode 100644
index 0000000..01481f8
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/CodeSourceTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.KeyStore;
+import java.security.Timestamp;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+
+import sun.security.provider.certpath.X509CertPath;
+
+@RunWith(JUnit4.class)
+public class CodeSourceTest {
+
+
+    private static final String PATH = "file://invalid_cert_path";
+
+    private CodeSource codeSource;
+
+    @Before
+    public void setUp() throws Exception {
+        CodeSigner codeSigner = createCodeSigner();
+        codeSource = new CodeSource(new URL(PATH), new CodeSigner[] { codeSigner });
+    }
+
+    private static CodeSigner createCodeSigner() throws Exception {
+        KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
+        keyStore.load(null);
+        // Get a X509Certificate from the keyStore
+        X509Certificate cert = null;
+        for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements(); ) {
+            String alias = aliases.nextElement();
+            Certificate certificate = keyStore.getCertificate(alias);
+            assertTrue(certificate instanceof X509Certificate);
+            cert = (X509Certificate) certificate;
+            break;
+        }
+
+        assertNotNull(cert);
+        X509CertPath certPath = new X509CertPath(List.of(cert));
+        return new CodeSigner(certPath, new Timestamp(new Date(), certPath));
+    }
+
+    @Test
+    public void testGetCerificates() {
+        assertNull(codeSource.getCertificates());
+    }
+
+    @Test
+    public void testGetCodeSigners() {
+        assertNull(codeSource.getCodeSigners());
+    }
+
+    @Test
+    public void testGetLocation() throws MalformedURLException {
+        assertEquals(new URL(PATH), codeSource.getLocation());
+    }
+
+    @Test
+    public void testImplies() {
+        assertTrue(codeSource.implies(null));
+        assertTrue(codeSource.implies(codeSource));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/PermissionCollectionTest.java b/luni/src/test/java/libcore/java/security/PermissionCollectionTest.java
new file mode 100644
index 0000000..1fb39e6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/PermissionCollectionTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.util.Enumeration;
+
+@RunWith(JUnit4.class)
+public class PermissionCollectionTest {
+
+    private static class TestPermissionCollection extends PermissionCollection {
+
+        @Override
+        public void add(Permission permission) {
+        }
+
+        @Override
+        public boolean implies(Permission permission) {
+            return true;
+        }
+
+        @Override
+        public Enumeration<Permission> elements() {
+            return null;
+        }
+    }
+
+    @Test
+    public void testSetReadOnly() {
+        PermissionCollection permissionCollection = new TestPermissionCollection();
+        // isReadOnly() always return true
+        assertTrue(permissionCollection.isReadOnly());
+        permissionCollection.setReadOnly();
+        assertTrue(permissionCollection.isReadOnly());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/PolicySpiTest.java b/luni/src/test/java/libcore/java/security/PolicySpiTest.java
new file mode 100644
index 0000000..52d5023
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/PolicySpiTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.PolicySpi;
+import java.security.ProtectionDomain;
+
+@RunWith(JUnit4.class)
+public class PolicySpiTest {
+
+    private static class TestPolicySpi extends PolicySpi {
+
+        @Override
+        protected boolean engineImplies(ProtectionDomain domain, Permission permission) {
+            return false;
+        }
+
+        @Override
+        public void engineRefresh() {
+            super.engineRefresh();
+        }
+
+        @Override
+        public PermissionCollection engineGetPermissions(CodeSource codesource) {
+            return super.engineGetPermissions(codesource);
+        }
+
+        @Override
+        public PermissionCollection engineGetPermissions(ProtectionDomain domain) {
+            return super.engineGetPermissions(domain);
+        }
+    }
+
+    private static final TestPolicySpi spi = new TestPolicySpi();
+
+    @Test
+    public void testEngineRefresh_doesntThrow() {
+        spi.engineRefresh();
+    }
+
+    @Test
+    public void testEngineGetPermissions() {
+        assertEquals(Policy.UNSUPPORTED_EMPTY_COLLECTION,
+                spi.engineGetPermissions((CodeSource) null));
+        assertEquals(Policy.UNSUPPORTED_EMPTY_COLLECTION,
+                spi.engineGetPermissions((ProtectionDomain) null));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/PolicyTest.java b/luni/src/test/java/libcore/java/security/PolicyTest.java
new file mode 100644
index 0000000..c25b3ce
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/PolicyTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.CodeSource;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.Provider;
+
+/**
+ * Test the stub implementation of {@link Policy}.
+ */
+@RunWith(JUnit4.class)
+public class PolicyTest {
+
+    private static class TestPolicy extends Policy {
+    }
+
+    private final Policy p = new TestPolicy();
+
+    @Test
+    public void testGetInstance_alwaysReturnNull() throws Exception {
+        assertNull(Policy.getInstance(null, null));
+        assertNull(Policy.getInstance(null, null, (String) null));
+        assertNull(Policy.getInstance(null, null, (Provider) null));
+
+        Policy.setPolicy(p);
+
+        // Still return null after setPolicy()
+        assertNull(Policy.getInstance(null, null));
+        assertNull(Policy.getInstance(null, null, (String) null));
+        assertNull(Policy.getInstance(null, null, (Provider) null));
+    }
+
+    @Test
+    public void testGetParameters() {
+        assertNull(p.getParameters());
+    }
+
+    @Test
+    public void testGetPermissions() {
+        assertNull(p.getPermissions((CodeSource) null));
+        assertNull(p.getPermissions((ProtectionDomain) null));
+    }
+
+    @Test
+    public void testGetProvider() {
+        assertNull(p.getProvider());
+    }
+
+    @Test
+    public void testGetType() {
+        assertNull(p.getType());
+    }
+
+    @Test
+    public void testImplies() {
+        assertTrue(p.implies(null, null));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/ProtectionDomainTest.java b/luni/src/test/java/libcore/java/security/ProtectionDomainTest.java
new file mode 100644
index 0000000..8360a52
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/ProtectionDomainTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.net.URL;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.KeyStore;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.ProtectionDomain;
+import java.security.Timestamp;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.List;
+
+import sun.security.provider.certpath.X509CertPath;
+
+@RunWith(JUnit4.class)
+public class ProtectionDomainTest {
+
+    private ProtectionDomain domain;
+
+    @Before
+    public void setUp() throws Exception {
+        String path = "file://invalid_path";
+        CodeSigner codeSigner = createCodeSigner();
+        CodeSource codeSource = new CodeSource(new URL(path), new CodeSigner[] { codeSigner });
+        domain = new ProtectionDomain(codeSource , new TestPermissionCollection(),
+                ProtectionDomainTest.class.getClassLoader(), new Principal[0]);
+    }
+
+    @Test
+    public void testGetClassLoader() {
+        // Return null even thought it's set in the constructor
+        assertNull(domain.getClassLoader());
+    }
+
+    @Test
+    public void testGetCodeSource() {
+        // Return null even thought it's set in the constructor
+        assertNull(domain.getCodeSource());
+    }
+
+    @Test
+    public void testGetPermissions() {
+        // Return null even thought it's set in the constructor
+        assertNull(domain.getPermissions());
+    }
+
+    @Test
+    public void testGetPrincipals() {
+        // Return null even thought it's set in the constructor
+        assertNull(domain.getPrincipals());
+    }
+
+    @Test
+    public void testImplies() {
+        assertTrue(domain.implies(null));
+    }
+
+    private static CodeSigner createCodeSigner() throws Exception {
+        KeyStore keyStore = KeyStore.getInstance("AndroidCAStore");
+        keyStore.load(null);
+        // Get a X509Certificate from the keyStore
+        X509Certificate cert = null;
+        for (Enumeration<String> aliases = keyStore.aliases(); aliases.hasMoreElements(); ) {
+            String alias = aliases.nextElement();
+            Certificate certificate = keyStore.getCertificate(alias);
+            assertTrue(certificate instanceof X509Certificate);
+            cert = (X509Certificate) certificate;
+            break;
+        }
+
+        assertNotNull(cert);
+        X509CertPath certPath = new X509CertPath(List.of(cert));
+        return new CodeSigner(certPath, new Timestamp(new Date(), certPath));
+    }
+
+    private static class TestPermissionCollection extends PermissionCollection {
+
+        @Override
+        public void add(Permission permission) {
+        }
+
+        @Override
+        public boolean implies(Permission permission) {
+            return true;
+        }
+
+        @Override
+        public Enumeration<Permission> elements() {
+            return null;
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/ProviderTest.java b/luni/src/test/java/libcore/java/security/ProviderTest.java
index 946f602..a0be85a 100644
--- a/luni/src/test/java/libcore/java/security/ProviderTest.java
+++ b/luni/src/test/java/libcore/java/security/ProviderTest.java
@@ -36,6 +36,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -155,9 +156,6 @@
                     }
                     remainingAlgorithms.removeAll(toRemove);
                 }
-                if (remainingAlgorithms != null && remainingAlgorithms.isEmpty()) {
-                    remainingExpected.remove(type);
-                }
 
                 // make sure class exists and can be initialized
                 try {
@@ -171,6 +169,14 @@
                     }
                 }
             }
+
+            // last chance: some algorithms might only be provided by their alias
+            remainingExpected.entrySet()
+                .forEach(entry ->
+                    entry.getValue()
+                        .removeIf(algorithm ->
+                            provider.getService(entry.getKey(), algorithm) != null)
+            );
         }
 
         // assert that we don't have any extra in the implementation
@@ -190,10 +196,12 @@
                 } catch (NoSuchAlgorithmException|NoSuchPaddingException e) {
                 }
             }
-            if (remainingExpected.get("Cipher").isEmpty()) {
-                remainingExpected.remove("Cipher");
-            }
         }
+
+        remainingExpected.entrySet()
+            .removeIf(entry ->
+                entry.getValue().isEmpty());
+
         // assert that we don't have any missing in the implementation
         assertEquals("Algorithms are present in StandardNames but not provided",
                 Collections.EMPTY_MAP, remainingExpected);
@@ -215,13 +223,13 @@
         assertProviderProperties(providers[2], "CertPathProvider",
             "sun.security.provider.CertPathProvider");
         assertProviderProperties(providers[3], "AndroidKeyStoreBCWorkaround",
-            "android.security.keystore.AndroidKeyStoreBCWorkaroundProvider");
+            "android.security.keystore2.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");
+            "android.security.keystore2.AndroidKeyStoreProvider");
     }
 
     private void assertProviderProperties(Provider p, String name, String className) {
@@ -382,7 +390,7 @@
                 bcClasses.add(service.getClassName());
             }
         }
-        assertTrue(bcClasses.size() > 0);  // Sanity check
+        assertTrue(bcClasses.size() > 0);
 
         // 3. Determine which IDs in BC point to that set of classes
         Set<String> shouldBeOverriddenBcIds = new HashSet<>();
@@ -402,7 +410,7 @@
                 shouldBeOverriddenBcIds.add(key);
             }
         }
-        assertTrue(shouldBeOverriddenBcIds.size() > 0);  // Sanity check
+        assertTrue(shouldBeOverriddenBcIds.size() > 0);
 
         // 4. Check each of those IDs to ensure that it's present in Conscrypt
         Set<String> nonOverriddenIds = new TreeSet<>();
@@ -1063,6 +1071,21 @@
         assertEquals("default", p.getOrDefault("thisIsNotInTheProvider", "default"));
     }
 
+    public void test_elements() {
+        Provider p = new MockProvider("MockProvider");
+        p.put("class1.algorithm1", "impl1");
+        Enumeration<Object> elements = p.elements();
+        boolean isImpl1Found = false;
+        while (elements.hasMoreElements()) {
+            if ("impl1".equals(elements.nextElement())) {
+                isImpl1Found = true;
+                break;
+            }
+        }
+
+        assertTrue("impl1 is not found.", isImpl1Found);
+    }
+
     private static class Pair<A, B> {
         private final A first;
         private final B second;
diff --git a/luni/src/test/java/libcore/java/security/SecurityPermissionTest.java b/luni/src/test/java/libcore/java/security/SecurityPermissionTest.java
new file mode 100644
index 0000000..20fa1c7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/SecurityPermissionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.SecurityPermission;
+
+@RunWith(JUnit4.class)
+public class SecurityPermissionTest {
+
+    @Test
+    public void testConstructor() {
+        SecurityPermission permission = new SecurityPermission("name", "action");
+
+        // The name and actions are discarded from the constructor.
+        assertEquals("", permission.getName());
+        assertEquals("", permission.getActions());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/SignatureTest.java b/luni/src/test/java/libcore/java/security/SignatureTest.java
index 9c014d2..0ba9cab 100644
--- a/luni/src/test/java/libcore/java/security/SignatureTest.java
+++ b/luni/src/test/java/libcore/java/security/SignatureTest.java
@@ -437,28 +437,6 @@
         }
     }
 
-    // NetscapeCertRequest looks up Signature algorithms by OID from
-    // BC but BC version 1.47 had registration bugs and MD5withRSA was
-    // overlooked.  http://b/7453821
-    public void testGetInstanceFromOID() throws Exception {
-        if (StandardNames.IS_RI) {
-            return;
-        }
-        assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.4");  // MD5withRSA
-        assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.5");  // SHA1withRSA
-        assertBouncyCastleSignatureFromOID("1.3.14.3.2.29");         // SHA1withRSA
-        assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.11"); // SHA256withRSA
-        assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.12"); // SHA384withRSA
-        assertBouncyCastleSignatureFromOID("1.2.840.113549.1.1.13"); // SHA512withRSA
-        assertBouncyCastleSignatureFromOID("1.2.840.10040.4.3");     // SHA1withDSA
-    }
-
-    private void assertBouncyCastleSignatureFromOID(String oid) throws Exception {
-        Signature signature = Signature.getInstance(oid, "BC");
-        assertNotNull(oid, signature);
-        assertEquals(oid, signature.getAlgorithm());
-    }
-
     /**
      * 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
diff --git a/luni/src/test/java/libcore/java/security/UnresolvedPermissionTest.java b/luni/src/test/java/libcore/java/security/UnresolvedPermissionTest.java
new file mode 100644
index 0000000..4e8b2de
--- /dev/null
+++ b/luni/src/test/java/libcore/java/security/UnresolvedPermissionTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.security.UnresolvedPermission;
+import java.security.cert.Certificate;
+
+@RunWith(JUnit4.class)
+public class UnresolvedPermissionTest {
+
+    private final UnresolvedPermission p = new UnresolvedPermission("type", "name", "action",
+            new Certificate[0]);
+
+    @Test
+    public void testGetName() {
+        assertEquals("", p.getName());
+    }
+
+    @Test
+    public void testGetActions() {
+        assertNull(p.getActions());
+    }
+
+    @Test
+    public void testUnresolvedType() {
+        assertNull(p.getUnresolvedType());
+    }
+
+    @Test
+    public void testGetUnresolvedCertssss() {
+        assertNull(p.getUnresolvedCerts());
+    }
+
+    @Test
+    public void testGetUnresolvedName() {
+        assertNull(p.getUnresolvedName());
+    }
+
+    @Test
+    public void testGetUnresolvedActions() {
+        assertNull(p.getUnresolvedActions());
+    }
+
+    @Test
+    public void testImplies() {
+        assertFalse(p.implies(null));
+        assertFalse(p.implies(p));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java b/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java
index 1836aac..74868c1 100644
--- a/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/PKIXParametersTest.java
@@ -16,16 +16,38 @@
 
 package libcore.java.security.cert;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.security.InvalidAlgorithmParameterException;
 import java.security.KeyStore;
+import java.security.cert.Certificate;
+import java.security.cert.PKIXCertPathChecker;
 import java.security.cert.PKIXParameters;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
 import libcore.java.security.TestKeyStore;
-import libcore.junit.junit3.TestCaseWithRules;
 import libcore.junit.util.EnableDeprecatedBouncyCastleAlgorithmsRule;
 import org.junit.Rule;
+import org.junit.Test;
 import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
-public class PKIXParametersTest extends TestCaseWithRules {
+@RunWith(JUnit4.class)
+public class PKIXParametersTest {
+    private  static final FakeCertPathChecker CHECK_ONE = new FakeCertPathChecker("One");
+    private  static final FakeCertPathChecker CHECK_TWO = new FakeCertPathChecker("Two");
+    private  static final FakeCertPathChecker CHECK_THREE = new FakeCertPathChecker("Three");
+    private static final List<PKIXCertPathChecker> CHECK_LIST
+        = List.of(CHECK_ONE, CHECK_TWO, CHECK_THREE);
 
     // Allow access to deprecated BC algorithms in this test, so we can ensure they
     // continue to work
@@ -33,7 +55,8 @@
     public TestRule enableDeprecatedBCAlgorithmsRule =
             EnableDeprecatedBouncyCastleAlgorithmsRule.getInstance();
 
-    public void testKeyStoreConstructor() throws Exception {
+    @Test
+    public void keyStoreConstructor() throws Exception {
         TestKeyStore server = TestKeyStore.getServer();
         KeyStore.PrivateKeyEntry pke = server.getPrivateKey("RSA", "RSA");
         char[] password = "password".toCharArray();
@@ -63,4 +86,139 @@
         } catch (InvalidAlgorithmParameterException expected) {
         }
     }
+
+    @Test
+    public void addCertPathChecker() throws Exception {
+        PKIXParameters parameters = newPkixParameters();
+        for (PKIXCertPathChecker pathChecker : CHECK_LIST) {
+            parameters.addCertPathChecker(pathChecker);
+        }
+
+        List<PKIXCertPathChecker> actualCheckers = parameters.getCertPathCheckers();
+        assertEquals(CHECK_LIST, actualCheckers);
+    }
+
+    @Test
+    public void addCertPathChecker_Null() throws Exception {
+        PKIXParameters parameters = newPkixParameters();
+
+        parameters.addCertPathChecker(null);
+        assertEquals(0, parameters.getCertPathCheckers().size());
+    }
+
+    @Test
+    public void setCertPathCheckers() throws Exception {
+        PKIXParameters parameters = newPkixParameters();
+        parameters.setCertPathCheckers(CHECK_LIST);
+
+        List<PKIXCertPathChecker> actualCheckers = parameters.getCertPathCheckers();
+        assertEquals(CHECK_LIST, actualCheckers);
+        assertNotSame(CHECK_LIST, actualCheckers);
+    }
+
+    @Test
+    public void setCertPathCheckers_NullEmpty() throws Exception {
+        PKIXParameters parameters = newPkixParameters();
+
+        parameters.setCertPathCheckers(null);
+        assertEquals(0, parameters.getCertPathCheckers().size());
+
+        parameters.setCertPathCheckers(new ArrayList<>());
+        assertEquals(0, parameters.getCertPathCheckers().size());
+    }
+
+    @Test
+    public void setCertPathCheckers_Replacement() throws Exception {
+        PKIXParameters parameters = newPkixParameters(CHECK_LIST);
+        parameters.setCertPathCheckers(null);
+        assertEquals(0, parameters.getCertPathCheckers().size());
+
+        parameters = newPkixParameters(CHECK_LIST);
+        parameters.setCertPathCheckers(new ArrayList<>());
+        assertEquals(0, parameters.getCertPathCheckers().size());
+
+        parameters = newPkixParameters(CHECK_LIST);
+        List<PKIXCertPathChecker> reversed = new ArrayList<>(CHECK_LIST);
+        Collections.reverse(reversed);
+        parameters.setCertPathCheckers(reversed);
+        assertEquals(reversed, parameters.getCertPathCheckers());
+    }
+
+    @Test
+    public void setCertPathCheckers_Error() throws Exception {
+        PKIXParameters parameters = newPkixParameters();
+        List badList = List.of("Wrong class");
+        try {
+            parameters.setCertPathCheckers(badList);
+            fail();
+        } catch (ClassCastException expected) {
+        }
+    }
+
+    @Test
+    public void toStringContainsPathCheckers() throws Exception {
+        PKIXParameters parameters = newPkixParameters(CHECK_LIST);
+
+        String regex = ".*" + CHECK_ONE + ".*" + CHECK_TWO + ".*" + CHECK_THREE + ".*";
+        Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
+        assertTrue(pattern.matcher(parameters.toString()).matches());
+    }
+
+    private PKIXParameters newPkixParameters() throws Exception {
+        PKIXParameters parameters = new PKIXParameters(TestKeyStore.getServer().keyStore);
+
+        List<PKIXCertPathChecker> pathCheckers = parameters.getCertPathCheckers();
+        assertEquals(0, pathCheckers.size());
+        return parameters;
+    }
+
+    private PKIXParameters newPkixParameters(List<PKIXCertPathChecker> pathCheckers)
+        throws Exception {
+
+        PKIXParameters parameters = newPkixParameters();
+        parameters.setCertPathCheckers(pathCheckers);
+        assertEquals(pathCheckers, parameters.getCertPathCheckers());
+        return parameters;
+    }
+
+    private static class FakeCertPathChecker extends PKIXCertPathChecker {
+        private final String tag;
+
+        FakeCertPathChecker(String tag) {
+            this.tag = tag;
+        }
+
+        @Override
+        public void init(boolean forward) {
+            // No-op
+        }
+
+        @Override
+        public boolean isForwardCheckingSupported() {
+            return false;
+        }
+
+        @Override
+        public Set<String> getSupportedExtensions() {
+            return new HashSet<>();
+        }
+
+        @Override
+        public void check(Certificate cert, Collection<String> unresolvedCritExts) {
+            // No-op
+        }
+
+        @Override
+        public String toString() {
+            return "FakeCertPathChecker: " + tag;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other instanceof FakeCertPathChecker) {
+                return tag.equals(((FakeCertPathChecker) other).tag);
+            }
+            return false;
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java b/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java
index 0e420cb..eed881e 100644
--- a/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/PKIXRevocationCheckerTest.java
@@ -116,4 +116,10 @@
         assertEquals(1, checker.getOcspExtensions().size());
         assertEquals("TestExtension", checker.getOcspExtensions().get(0).getId());
     }
+
+    public void test_clone() {
+        PKIXRevocationChecker clone = checker.clone();
+        assertNotNull(clone);
+        assertNotSame(checker, clone);
+    }
 }
diff --git a/luni/src/test/java/libcore/java/sql/OldConnectionTest.java b/luni/src/test/java/libcore/java/sql/OldConnectionTest.java
index 0edee1c..3548ba3 100644
--- a/luni/src/test/java/libcore/java/sql/OldConnectionTest.java
+++ b/luni/src/test/java/libcore/java/sql/OldConnectionTest.java
@@ -1614,7 +1614,7 @@
 
     // TODO Savepoint is not supported
     public void testRollback_Savepoint() throws SQLException {
-        Savepoint sp = new DummySavePoint();
+        Savepoint sp = new FakeSavePoint();
         conn.setAutoCommit(false);
 
         try {
@@ -1735,7 +1735,7 @@
 
     // TODO Savepoint is not supported
     public void testReleaseSavepoint_Savepoint() throws SQLException {
-        Savepoint sp = new DummySavePoint();
+        Savepoint sp = new FakeSavePoint();
         conn.setAutoCommit(false);
 
         try {
@@ -2181,7 +2181,7 @@
         st.execute("select * from zoo");
     }
 
-    private static class DummySavePoint implements Savepoint{
+    private static class FakeSavePoint implements Savepoint{
         public int getSavepointId()  {
             return 0;
         }
diff --git a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
index e2be925..4e5e994 100644
--- a/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/DecimalFormatTest.java
@@ -120,6 +120,112 @@
                 en_IN, "-9,87,65,43,21,09,87,65,43,21,09,87,65,43,210");
     }
 
+    // Test for http://b/168304209
+    public void testFieldPosition() {
+        DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        DecimalFormat currencyDf = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
+        DecimalFormat percentDf = (DecimalFormat) NumberFormat.getPercentInstance(Locale.US);
+        DecimalFormat milledf = (DecimalFormat) NumberFormat.getInstance(Locale.US);
+        milledf.applyPattern("#,##0\u2030;-#,##0\u2030");
+        DecimalFormat scientificDf = (DecimalFormat) NumberFormat.getNumberInstance(Locale.US);
+        scientificDf.applyPattern("0.###E0");
+
+        // Reference behaviors of different field positions when formatting a simple integer.
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.INTEGER, "123", 0, 3);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.FRACTION, "123", 3, 3);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.CURRENCY, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.DECIMAL_SEPARATOR, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.EXPONENT, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.EXPONENT_SIGN, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.EXPONENT_SYMBOL, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.GROUPING_SEPARATOR, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.PERCENT, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.PERMILLE, "123", 0, 0);
+        assertFieldPosition4Types(df, 123, NumberFormat.Field.SIGN, "123", 0, 0);
+
+        assertFieldPosition4Types(currencyDf, 123, NumberFormat.Field.CURRENCY, "$123.00", 0, 1);
+        assertFieldPosition(df, 123.4, NumberFormat.Field.DECIMAL_SEPARATOR, "123.4", 3, 4);
+        assertFieldPosition4Types(scientificDf, 123, NumberFormat.Field.EXPONENT, "1.23E2", 5, 6);
+        assertFieldPosition(scientificDf, 0.123, NumberFormat.Field.EXPONENT_SIGN, "1.23E-1", 5, 6);
+        assertFieldPosition4Types(scientificDf, 123, NumberFormat.Field.EXPONENT_SYMBOL, "1.23E2",
+                4, 5);
+        assertFieldPosition4Types(df, 1234, NumberFormat.Field.GROUPING_SEPARATOR, "1,234", 1, 2);
+        assertFieldPosition4Types(percentDf, 12, NumberFormat.Field.PERCENT, "1,200%", 5, 6);
+        assertFieldPosition4Types(milledf, 12, NumberFormat.Field.PERMILLE, "12,000\u2030", 6, 7);
+        assertFieldPosition4Types(df, -123, NumberFormat.Field.SIGN, "-123", 0, 1);
+
+        BigInteger bigInteger = new BigInteger("999999999999999999999999"); // 24 of '9';
+        // Assert this large number is larger than the max possible long value.
+        assertEquals(1, bigInteger.compareTo(BigInteger.valueOf(Long.MAX_VALUE)));
+        String expectedStr = "999,999,999,999,999,999,999,999";
+        assertFieldPosition(df, bigInteger, NumberFormat.Field.INTEGER, expectedStr, 0,
+                expectedStr.length());
+        expectedStr = "$" + expectedStr + ".00";
+        assertFieldPosition(currencyDf, bigInteger, NumberFormat.Field.INTEGER, expectedStr, 1,
+                expectedStr.length() - 3);
+        assertFieldPosition(currencyDf, bigInteger, NumberFormat.Field.CURRENCY, expectedStr, 0, 1);
+
+        BigDecimal bigDecimal = BigDecimal.valueOf(123.45);
+        assertFieldPosition(df, bigDecimal, NumberFormat.Field.INTEGER, "123.45", 0, 3);
+        assertFieldPosition(currencyDf, bigDecimal, NumberFormat.Field.CURRENCY, "$123.45", 0, 1);
+    }
+
+    /**
+     * Run the test with {@param num} in 4 different types, i.e. long, double, BigInteger
+     * and BigDecimal to increase the test coverage, because the 4 types have 4 different code paths
+     * internally.
+     */
+    private void assertFieldPosition4Types(DecimalFormat df, long num, NumberFormat.Field field,
+            String expectedStr, int expectedBeginIndex, int expectedEndIndex) {
+        assertFieldPosition(df, num, field, expectedStr, expectedBeginIndex, expectedEndIndex);
+        assertFieldPosition(df, (double) num, field, expectedStr, expectedBeginIndex,
+                expectedEndIndex);
+        assertFieldPosition(df, BigInteger.valueOf(num), field, expectedStr, expectedBeginIndex,
+                expectedEndIndex);
+        assertFieldPosition(df, BigDecimal.valueOf(num), field, expectedStr, expectedBeginIndex,
+                expectedEndIndex);
+    }
+
+    private void assertFieldPosition(DecimalFormat df, long num, NumberFormat.Field field,
+            String expectedStr, int expectedBeginIndex, int expectedEndIndex) {
+        FieldPosition fp = new FieldPosition(field);
+        StringBuffer stringBuffer = new StringBuffer();
+        df.format(num, stringBuffer, fp);
+        assertEquals(expectedStr, stringBuffer.toString());
+        assertEquals(expectedBeginIndex, fp.getBeginIndex());
+        assertEquals(expectedEndIndex, fp.getEndIndex());
+    }
+
+    private void assertFieldPosition(DecimalFormat df, double num, NumberFormat.Field field,
+            String expectedStr, int expectedBeginIndex, int expectedEndIndex) {
+        FieldPosition fp = new FieldPosition(field);
+        StringBuffer stringBuffer = new StringBuffer();
+        df.format(num, stringBuffer, fp);
+        assertEquals(expectedStr, stringBuffer.toString());
+        assertEquals(expectedBeginIndex, fp.getBeginIndex());
+        assertEquals(expectedEndIndex, fp.getEndIndex());
+    }
+
+    private void assertFieldPosition(DecimalFormat df, BigInteger num, NumberFormat.Field field,
+            String expectedStr, int expectedBeginIndex, int expectedEndIndex) {
+        FieldPosition fp = new FieldPosition(field);
+        StringBuffer stringBuffer = new StringBuffer();
+        df.format(num, stringBuffer, fp);
+        assertEquals(expectedStr, stringBuffer.toString());
+        assertEquals(expectedBeginIndex, fp.getBeginIndex());
+        assertEquals(expectedEndIndex, fp.getEndIndex());
+    }
+
+    private void assertFieldPosition(DecimalFormat df, BigDecimal num, NumberFormat.Field field,
+            String expectedStr, int expectedBeginIndex, int expectedEndIndex) {
+        FieldPosition fp = new FieldPosition(field);
+        StringBuffer stringBuffer = new StringBuffer();
+        df.format(num, stringBuffer, fp);
+        assertEquals(expectedStr, stringBuffer.toString());
+        assertEquals(expectedBeginIndex, fp.getBeginIndex());
+        assertEquals(expectedEndIndex, fp.getEndIndex());
+    }
+
     public void testBigDecimalICUConsistency() {
         DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
         df.setMaximumFractionDigits(2);
@@ -302,34 +408,6 @@
         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");
diff --git a/luni/src/test/java/libcore/java/text/OldDecimalFormatTestICU.java b/luni/src/test/java/libcore/java/text/OldDecimalFormatTestICU.java
index eb3f4ca..75344af 100644
--- a/luni/src/test/java/libcore/java/text/OldDecimalFormatTestICU.java
+++ b/luni/src/test/java/libcore/java/text/OldDecimalFormatTestICU.java
@@ -35,7 +35,7 @@
         format = (DecimalFormat) NumberFormat.getNumberInstance();
     }
 
-    // AndroidOnly: special feature of icu4c
+    // Android-note: special feature of icu4c.
     public void test_sigDigitPatterns() throws Exception {
         DecimalFormat format = (DecimalFormat) NumberFormat
         .getInstance(Locale.US);
@@ -62,7 +62,7 @@
         }
     }
 
-    // AndroidOnly: special feature of icu4c
+    // Android-note: special feature of icu4c.
     public void test_paddingPattern() throws Exception {
         format.applyPattern("*x##,##,#,##0.0#");
         assertEquals("xxxxxxxxx123.0", format.format(123));
@@ -95,7 +95,7 @@
         }
     }
 
-    // AndroidOnly: special feature of icu4c
+    // Android-note: special feature of icu4c.
     public void test_positiveExponentSign() throws Exception {
         format.applyPattern("0.###E+0");
         assertEquals("1E+2", format.format(100));
@@ -124,7 +124,7 @@
         }
     }
 
-    // AndroidOnly: special feature of icu4c
+    // Android-note: special feature of icu4c.
     public void test_secondaryGroupingSize() throws Exception {
         format.applyPattern("#,##,###,####");
         assertEquals("123,456,7890", format.format(1234567890));
diff --git a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
index a4ebad3..245cd3d 100644
--- a/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
+++ b/luni/src/test/java/libcore/java/text/SimpleDateFormatTest.java
@@ -388,21 +388,19 @@
         assertEquals(20, calendar.get(Calendar.HOUR_OF_DAY)); // 9:00 GMT+11:00
         assertEquals(0, calendar.get(Calendar.MINUTE));
     }
-
-    public void testLocales() throws Exception {
-        // Just run through them all. Handy as a poor man's benchmark, and a sanity check.
-        for (Locale l : Locale.getAvailableLocales()) {
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss zzzz", l);
-            sdf.format(new Date(0));
-        }
-    }
-
     // http://code.google.com/p/android/issues/detail?id=14963
     public void testParseTimezoneOnly() throws Exception {
         new SimpleDateFormat("z", Locale.FRANCE).parse("UTC");
         new SimpleDateFormat("z", Locale.US).parse("UTC");
     }
 
+    public void testParseMetazoneFallbacksToLocale() throws Exception {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm zzzz", Locale.US);
+        Date date = format.parse("2021-02-08T14:14 Pacific Standard Time"); // 22:14 GMT-8:00
+
+        assertEquals(1612822440000L, date.getTime());
+    }
+
     // http://code.google.com/p/android/issues/detail?id=36689
     public void testParseArabic() throws Exception {
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", new Locale("ar", "EG"));
diff --git a/luni/src/test/java/libcore/java/time/OffsetDateTimeTest.java b/luni/src/test/java/libcore/java/time/OffsetDateTimeTest.java
index 09a258a..ba69230 100644
--- a/luni/src/test/java/libcore/java/time/OffsetDateTimeTest.java
+++ b/luni/src/test/java/libcore/java/time/OffsetDateTimeTest.java
@@ -53,4 +53,40 @@
         assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 4, 5, 7, ZoneOffset.UTC),
                 ODT.plus(1, ChronoUnit.NANOS));
     }
+
+    @Test
+    public void test_minus_utc_offset() {
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 2, 4, 5, 6, ZoneOffset.UTC),
+                ODT.minus(1, ChronoUnit.HOURS));
+        assertEquals(OffsetDateTime.of(2000, 1, 1, 4, 4, 5, 6, ZoneOffset.UTC),
+                ODT.minus(23, ChronoUnit.HOURS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 3, 5, 6, ZoneOffset.UTC),
+                ODT.minus(1, ChronoUnit.MINUTES));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 3, 5, 6, ZoneOffset.UTC),
+                ODT.minus(60, ChronoUnit.SECONDS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 4, 4, 999_000_006, ZoneOffset.UTC),
+                ODT.minus(1, ChronoUnit.MILLIS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 4, 5, 5, ZoneOffset.UTC),
+                ODT.minus(1, ChronoUnit.NANOS));
+    }
+
+    @Test
+    public void test_minus_non_utc_offset() {
+        ZoneOffset offset = ZoneOffset.ofHours(4);
+        OffsetDateTime odt =
+                OffsetDateTime.of(2000, 1, 2, 3, 4, 5, 6, offset);
+
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 2, 4, 5, 6, offset),
+                odt.minus(1, ChronoUnit.HOURS));
+        assertEquals(OffsetDateTime.of(2000, 1, 1, 4, 4, 5, 6, offset),
+                odt.minus(23, ChronoUnit.HOURS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 3, 5, 6, offset),
+                odt.minus(1, ChronoUnit.MINUTES));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 3, 5, 6, offset),
+                odt.minus(60, ChronoUnit.SECONDS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 4, 4, 999_000_006, offset),
+                odt.minus(1, ChronoUnit.MILLIS));
+        assertEquals(OffsetDateTime.of(2000, 1, 2, 3, 4, 5, 5, offset),
+                odt.minus(1, ChronoUnit.NANOS));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/time/ZonedDateTimeTest.java b/luni/src/test/java/libcore/java/time/ZonedDateTimeTest.java
index 09422dd..afeb570 100644
--- a/luni/src/test/java/libcore/java/time/ZonedDateTimeTest.java
+++ b/luni/src/test/java/libcore/java/time/ZonedDateTimeTest.java
@@ -92,8 +92,8 @@
 
     /**
      * Assert that calling {@link ZonedDateTime#ofInstant(LocalDateTime, ZoneOffset, ZoneId)} with
-     * the first three parameters produces a sane result with the localDateTime and offset equal to
-     * the last two.
+     * the first three parameters produces a meaningful result with the localDateTime and offset
+     * equal to the last two.
      */
     private static void checkOfInstant(LocalDateTime localDateTime, ZoneOffset offset,
             ZoneId zone, LocalDateTime expectedDateTime, ZoneOffset expectedOffset) {
@@ -162,8 +162,8 @@
 
     /**
      * Assert that calling {@link ZonedDateTime#ofLocal(LocalDateTime, ZoneId, ZoneOffset)} with
-     * the first three parameters produces a sane result with the localDateTime, and offset equal
-     * to the last two.
+     * the first three parameters produces a meaningful result with the localDateTime, and offset
+     * equal to the last two.
      */
     private static void checkOfLocal(LocalDateTime localDateTime, ZoneId zone,
             ZoneOffset preferredOffset, LocalDateTime expectedDateTime, ZoneOffset expectedOffset) {
diff --git a/luni/src/test/java/libcore/java/time/chrono/ChronoPeriodTest.java b/luni/src/test/java/libcore/java/time/chrono/ChronoPeriodTest.java
new file mode 100644
index 0000000..b0e3bb6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/ChronoPeriodTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.dx.Local;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.chrono.ChronoPeriod;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
+
+@RunWith(JUnit4.class)
+public class ChronoPeriodTest {
+
+    @Test
+    public void between_withNull_throwsNpe() {
+        try {
+            ChronoPeriod.between(null, null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+
+        try {
+            ChronoPeriod.between(null, LocalDate.now());
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+
+        try {
+            ChronoPeriod.between(LocalDate.now(), null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void between_nonNull() {
+        LocalDate now = LocalDate.of(2021, 5, 26);
+        LocalDate tomorrow = LocalDate.of(2021, 5, 27);
+
+        assertEquals(Period.ofDays(1), ChronoPeriod.between(now, tomorrow));
+        assertEquals(HijrahChronology.INSTANCE.period(0, 0, 2),
+                ChronoPeriod.between(HijrahDate.of(1442, 9, 10), HijrahDate.of(1442, 9, 12)));
+    }
+
+    @Test
+    public void between_differentInterfaceImplementations() {
+        LocalDate isoNow = LocalDate.of(2021, 5, 26);
+        HijrahDate hijrahTomorrow = HijrahDate.of(1442, 10, 15);
+
+        assertEquals(Period.ofDays(1), ChronoPeriod.between(isoNow, hijrahTomorrow));
+        assertEquals(HijrahChronology.INSTANCE.period(0, 0, -1),
+                ChronoPeriod.between(hijrahTomorrow, isoNow));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/time/chrono/ChronoZonedDateTimeTest.java b/luni/src/test/java/libcore/java/time/chrono/ChronoZonedDateTimeTest.java
new file mode 100644
index 0000000..a319980
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/ChronoZonedDateTimeTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.chrono.ChronoLocalDateTime;
+import java.time.chrono.ChronoZonedDateTime;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+
+@RunWith(JUnit4.class)
+public class ChronoZonedDateTimeTest {
+
+    @Test
+    public void isSupported_returnsFalse_forForever() {
+        ChronoZonedDateTime chronoZonedDateTime = new TestChronoZonedDateTime();
+        assertFalse(chronoZonedDateTime.isSupported(ChronoUnit.FOREVER));
+    }
+
+    @Test
+    public void isSupported_returnsFalse_forNull() {
+        ChronoZonedDateTime chronoZonedDateTime = new TestChronoZonedDateTime();
+        assertFalse(chronoZonedDateTime.isSupported((TemporalUnit) null));
+    }
+
+    @Test
+    public void isSupported_defersToArgument() {
+        ChronoZonedDateTime chronoZonedDateTime = new TestChronoZonedDateTime();
+        TemporalUnit temporalUnit = mock(TemporalUnit.class);
+
+        chronoZonedDateTime.isSupported(temporalUnit);
+
+        verify(temporalUnit).isSupportedBy(chronoZonedDateTime);
+    }
+
+    /* Used to test default methods. */
+    private static class TestChronoZonedDateTime implements ChronoZonedDateTime {
+
+        @Override
+        public ChronoLocalDateTime toLocalDateTime() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ZoneOffset getOffset() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ZoneId getZone() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime withEarlierOffsetAtOverlap() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime withLaterOffsetAtOverlap() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime withZoneSameLocal(ZoneId zone) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime withZoneSameInstant(ZoneId zone) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isSupported(TemporalField field) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime with(TemporalField field, long newValue) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ChronoZonedDateTime plus(long amountToAdd, TemporalUnit unit) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public long until(Temporal endExclusive, TemporalUnit unit) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int compareTo(Object o) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/time/chrono/ChronologyTest.java b/luni/src/test/java/libcore/java/time/chrono/ChronologyTest.java
index 37fdd7c..430e350 100644
--- a/luni/src/test/java/libcore/java/time/chrono/ChronologyTest.java
+++ b/luni/src/test/java/libcore/java/time/chrono/ChronologyTest.java
@@ -40,8 +40,8 @@
     @Test
     public void test_compareTo() {
         Set<Chronology> chronologies = new LinkedHashSet<>(Chronology.getAvailableChronologies());
-        chronologies.add(new DummyChronology("aaa", "z aaa"));
-        chronologies.add(new DummyChronology("zzz", "a zzz"));
+        chronologies.add(new FakeChronology("aaa", "z aaa"));
+        chronologies.add(new FakeChronology("zzz", "a zzz"));
 
         // Check for comparison of each chronology with each other (including itself).
         for (Chronology c1 : chronologies) {
@@ -68,14 +68,14 @@
         IsoChronology.INSTANCE.compareTo(null);
     }
 
-    /** Dummy chronology that supports only returning an id and a type. */
-    private static class DummyChronology extends AbstractChronology {
+    /** Fake chronology that supports only returning an id and a type. */
+    private static class FakeChronology extends AbstractChronology {
 
         private final String id;
 
         private final String type;
 
-        public DummyChronology(String id, String type) {
+        public FakeChronology(String id, String type) {
             this.id = id;
             this.type = type;
         }
diff --git a/luni/src/test/java/libcore/java/time/chrono/EraTest.java b/luni/src/test/java/libcore/java/time/chrono/EraTest.java
new file mode 100644
index 0000000..92d284e
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/EraTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import static java.time.temporal.ChronoField.ERA;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.chrono.Era;
+import java.time.temporal.ChronoField;
+import java.time.temporal.Temporal;
+import java.time.temporal.TemporalAccessor;
+import java.time.temporal.TemporalField;
+import java.time.temporal.TemporalUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+import java.time.temporal.ValueRange;
+import java.util.EnumSet;
+
+@RunWith(JUnit4.class)
+public class EraTest {
+
+    @Test
+    public void getLong_returnsValue_forEra() {
+        assertEquals(10, TestEra.INSTANCE.getLong(ERA));
+    }
+
+    @Test
+    public void getLong_throws_forNonERA_chronoFields() {
+        EnumSet<ChronoField> unsupportedFields = EnumSet.complementOf(EnumSet.of(ERA));
+
+        for (ChronoField unsupportedField : unsupportedFields) {
+            try {
+                TestEra.INSTANCE.getLong(unsupportedField);
+                fail("getLong(" + unsupportedField + ") should throw exception");
+            } catch (UnsupportedTemporalTypeException ignored) {
+                // expected
+            }
+        }
+    }
+
+    @Test
+    public void getLong_defersToArgument_forNonChronoFieldInstances() {
+        TestTemporalField temporalField = new TestTemporalField();
+
+        TestEra.INSTANCE.getLong(temporalField);
+
+        temporalField.assertGetFromWasCalledWith(TestEra.INSTANCE);
+    }
+
+    private enum TestEra implements Era {
+        INSTANCE;
+
+        @Override
+        public int getValue() {
+            return 10;
+        }
+    }
+
+    private static class TestTemporalField implements TemporalField {
+
+        TemporalAccessor getFromArgument = null;
+
+        @Override
+        public TemporalUnit getBaseUnit() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public TemporalUnit getRangeUnit() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ValueRange range() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isDateBased() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isTimeBased() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isSupportedBy(TemporalAccessor temporal) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public ValueRange rangeRefinedBy(TemporalAccessor temporal) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public long getFrom(TemporalAccessor temporal) {
+            if (getFromArgument != null) {
+                throw new IllegalStateException("getFrom was called more than once");
+            }
+            getFromArgument = temporal;
+            return 0;
+        }
+
+        @Override
+        public <R extends Temporal> R adjustInto(R temporal, long newValue) {
+            throw new UnsupportedOperationException();
+        }
+
+        public void assertGetFromWasCalledWith(TemporalAccessor temporal) {
+            assertSame(temporal, getFromArgument);
+        }
+    }
+
+
+}
diff --git a/luni/src/test/java/libcore/java/time/chrono/HijrahChronologyTest.java b/luni/src/test/java/libcore/java/time/chrono/HijrahChronologyTest.java
index 3a33e5b..2122c01 100644
--- a/luni/src/test/java/libcore/java/time/chrono/HijrahChronologyTest.java
+++ b/luni/src/test/java/libcore/java/time/chrono/HijrahChronologyTest.java
@@ -15,15 +15,16 @@
  */
 package libcore.java.time.chrono;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
 import org.junit.Test;
+
 import java.time.chrono.HijrahChronology;
 import java.time.chrono.HijrahDate;
 import java.time.chrono.HijrahEra;
 import java.time.temporal.ChronoField;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertSame;
-
 /**
  * Additional tests for {@link HijrahDate}.
  *
@@ -64,4 +65,12 @@
     public void test_HijrahDate_withVariant_null() {
         HijrahDate.now().withVariant(null);
     }
+
+    @Test
+    public void dateEpochDay() {
+        // 18766th Epoch Day is 19 May 2021
+        assertEquals(HijrahDate.of(1442, 10, 7), HijrahChronology.INSTANCE.dateEpochDay(18766));
+        assertEquals(HijrahDate.of(1389, 10, 22), HijrahChronology.INSTANCE.dateEpochDay(0));
+    }
+
 }
diff --git a/luni/src/test/java/libcore/java/time/chrono/HijrahDateTest.java b/luni/src/test/java/libcore/java/time/chrono/HijrahDateTest.java
new file mode 100644
index 0000000..23f1ad0
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/HijrahDateTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.apache.harmony.tests.support.P;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.Period;
+import java.time.Year;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+
+@RunWith(JUnit4.class)
+public class HijrahDateTest {
+
+    @Test
+    public void minus_null_throws_NPE() {
+        try {
+            HijrahDate.now().minus(/* amount= */ null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_Duration_throws_DateTimeException() {
+        try {
+            HijrahDate.now().minus(Duration.ofDays(1));
+          fail();
+        } catch (DateTimeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_Period_throws_DateTimeException() {
+        try {
+            HijrahDate.now().minus(Period.ofDays(1));
+            fail();
+        } catch (DateTimeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_hijrah_period() {
+        // 26 May 2021
+        HijrahDate now = HijrahDate.of(1442, 10, 14);
+
+        assertEquals(HijrahDate.of(1442, 10, 13),
+                now.minus(HijrahChronology.INSTANCE.period(0, 0, 1)));
+        assertEquals(HijrahDate.of(1441, 10, 14),
+                now.minus(HijrahChronology.INSTANCE.period(1, 0, 0)));
+        assertEquals(HijrahDate.of(1443, 11, 15),
+                now.minus(HijrahChronology.INSTANCE.period(-1, -1, -1)));
+        assertEquals(HijrahDate.of(1442, 9, 30),
+                now.minus(HijrahChronology.INSTANCE.period(0, 0, 14)));
+        assertEquals(HijrahDate.of(1442, 11, 1),
+                now.minus(HijrahChronology.INSTANCE.period(0, 0, -16)));
+    }
+
+    @Test
+    public void until_isoDates() {
+        // 26 May 2021
+        HijrahDate hijrahNow = HijrahDate.of(1442, 10, 14);
+        LocalDate isoNow = LocalDate.of(2021, 5, 26);
+
+        assertEquals(0, hijrahNow.until(isoNow, ChronoUnit.DAYS));
+        assertEquals(0, hijrahNow.until(isoNow.atTime(10, 10), ChronoUnit.DAYS));
+    }
+
+    @Test
+    public void until_hijrahDates() {
+        // 26 May 2021
+        HijrahDate hijrahNow = HijrahDate.of(1442, 10, 14);
+        HijrahDate hijrahTomorrow = HijrahDate.of(1442, 10, 15);
+
+        assertEquals(-1, hijrahTomorrow.until(hijrahNow, ChronoUnit.DAYS));
+        assertEquals(1, hijrahNow.until(HijrahDate.of(1442, 11, 14), ChronoUnit.MONTHS));
+    }
+
+    @Test
+    public void until_isoDates_unsupportedTypes() {
+        // 26 May 2021
+        HijrahDate hijrahNow = HijrahDate.of(1442, 10, 14);
+        LocalDate isoNow = LocalDate.of(2021, 5, 26);
+
+        try {
+            hijrahNow.until(isoNow, ChronoUnit.HOURS);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+
+        try {
+            hijrahNow.until(Year.of(2021), ChronoUnit.YEARS);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+
+        try {
+            hijrahNow.until(Instant.ofEpochSecond(1622113481L), ChronoUnit.DAYS);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+    }
+}
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 5e920b3..148c8cd 100644
--- a/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java
+++ b/luni/src/test/java/libcore/java/time/chrono/JapaneseChronologyTest.java
@@ -18,6 +18,9 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertSame;
 
+import static java.time.chrono.JapaneseEra.REIWA;
+import static java.time.chrono.JapaneseEra.SHOWA;
+
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalTime;
@@ -74,7 +77,7 @@
         // first supported year in JapaneseChronology is Meiji 6.
         assertEquals(JapaneseEra.MEIJI, JapaneseDate.from(LocalDate.of(1873, 1, 1)).getEra());
         assertEquals(JapaneseEra.TAISHO, JapaneseDate.from(LocalDate.of(1913, 1, 1)).getEra());
-        assertEquals(JapaneseEra.SHOWA, JapaneseDate.from(LocalDate.of(1927, 1, 1)).getEra());
+        assertEquals(SHOWA, JapaneseDate.from(LocalDate.of(1927, 1, 1)).getEra());
         assertEquals(JapaneseEra.HEISEI, JapaneseDate.from(LocalDate.of(1990, 1, 1)).getEra());
     }
 
@@ -144,4 +147,15 @@
         assertEquals("Reiwa", reiwaDate.getEra().toString());
     }
 
+    @Test
+    public void dateEpochDay() {
+        JapaneseDate epoch = JapaneseChronology.INSTANCE.dateEpochDay(0);
+        JapaneseDate today = JapaneseChronology.INSTANCE.dateEpochDay(18768);
+        JapaneseDate dayBeforeEpoch = JapaneseChronology.INSTANCE.dateEpochDay(-1);
+
+        assertEquals(JapaneseDate.of(SHOWA, 45, 1, 1), epoch);
+        assertEquals(JapaneseDate.of(REIWA, 3, 5, 21), today);
+        assertEquals(JapaneseDate.of(SHOWA, 44, 12, 31), dayBeforeEpoch);
+    }
+
 }
diff --git a/luni/src/test/java/libcore/java/time/chrono/JapaneseDateTest.java b/luni/src/test/java/libcore/java/time/chrono/JapaneseDateTest.java
new file mode 100644
index 0000000..7789e06
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/JapaneseDateTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import static java.time.chrono.JapaneseEra.HEISEI;
+import static java.time.chrono.JapaneseEra.REIWA;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Period;
+import java.time.chrono.JapaneseChronology;
+import java.time.chrono.JapaneseDate;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+
+@RunWith(JUnit4.class)
+public class JapaneseDateTest {
+
+    @Test
+    public void minus_null_throwsNpe() {
+        try {
+            JapaneseDate.now().minus(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_days() {
+        JapaneseDate date = JapaneseDate.of(REIWA, 3, 5, 21);
+
+        assertEquals(JapaneseDate.of(REIWA, 3, 5, 20), date.minus(1, ChronoUnit.DAYS));
+    }
+
+    @Test
+    public void minus_negative_days() {
+        JapaneseDate date = JapaneseDate.of(REIWA, 3, 5, 21);
+
+        assertEquals(JapaneseDate.of(REIWA, 3, 5, 22), date.minus(-1, ChronoUnit.DAYS));
+    }
+
+    @Test
+    public void minus_days_crossEras() {
+        JapaneseDate date = JapaneseDate.of(REIWA, 1, 5, 1);
+
+        assertEquals(JapaneseDate.of(HEISEI, 31, 4, 30), date.minus(1, ChronoUnit.DAYS));
+    }
+
+    @Test
+    public void minus_less_than_day_throwsUnsupportedTemporalTypeException() {
+        try {
+            JapaneseDate.now().minus(1, ChronoUnit.HOURS);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+
+        try {
+            JapaneseDate.now().minus(1, ChronoUnit.MINUTES);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+
+        try {
+            JapaneseDate.now().minus(1, ChronoUnit.SECONDS);
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_Duration_throws_UnsupportedTemporalTypeException() {
+        try {
+            JapaneseDate.now().minus(Duration.ofDays(1));
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_Period_throws_DateTimeException() {
+        try {
+            JapaneseDate.now().minus(Period.ofDays(1));
+            fail();
+        } catch (DateTimeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_japanesePeriod() {
+        JapaneseDate date = JapaneseDate.of(REIWA, 3, 5, 21);
+
+        assertEquals(JapaneseDate.of(REIWA, 2, 4, 20),
+                date.minus(JapaneseChronology.INSTANCE.period(1, 1, 1)));
+    }
+
+    @Test
+    public void minus_japanesePeriod_withNegative() {
+        JapaneseDate date = JapaneseDate.of(REIWA, 2, 5, 21);
+
+        assertEquals(JapaneseDate.of(REIWA, 3, 8, 26),
+                date.minus(JapaneseChronology.INSTANCE.period(-1, -3, -5)));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/time/chrono/MinguoChronologyTest.java b/luni/src/test/java/libcore/java/time/chrono/MinguoChronologyTest.java
index 4d9e7bc..044e6f9 100644
--- a/luni/src/test/java/libcore/java/time/chrono/MinguoChronologyTest.java
+++ b/luni/src/test/java/libcore/java/time/chrono/MinguoChronologyTest.java
@@ -17,6 +17,8 @@
 
 import org.junit.Test;
 import java.time.LocalDate;
+import java.time.chrono.HijrahChronology;
+import java.time.chrono.HijrahDate;
 import java.time.chrono.MinguoChronology;
 import java.time.chrono.MinguoDate;
 import java.time.chrono.MinguoEra;
@@ -119,4 +121,11 @@
         assertEquals(31 + 5, date.getLong(ChronoField.DAY_OF_YEAR));
         assertEquals(date.toEpochDay(), date.getLong(ChronoField.EPOCH_DAY));
     }
+
+    @Test
+    public void getEpochDay() {
+        // 18766th Epoch Day is 19 May 2021
+        assertEquals(MinguoDate.of(110, 5, 19), MinguoChronology.INSTANCE.dateEpochDay(18766));
+        assertEquals(MinguoDate.of(59, 1, 1), MinguoChronology.INSTANCE.dateEpochDay(0));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/time/chrono/MinguoDateTest.java b/luni/src/test/java/libcore/java/time/chrono/MinguoDateTest.java
new file mode 100644
index 0000000..5fbc1f7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/MinguoDateTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Period;
+import java.time.chrono.MinguoChronology;
+import java.time.chrono.MinguoDate;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.UnsupportedTemporalTypeException;
+
+@RunWith(JUnit4.class)
+public class MinguoDateTest {
+
+    @Test
+    public void minus_null_throwsNpe() {
+        try {
+            MinguoDate.now().minus(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_days() {
+        MinguoDate date = MinguoDate.of(110, 1, 1);
+
+        assertEquals(MinguoDate.of(109, 12, 31), date.minus(1, ChronoUnit.DAYS));
+    }
+
+    @Test
+    public void minus_Duration_throws_UnsupportedTemporalTypeException() {
+        try {
+            MinguoDate.now().minus(Duration.ofDays(1));
+            fail();
+        } catch (UnsupportedTemporalTypeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_Period_throws_DateTimeException() {
+       try {
+           MinguoDate.now().minus(Period.ofDays(1));
+           fail();
+       } catch (DateTimeException ignored) {
+           // expected
+       }
+    }
+
+    @Test
+    public void minus_minguoPeriod() {
+        MinguoDate date = MinguoDate.of(110, 1, 1);
+
+        assertEquals(MinguoDate.of(108, 11, 30),
+                date.minus(MinguoChronology.INSTANCE.period(1, 1, 1)));
+    }
+
+    @Test
+    public void minus_minguoPeriod_withNegative() {
+        MinguoDate date = MinguoDate.of(110, 2, 28);
+
+        assertEquals(MinguoDate.of(109, 3, 29),
+                date.minus(MinguoChronology.INSTANCE.period(1, -1, -1)));
+
+        assertEquals(MinguoDate.of(110, 3, 29),
+                date.minus(MinguoChronology.INSTANCE.period(0, -1, -1)));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/time/chrono/ThaiBuddhistDateTest.java b/luni/src/test/java/libcore/java/time/chrono/ThaiBuddhistDateTest.java
new file mode 100644
index 0000000..34b08b2
--- /dev/null
+++ b/luni/src/test/java/libcore/java/time/chrono/ThaiBuddhistDateTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 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.time.chrono;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.time.DateTimeException;
+import java.time.Duration;
+import java.time.Period;
+import java.time.chrono.ChronoPeriod;
+import java.time.chrono.ThaiBuddhistChronology;
+import java.time.chrono.ThaiBuddhistDate;
+
+@RunWith(JUnit4.class)
+public class ThaiBuddhistDateTest {
+
+    @Test
+    public void minus_thaiBuddhistChronologyPeriod() {
+        ThaiBuddhistDate date = ThaiBuddhistDate.of(2484, 1, 1);
+
+        ChronoPeriod period = ThaiBuddhistChronology.INSTANCE.period(1, 1, 1);
+
+        assertEquals(ThaiBuddhistDate.of(2482, 11, 30), date.minus(period));
+    }
+
+    @Test
+    public void minus_thaiBuddhistChronologyPeriod_withNegative() {
+        ThaiBuddhistDate date = ThaiBuddhistDate.of(2484, 1, 1);
+
+        ChronoPeriod period = ThaiBuddhistChronology.INSTANCE.period(1, -1, -1);
+
+        assertEquals(ThaiBuddhistDate.of(2483, 2, 2), date.minus(period));
+    }
+
+    @Test
+    public void minus_javaTimePeriod_shouldThrowDateTimeException() {
+        ThaiBuddhistDate date = ThaiBuddhistDate.of(2484, 1, 1);
+
+        try {
+            date.minus(Period.ofDays(1));
+            fail();
+        } catch (DateTimeException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void minus_javaTimeDuration_shouldThrowDateTimeException() {
+        ThaiBuddhistDate date = ThaiBuddhistDate.of(2484, 1, 1);
+
+        try {
+            date.minus(Duration.ofDays(1));
+            fail();
+        } catch (DateTimeException ignored) {
+            // excepted
+        }
+    }
+
+    @Test
+    public void minusNull_shouldThrowNpe() {
+        try {
+            ThaiBuddhistDate.now().minus(null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
index 0e57178..7db90cd 100644
--- a/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
+++ b/luni/src/test/java/libcore/java/time/format/DateTimeFormatterTest.java
@@ -16,9 +16,19 @@
 package libcore.java.time.format;
 
 import org.junit.Test;
+
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.chrono.Chronology;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeFormatterBuilder;
 import java.time.format.DecimalStyle;
+import java.time.format.FormatStyle;
+import java.time.temporal.ChronoField;
+import java.time.temporal.ChronoUnit;
+import java.time.temporal.TemporalAccessor;
 import java.util.Locale;
 
 import static org.junit.Assert.assertEquals;
@@ -60,4 +70,40 @@
             assertEquals(formatter.toString(), DecimalStyle.STANDARD, formatter.getDecimalStyle());
         }
     }
+
+    // Regression test for http://b/170717042.
+    @Test
+    public void test_format_locale_agq() {
+        Locale locale = new Locale("agq");
+        ZonedDateTime zonedDateTime = Instant.EPOCH.atZone(ZoneId.of("UTC"));
+        assertEquals("kɨbâ kɨ 1",
+                formatWithPattern(locale, "qqqq"/* standalone full quarter */, zonedDateTime));
+    }
+
+    @Test
+    public void test_format_locale_en_US() {
+        Locale locale = Locale.US;
+        ZonedDateTime zonedDateTime = Instant.EPOCH.atZone(ZoneId.of("UTC"));
+        assertEquals("1st quarter",
+                formatWithPattern(locale, "qqqq"/* standalone full quarter */, zonedDateTime));
+    }
+
+    private static String formatWithPattern(Locale l, String pattern, TemporalAccessor datetime) {
+        return DateTimeFormatter.ofPattern(pattern, l).format(datetime);
+    }
+
+    // 1 January 2022 00:00:00 GMT+00:00
+    private static final Instant TEST_INSTANT = Instant.ofEpochSecond(1640995200L);
+
+    // Regression test for http://b/174804526 when DateTimeFormatter fetches symbol 'B' from ICU.
+    @Test
+    public void test_format_locale_my_MM() {
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
+                .withLocale(new Locale("my", "MM"))
+                .withZone(ZoneOffset.UTC);
+        assertEquals("0:00", dateTimeFormatter.format(TEST_INSTANT));
+        TemporalAccessor accessor = dateTimeFormatter.parse("23:59");
+        assertEquals(23, accessor.getLong(ChronoField.HOUR_OF_DAY));
+        assertEquals(59, accessor.getLong(ChronoField.MINUTE_OF_HOUR));
+    }
 }
diff --git a/luni/src/test/java/libcore/java/time/zone/IcuZoneRulesProviderTest.java b/luni/src/test/java/libcore/java/time/zone/IcuZoneRulesProviderTest.java
deleted file mode 100644
index c3c0f50..0000000
--- a/luni/src/test/java/libcore/java/time/zone/IcuZoneRulesProviderTest.java
+++ /dev/null
@@ -1,186 +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.java.time.zone;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import android.icu.util.BasicTimeZone;
-import android.icu.util.TimeZone;
-import android.icu.util.TimeZoneRule;
-import android.icu.util.TimeZoneTransition;
-import java.time.Duration;
-import java.time.Instant;
-import java.time.LocalDateTime;
-import java.time.Month;
-import java.time.ZoneOffset;
-import java.time.zone.ZoneOffsetTransition;
-import java.time.zone.ZoneRules;
-import java.time.zone.ZoneRulesProvider;
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-
-/**
- * Test the {@link java.time.zone.IcuZoneRulesProvider}.
- *
- * It is indirectly tested via static methods in {@link ZoneRulesProvider} as all the relevant
- * methods are protected. This test verifies that the rules returned by that provider behave
- * equivalently to the ICU rules from which they are created.
- */
-@RunWith(Parameterized.class)
-public class IcuZoneRulesProviderTest {
-
-    @Parameterized.Parameters(name = "{0}")
-    public static Iterable<String> getZoneIds() {
-        Set<String> availableZoneIds = ZoneRulesProvider.getAvailableZoneIds();
-        assertFalse("no zones returned", availableZoneIds.isEmpty());
-        return availableZoneIds;
-    }
-
-    private final String zoneId;
-
-    public IcuZoneRulesProviderTest(final String zoneId) {
-        this.zoneId = zoneId;
-    }
-
-    /**
-     * Verifies that ICU and java.time return the same transitions before and after a pre-selected
-     * set of instants in time.
-     */
-    @Test
-    public void testTransitionsNearInstants() {
-        // An arbitrary set of instants at which to test the offsets in both implementations.
-        Instant[] instants = new Instant[] {
-                LocalDateTime.of(1900, Month.DECEMBER, 24, 12, 0).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(1970, Month.JANUARY, 1, 2, 3).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(1980, Month.FEBRUARY, 4, 5, 6).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(1990, Month.MARCH, 7, 8, 9).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(2000, Month.APRIL, 10, 11, 12).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(2016, Month.MAY, 13, 14, 15).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(2020, Month.JUNE, 16, 17, 18).toInstant(ZoneOffset.UTC),
-                LocalDateTime.of(2100, Month.JULY, 19, 20, 21).toInstant(ZoneOffset.UTC),
-                // yes, adding "now" makes the test time-dependent, but it also ensures that future
-                // updates don't break on the then-current date.
-                Instant.now()
-        };
-        // Coincidentally this test verifies that all zones can be converted to ZoneRules and
-        // don't violate any of the assumptions of IcuZoneRulesProvider.
-        ZoneRules rules = ZoneRulesProvider.getRules(zoneId, false);
-        BasicTimeZone timeZone = (BasicTimeZone) TimeZone.getTimeZone(zoneId);
-
-        int[] icuOffsets = new int[2];
-        for (Instant instant : instants) {
-            ZoneOffset offset = rules.getOffset(instant);
-            Duration daylightSavings = rules.getDaylightSavings(instant);
-            timeZone.getOffset(instant.toEpochMilli(), false, icuOffsets);
-
-            assertEquals("total offset for " + zoneId + " at " + instant,
-                    icuOffsets[1] + icuOffsets[0], offset.getTotalSeconds() * 1000);
-            assertEquals("dst offset for " + zoneId + " at " + instant,
-                    icuOffsets[1], daylightSavings.toMillis());
-
-            ZoneOffsetTransition jtTrans;
-            TimeZoneTransition icuTrans;
-
-            jtTrans = rules.nextTransition(instant);
-            icuTrans = timeZone.getNextTransition(instant.toEpochMilli(), false);
-            while (isIcuOnlyTransition(icuTrans)) {
-                icuTrans = timeZone.getNextTransition(icuTrans.getTime(), false);
-            }
-            assertEquivalent(icuTrans, jtTrans);
-
-            jtTrans = rules.previousTransition(instant);
-            icuTrans = timeZone.getPreviousTransition(instant.toEpochMilli(), false);
-            // Find previous "real" transition.
-            while (isIcuOnlyTransition(icuTrans)) {
-                icuTrans = timeZone.getPreviousTransition(icuTrans.getTime(), false);
-            }
-            assertEquivalent(icuTrans, jtTrans);
-        }
-    }
-
-    /**
-     * Verifies that ICU and java.time rules return the same transitions between 1900 and 2100.
-     */
-    @Test
-    public void testAllTransitions() {
-        final Instant start = LocalDateTime.of(1900, Month.JANUARY, 1, 12, 0)
-                .toInstant(ZoneOffset.UTC);
-        // Many timezones have ongoing DST changes, so they would generate transitions endlessly.
-        // Pick a far-future end date to stop comparing in that case.
-        final Instant end = LocalDateTime.of(2100, Month.DECEMBER, 31, 12, 0)
-                .toInstant(ZoneOffset.UTC);
-
-        ZoneRules rules = ZoneRulesProvider.getRules(zoneId, false);
-        BasicTimeZone timeZone = (BasicTimeZone) TimeZone.getTimeZone(zoneId);
-
-        Instant instant = start;
-        while (instant.isBefore(end)) {
-            ZoneOffsetTransition jtTrans;
-            TimeZoneTransition icuTrans;
-
-            jtTrans = rules.nextTransition(instant);
-            icuTrans = timeZone.getNextTransition(instant.toEpochMilli(), false);
-            while (isIcuOnlyTransition(icuTrans)) {
-                icuTrans = timeZone.getNextTransition(icuTrans.getTime(), false);
-            }
-            assertEquivalent(icuTrans, jtTrans);
-            if (jtTrans == null) {
-                break;
-            }
-            instant = jtTrans.getInstant();
-        }
-    }
-
-    /**
-     * Returns {@code true} iff this transition will only be returned by ICU code.
-     * ICU reports "no-op" transitions where the raw offset and the dst savings
-     * change by the same absolute value in opposite directions, java.time doesn't
-     * return them, so find the next "real" transition.
-     */
-    private static boolean isIcuOnlyTransition(TimeZoneTransition transition) {
-        if (transition == null) {
-            return false;
-        }
-        return transition.getFrom().getRawOffset() + transition.getFrom().getDSTSavings()
-                == transition.getTo().getRawOffset() + transition.getTo().getDSTSavings();
-    }
-
-    /**
-     * Asserts that the ICU {@link TimeZoneTransition} is equivalent to the java.time {@link
-     * ZoneOffsetTransition}.
-     */
-    private static void assertEquivalent(
-            TimeZoneTransition icuTransition, ZoneOffsetTransition jtTransition) {
-        if (icuTransition == null) {
-            assertNull(jtTransition);
-            return;
-        }
-        assertEquals("time of transition",
-                Instant.ofEpochMilli(icuTransition.getTime()), jtTransition.getInstant());
-        TimeZoneRule from = icuTransition.getFrom();
-        TimeZoneRule to = icuTransition.getTo();
-        assertEquals("offset before",
-                (from.getDSTSavings() + from.getRawOffset()) / 1000,
-                jtTransition.getOffsetBefore().getTotalSeconds());
-        assertEquals("offset after",
-                (to.getDSTSavings() + to.getRawOffset()) / 1000,
-                jtTransition.getOffsetAfter().getTotalSeconds());
-    }
-}
diff --git a/luni/src/test/java/libcore/java/util/CalendarTest.java b/luni/src/test/java/libcore/java/util/CalendarTest.java
index cdeab95..abe5ab8 100644
--- a/luni/src/test/java/libcore/java/util/CalendarTest.java
+++ b/luni/src/test/java/libcore/java/util/CalendarTest.java
@@ -418,16 +418,4 @@
 
         }
     }
-
-    /**
-     * 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/ConcurrentHashMapTest.java b/luni/src/test/java/libcore/java/util/ConcurrentHashMapTest.java
deleted file mode 100644
index 397108c..0000000
--- a/luni/src/test/java/libcore/java/util/ConcurrentHashMapTest.java
+++ /dev/null
@@ -1,75 +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.java.util;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-public class ConcurrentHashMapTest extends junit.framework.TestCase {
-
-    public void test_getOrDefault() {
-        MapDefaultMethodTester.test_getOrDefault(new ConcurrentHashMap<>(),
-                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
-                true /*getAcceptsAnyObject*/);
-    }
-
-    public void test_forEach() {
-        MapDefaultMethodTester.test_forEach(new ConcurrentHashMap<>());
-    }
-
-    public void test_putIfAbsent() {
-        MapDefaultMethodTester
-                .test_putIfAbsent(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
-                        false /*doesNotAcceptNullValue*/);
-    }
-
-    public void test_remove() {
-        MapDefaultMethodTester
-                .test_remove(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
-                        false /*doesNotAcceptNullValue*/);
-    }
-
-    public void test_replace$K$V$V() {
-        MapDefaultMethodTester
-                .test_replace$K$V$V(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
-                        false /*doesNotAcceptNullValue*/);
-    }
-
-    public void test_replace$K$V() {
-        MapDefaultMethodTester.test_replace$K$V(new ConcurrentHashMap<>(),
-                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
-    }
-
-    public void test_computeIfAbsent() {
-        MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentHashMap<>(),
-                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
-    }
-
-    public void test_computeIfPresent() {
-        MapDefaultMethodTester.test_computeIfPresent(new ConcurrentHashMap<>(),
-                false /*doesNotAcceptNullKey*/);
-    }
-
-    public void test_compute() {
-        MapDefaultMethodTester
-                .test_compute(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/);
-    }
-
-    public void test_merge() {
-        MapDefaultMethodTester.test_merge(new ConcurrentHashMap<>(),
-                false /*doesNotAcceptNullKey*/);
-    }
-}
diff --git a/luni/src/test/java/libcore/java/util/CurrencyTest.java b/luni/src/test/java/libcore/java/util/CurrencyTest.java
index 6ed6bc6..87f4315 100644
--- a/luni/src/test/java/libcore/java/util/CurrencyTest.java
+++ b/luni/src/test/java/libcore/java/util/CurrencyTest.java
@@ -165,4 +165,50 @@
         assertEquals(0, Currency.getInstance("XFU").getNumericCode());
     }
 
+    /**
+    * It tests the current behavior, but the current behavior may not be expected.
+    */
+    public void test_getInstanceWithLocaleVariant() {
+        Locale[] invalidLocales = new Locale[] {
+            // Locale without country code
+            Locale.ROOT,
+            new Locale("en"),
+            // Invalid country code
+            new Locale("en", "XA"),
+            new Locale("en", "AA"),
+            // Locale with 3 special variants. It's invalid due to historic reason.
+            new Locale("de", "DE", "PREEURO"),
+            new Locale("pt", "PT", "PREEURO"),
+            new Locale("de", "DE", "EURO"),
+            new Locale("pt", "PT", "EURO"),
+            new Locale("zh", "HK", "HK"),
+            new Locale("en", "US", "HK"),
+        };
+        for (Locale invalidLocale : invalidLocales) {
+            try {
+                Currency.getInstance(invalidLocale);
+                fail("Currency.getInstance doesn't fail with locale:"
+                    + invalidLocale.toLanguageTag());
+            } catch (IllegalArgumentException e){
+                // expected
+            }
+        }
+    }
+
+    public void test_localeExtension() {
+        // Language=en, Country=US, Currency=Euro
+        Locale locale = Locale.forLanguageTag("en-US-u-cu-eur");
+        // This is expected because Currency.getInstance only considers country code, not extension.
+        assertEquals("USD", getCurrency(locale).getCurrencyCode());
+    }
+
+    private static Currency getCurrency(Locale l) {
+        try {
+            return Currency.getInstance(l);
+        } catch (IllegalArgumentException e) {
+            // The locale could have no country or does not have currency for other reasons.
+            return null;
+        }
+    }
+
 }
diff --git a/luni/src/test/java/libcore/java/util/EvilMapTest.java b/luni/src/test/java/libcore/java/util/EvilMapTest.java
index 2c5f913..3532462 100644
--- a/luni/src/test/java/libcore/java/util/EvilMapTest.java
+++ b/luni/src/test/java/libcore/java/util/EvilMapTest.java
@@ -40,7 +40,7 @@
     // ...but potentially return many entries.
     @Override public Set<Entry<K, V>> entrySet() { return entries; }
 
-    // Dummy implementation, not relevant for this test but
+    // Fake implementation, not relevant for this test but
     // necessary to implement AbstractMap.
     @Override public V put(K key, V val) { return val; }
   }
diff --git a/luni/src/test/java/libcore/java/util/InvalidPropertiesFormatExceptionTest.java b/luni/src/test/java/libcore/java/util/InvalidPropertiesFormatExceptionTest.java
index 35693d6..046be49 100644
--- a/luni/src/test/java/libcore/java/util/InvalidPropertiesFormatExceptionTest.java
+++ b/luni/src/test/java/libcore/java/util/InvalidPropertiesFormatExceptionTest.java
@@ -94,7 +94,7 @@
             Object obj = SerializationTester.deserializeHex(hex);
             fail("Deserialized to " + obj);
         } catch (NotSerializableException expected) {
-            // Sanity check that this is the right exception that we expected.
+            // Check that this is the right exception that we expected.
             assertEquals("Not serializable.", expected.getMessage());
         }
     }
@@ -107,7 +107,7 @@
             }
             fail();
         } catch (NotSerializableException expected) {
-            // Sanity check that this is the right exception that we expected.
+            // Check that this is the right exception that we expected.
             assertEquals("Not serializable.", expected.getMessage());
         }
     }
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 6cb9e17..84a8740 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -1037,28 +1037,28 @@
         List<LanguageRange> priorityList = languageRangesOf("de-DE", "de-*-DE");
         List<Locale> locales = localesOf("de-DE", "de-Latn-DE", "ja-JP");
 
-        Locale dummy = Locale.FRANCE;
+        Locale fake = Locale.FRANCE;
         // should not throw
-        Locale.filter(priorityList, locales).add(dummy);
-        Locale.filter(priorityList, locales, AUTOSELECT_FILTERING).add(dummy);
-        Locale.filter(priorityList, locales, EXTENDED_FILTERING).add(dummy);
-        Locale.filter(priorityList, locales, IGNORE_EXTENDED_RANGES).add(dummy);
-        Locale.filter(priorityList, locales, MAP_EXTENDED_RANGES).add(dummy);
-        Locale.filter(languageRangesOf("de-DE"), locales, REJECT_EXTENDED_RANGES).add(dummy);
+        Locale.filter(priorityList, locales).add(fake);
+        Locale.filter(priorityList, locales, AUTOSELECT_FILTERING).add(fake);
+        Locale.filter(priorityList, locales, EXTENDED_FILTERING).add(fake);
+        Locale.filter(priorityList, locales, IGNORE_EXTENDED_RANGES).add(fake);
+        Locale.filter(priorityList, locales, MAP_EXTENDED_RANGES).add(fake);
+        Locale.filter(languageRangesOf("de-DE"), locales, REJECT_EXTENDED_RANGES).add(fake);
     }
 
     public void test_filter_resultIsModifiable_tags() {
         List<LanguageRange> priorityList = languageRangesOf("de-DE", "de-*-DE");
         List<String> tags = tagsOf("de-DE", "de-Latn-DE", "ja-JP");
 
-        String dummy = "fr-FR";
+        String fake = "fr-FR";
         // should not throw
-        Locale.filterTags(priorityList, tags).add(dummy);
-        Locale.filterTags(priorityList, tags, AUTOSELECT_FILTERING).add(dummy);
-        Locale.filterTags(priorityList, tags, EXTENDED_FILTERING).add(dummy);
-        Locale.filterTags(priorityList, tags, IGNORE_EXTENDED_RANGES).add(dummy);
-        Locale.filterTags(priorityList, tags, MAP_EXTENDED_RANGES).add(dummy);
-        Locale.filterTags(languageRangesOf("de-DE"), tags, REJECT_EXTENDED_RANGES).add(dummy);
+        Locale.filterTags(priorityList, tags).add(fake);
+        Locale.filterTags(priorityList, tags, AUTOSELECT_FILTERING).add(fake);
+        Locale.filterTags(priorityList, tags, EXTENDED_FILTERING).add(fake);
+        Locale.filterTags(priorityList, tags, IGNORE_EXTENDED_RANGES).add(fake);
+        Locale.filterTags(priorityList, tags, MAP_EXTENDED_RANGES).add(fake);
+        Locale.filterTags(languageRangesOf("de-DE"), tags, REJECT_EXTENDED_RANGES).add(fake);
     }
 
     public void test_forLanguageTag() {
@@ -1507,8 +1507,10 @@
         assertEquals("en-US-POSIX", posix.toLanguageTag());
     }
 
-    public void test_forLanguageTag_grandFatheredLocale() {
-        // Regular grandfathered locale.
+    // Legacy locales in this test refer to "grandfathered" locales as defined in
+    // https://tools.ietf.org/html/bcp47#section-2.2.8
+    public void test_forLanguageTag_legacyLocale() {
+        // Regular legacy locale.
         Locale gaulish = Locale.forLanguageTag("cel-gaulish");
         assertEquals("xtg", gaulish.getLanguage());
         assertEquals("cel-gaulish", gaulish.getExtension(Locale.PRIVATE_USE_EXTENSION));
@@ -1516,7 +1518,7 @@
         assertEquals("", gaulish.getScript());
         assertEquals("", gaulish.getVariant());
 
-        // Irregular grandfathered locale.
+        // Irregular legacy locale.
         Locale enochian = Locale.forLanguageTag("i-enochian");
         assertEquals("", enochian.getLanguage());
         assertEquals("i-enochian", enochian.getExtension(Locale.PRIVATE_USE_EXTENSION));
diff --git a/luni/src/test/java/libcore/java/util/Locales.java b/luni/src/test/java/libcore/java/util/Locales.java
index 102188b..8fe231b 100644
--- a/luni/src/test/java/libcore/java/util/Locales.java
+++ b/luni/src/test/java/libcore/java/util/Locales.java
@@ -56,7 +56,7 @@
         Locales oldLocales = getDefault();
         Locales newLocales = new Locales(uncategorizedLocale, displayLocale, formatLocale);
         newLocales.setAsDefault();
-        assertEquals(newLocales, getDefault()); // sanity check
+        assertEquals(newLocales, getDefault());
         return oldLocales;
     }
 
diff --git a/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java b/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
index fdfcdcf..2bedf7c 100644
--- a/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/SimpleTimeZoneTest.java
@@ -41,7 +41,7 @@
     private static final TimeZone UTC = TimeZone.getTimeZone("UTC");
 
     /**
-     * Sanity check to ensure that the standard TimeZone for Europe/Paris has the correct DST
+     * Check to ensure that the standard TimeZone for Europe/Paris has the correct DST
      * transition times.
      */
     public void testStandardParis2014() {
@@ -100,7 +100,7 @@
     }
 
     /**
-     * Sanity check to ensure that the standard TimeZone for America/New_York has the correct DST
+     * Check to ensure that the standard TimeZone for America/New_York has the correct DST
      * transition times.
      */
     public void testStandardNewYork2014() {
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index da4a04f..a686534 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -298,7 +298,7 @@
                 }
             }
 
-            // Sanity check that whenever a display name is just a GMT string that it's the
+            // Check that whenever a display name is just a GMT string that it's the
             // right GMT string.
             String gmtDst = formatGmtString(tz, true);
             String gmtStd = formatGmtString(tz, false);
diff --git a/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java b/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
index 1c9b399..3ae0acc 100644
--- a/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
+++ b/luni/src/test/java/libcore/java/util/beans/PropertyChangeSupportTest.java
@@ -16,6 +16,7 @@
 
 package libcore.java.util.beans;
 
+import java.beans.IndexedPropertyChangeEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeListenerProxy;
@@ -246,6 +247,68 @@
         }.test();
     }
 
+    public void testFireIndexedPropertyChange_intUpdate() {
+        Object bean = "bean";
+        PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+        EventLog listenerToIntProperty = new EventLog();
+        support.addPropertyChangeListener("intProperty", listenerToIntProperty);
+
+        support.fireIndexedPropertyChange("intProperty", 10, 1, 2);
+
+        List<PropertyChangeEvent> events = listenerToIntProperty.log;
+        assertEquals(1, events.size());
+        assertEquals(1, events.get(0).getOldValue());
+        assertEquals(2, events.get(0).getNewValue());
+        assertEquals("intProperty", events.get(0).getPropertyName());
+        assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
+        assertEquals(10, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
+    }
+
+    public void testFireIndexedPropertyChange_intUpdate_noEventWhenOldIsEqualToNew() {
+        Object bean = "bean";
+        PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+        EventLog listenerToIntProperty = new EventLog();
+        support.addPropertyChangeListener("intProperty", listenerToIntProperty);
+
+        support.fireIndexedPropertyChange("intProperty", 0, 1, 1);
+
+        List<PropertyChangeEvent> events = listenerToIntProperty.log;
+        assertTrue(events.isEmpty());
+    }
+
+    public void testFireIndexedPropertyChange_booleanUpdate() {
+        Object bean = "bean";
+        PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+        EventLog listenerToBooleanProperty = new EventLog();
+        support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
+
+        support.fireIndexedPropertyChange("booleanProperty", 11, true, false);
+
+        List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
+        assertEquals(1, events.size());
+        assertEquals(true, events.get(0).getOldValue());
+        assertEquals(false, events.get(0).getNewValue());
+        assertEquals("booleanProperty", events.get(0).getPropertyName());
+        assertTrue(events.get(0) instanceof IndexedPropertyChangeEvent);
+        assertEquals(11, ((IndexedPropertyChangeEvent) events.get(0)).getIndex());
+    }
+
+    public void testFireIndexedPropertyChange_booleanUpdate_noEventWhenOldIsEqualToNew() {
+        Object bean = "bean";
+        PropertyChangeSupport support = new PropertyChangeSupport(bean);
+
+        EventLog listenerToBooleanProperty = new EventLog();
+        support.addPropertyChangeListener("booleanProperty", listenerToBooleanProperty);
+
+        support.fireIndexedPropertyChange("booleanProperty", 0, true, true);
+
+        List<PropertyChangeEvent> events = listenerToBooleanProperty.log;
+        assertTrue(events.isEmpty());
+    }
+
     private String describe(PropertyChangeListener[] listeners) {
         List<String> result = new ArrayList<String>();
         for (PropertyChangeListener listener : listeners) {
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java
new file mode 100644
index 0000000..c4ed1e6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractExecutorServiceTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractExecutorServiceTest {
+
+    static class TestExecutorService extends AbstractExecutorService {
+
+        public volatile boolean isRunning = true;
+
+        public boolean awaitTermination(long timeout, TimeUnit unit) {
+            return isShutdown();
+        }
+
+        public boolean isShutdown() {
+            return !isRunning;
+        }
+
+        public boolean isTerminated() {
+            return isShutdown();
+        }
+
+        public void shutdown() {
+            isRunning = false;
+        }
+
+        public List<Runnable> shutdownNow() {
+            shutdown();
+            return Collections.emptyList();
+        }
+
+        public void execute(Runnable command) {
+            command.run();
+        }
+
+        public <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
+            return super.newTaskFor(runnable, value);
+        }
+    }
+
+    @Test
+    public void testSubmitRunnableWithValue() throws Exception {
+        Integer value = Integer.valueOf(42);
+        ExecutorService service = new TestExecutorService();
+        AtomicBoolean didRun = new AtomicBoolean(false);
+        Future<Integer> future = service.submit(() -> didRun.set(true), value);
+        Integer result = future.get();
+        assertSame(value, result);
+        assertTrue(didRun.get());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
new file mode 100644
index 0000000..2735eab
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedLongSynchronizerTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractQueuedLongSynchronizerTest {
+
+    class DefaultMutex extends AbstractQueuedLongSynchronizer {
+
+        @Override
+        public boolean isHeldExclusively() {
+            return super.isHeldExclusively();
+        }
+
+        @Override
+        public boolean tryAcquire(long acquires) {
+            return super.tryAcquire(acquires);
+        }
+
+        @Override
+        public long tryAcquireShared(long acquires) {
+            return super.tryAcquireShared(acquires);
+        }
+
+        @Override
+        public boolean tryRelease(long releases) {
+            return super.tryRelease(releases);
+        }
+
+        @Override
+        public boolean tryReleaseShared(long releases) {
+            return super.tryReleaseShared(releases);
+        }
+
+        public AbstractQueuedLongSynchronizer.ConditionObject newCondition() {
+            return new AbstractQueuedLongSynchronizer.ConditionObject();
+        }
+
+    }
+
+    @Test
+    public void testDefaultIsHeldExclusivelyFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.isHeldExclusively();
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryAcquireFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryAcquire(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryAcquireSharedFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryAcquireShared(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryReleaseFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryRelease(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryReleaseSharedFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryReleaseShared(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testConditionObjectCreation() {
+        DefaultMutex mutex = new DefaultMutex();
+        AbstractQueuedLongSynchronizer.ConditionObject condition = mutex.newCondition();
+        assertTrue(mutex.owns(condition));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java
new file mode 100644
index 0000000..0c0b98a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/AbstractQueuedSynchronizerTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class AbstractQueuedSynchronizerTest {
+
+    class DefaultMutex extends AbstractQueuedSynchronizer {
+
+        @Override
+        public boolean isHeldExclusively() {
+            return super.isHeldExclusively();
+        }
+
+        @Override
+        public boolean tryAcquire(int acquires) {
+            return super.tryAcquire(acquires);
+        }
+
+        @Override
+        public int tryAcquireShared(int acquires) {
+            return super.tryAcquireShared(acquires);
+        }
+
+        @Override
+        public boolean tryRelease(int releases) {
+            return super.tryRelease(releases);
+        }
+
+        @Override
+        public boolean tryReleaseShared(int releases) {
+            return super.tryReleaseShared(releases);
+        }
+
+        public AbstractQueuedSynchronizer.ConditionObject newCondition() {
+            return new AbstractQueuedSynchronizer.ConditionObject();
+        }
+
+    }
+
+    @Test
+    public void testDefaultIsHeldExclusivelyFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.isHeldExclusively();
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryAcquireFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryAcquire(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryAcquireSharedFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryAcquireShared(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryReleaseFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryRelease(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testDefaultTryReleaseSharedFails() {
+        DefaultMutex mutex = new DefaultMutex();
+        try {
+            mutex.tryReleaseShared(1);
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testConditionObjectCreation() {
+        DefaultMutex mutex = new DefaultMutex();
+        AbstractQueuedSynchronizer.ConditionObject condition = mutex.newCondition();
+        assertTrue(mutex.owns(condition));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java
new file mode 100644
index 0000000..3632c09
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/BrokenBarrierExceptionTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.BrokenBarrierException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class BrokenBarrierExceptionTest {
+
+    /**
+     * constructor creates exception with detail message
+     */
+    @Test
+    public void testConstructWithMessage() {
+        BrokenBarrierException exception = new BrokenBarrierException("test");
+        assertEquals("test", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java
new file mode 100644
index 0000000..956026c
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/CompletionExceptionTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.CompletionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class CompletionExceptionTest {
+
+    // Adding derived class to be able to test the protected constructors
+    private class TestCompletionException extends CompletionException {
+        public TestCompletionException() {
+            super();
+        }
+        public TestCompletionException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * constructor creates exception without any details
+     */
+    @Test
+    public void testConstructNoMessage() {
+        CompletionException exception = new TestCompletionException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with detail message
+     */
+    @Test
+    public void testConstructWithMessage() {
+        CompletionException exception = new TestCompletionException("test");
+        assertEquals("test", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with detail message and cause
+     */
+    @Test
+    public void testConstructWithMessageAndCause() {
+        Throwable cause = new Exception();
+        CompletionException exception = new CompletionException("test", cause);
+        assertEquals("test", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java
new file mode 100644
index 0000000..233e6d3
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentHashMapTest.java
@@ -0,0 +1,391 @@
+/*
+ * 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.java.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+import java.util.function.ToDoubleBiFunction;
+import java.util.function.ToDoubleFunction;
+import java.util.function.ToIntBiFunction;
+import java.util.function.ToIntFunction;
+import java.util.function.ToLongBiFunction;
+import java.util.function.ToLongFunction;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import libcore.java.util.MapDefaultMethodTester;
+
+@RunWith(JUnit4.class)
+public class ConcurrentHashMapTest {
+
+    // Constants that dictate parallelism for 'reduce' calls. The value represents the number of
+    // elements needed for the operation to be executed in parallel.
+    static final long IN_PARALLEL = 1L;
+    static final long SEQUENTIALLY = Long.MAX_VALUE;
+
+    static final int MAP_SIZE = 100;
+
+    static class SumKeys implements BiFunction<Map.Entry<Long,Long>,
+                 Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
+        public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y) {
+            return new AbstractMap.SimpleEntry<Long,Long>
+             (Long.valueOf(x.getKey().longValue() + y.getKey().longValue()),
+              Long.valueOf(1L));
+        }
+    }
+
+    static class IncrementKey implements Function<Map.Entry<Long, Long>, Map.Entry<Long, Long>> {
+        public Map.Entry<Long, Long> apply(Map.Entry<Long, Long> in) {
+            return new AbstractMap.SimpleEntry<Long, Long>
+                (Long.valueOf(in.getKey().longValue() + 1),
+                 Long.valueOf(1L));
+        }
+    }
+
+    static class KeyAsDouble implements ToDoubleFunction<Map.Entry<Long, Long>> {
+        public double applyAsDouble(Map.Entry<Long, Long> in) {
+            return in.getKey().doubleValue();
+        }
+    }
+
+    static class KeyAsInt implements ToIntFunction<Map.Entry<Long, Long>> {
+        public int applyAsInt(Map.Entry<Long, Long> in) {
+            return in.getKey().intValue();
+        }
+    }
+
+    static class KeyAsLong implements ToLongFunction<Map.Entry<Long, Long>> {
+        public long applyAsLong(Map.Entry<Long, Long> in) {
+            return in.getKey().longValue();
+        }
+    }
+
+    static class IncrementKeyToDouble implements ToDoubleBiFunction<Long, Long> {
+        public double applyAsDouble(Long key, Long value) {
+            return (key.doubleValue() + 1);
+        }
+    }
+
+    static class IncrementKeyToInt implements ToIntBiFunction<Long, Long> {
+        public int applyAsInt(Long key, Long value) {
+            return (key.intValue() + 1);
+        }
+    }
+
+    static class IncrementKeyToLong implements ToLongBiFunction<Long, Long> {
+        public long applyAsLong(Long key, Long value) {
+            return (key.longValue() + 1);
+        }
+    }
+
+    static ConcurrentHashMap<Long, Long> createMap() {
+        ConcurrentHashMap<Long, Long> map = new ConcurrentHashMap<Long, Long>(MAP_SIZE);
+        for (int i = 0; i < MAP_SIZE; ++i) {
+            map.put(Long.valueOf(i), Long.valueOf(-i));
+        }
+        return map;
+    }
+
+    @Test
+    public void testReduceEntriesToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        double result = map.reduceEntriesToDouble(SEQUENTIALLY,
+                new KeyAsDouble(), 0.0, Double::sum);
+        assertEquals((double)MAP_SIZE * (MAP_SIZE - 1) / 2, result, 0.5);
+    }
+
+    @Test
+    public void testReduceEntriesToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        double result = map.reduceEntriesToDouble(IN_PARALLEL,
+                new KeyAsDouble(), 0.0, Double::sum);
+        assertEquals((double)MAP_SIZE * (MAP_SIZE - 1) / 2, result, 0.5);
+    }
+
+    @Test
+    public void testReduceEntriesToIntSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        int result = map.reduceEntriesToInt(SEQUENTIALLY, new KeyAsInt(), 0, Integer::sum);
+        assertEquals((int)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+    }
+
+    @Test
+    public void testReduceEntriesToIntInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        int result = map.reduceEntriesToInt(IN_PARALLEL, new KeyAsInt(), 0, Integer::sum);
+        assertEquals(MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+    }
+
+    @Test
+    public void testReduceEntriesToLongSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        long result = map.reduceEntriesToLong(SEQUENTIALLY, new KeyAsLong(), 0L, Long::sum);
+        assertEquals((long)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+    }
+
+    @Test
+    public void testReduceEntriesToLongInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        long result = map.reduceEntriesToLong(IN_PARALLEL, new KeyAsLong(), 0L, Long::sum);
+        assertEquals((long)MAP_SIZE * (MAP_SIZE - 1) / 2, result);
+    }
+
+    @Test
+    public void testTransformReduceEntriesSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        Map.Entry<Long, Long> result;
+        result = map.reduceEntries(SEQUENTIALLY, new IncrementKey(), new SumKeys());
+        assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result.getKey().longValue());
+    }
+
+    @Test
+    public void testTransformReduceEntriesInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        Map.Entry<Long, Long> result;
+        result = map.reduceEntries(IN_PARALLEL, new IncrementKey(), new SumKeys());
+        assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result.getKey().longValue());
+    }
+
+    @Test
+    public void testTransformReduceEntriesToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        double result = map.reduceToDouble(SEQUENTIALLY,
+                new IncrementKeyToDouble(), 0.0, Double::sum);
+        assertEquals((double)MAP_SIZE * (MAP_SIZE + 1) / 2, result, 0.5);
+    }
+
+    @Test
+    public void testTransformReduceEntriesToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        double result = map.reduceToDouble(IN_PARALLEL,
+                new IncrementKeyToDouble(), 0.0, Double::sum);
+        assertEquals((double)MAP_SIZE * (MAP_SIZE + 1) / 2, result, 0.5);
+    }
+
+    @Test
+    public void testTransformReduceEntriesToIntSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        int result = map.reduceToInt(SEQUENTIALLY, new IncrementKeyToInt(), 0, Integer::sum);
+        assertEquals(MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+    }
+
+    @Test
+    public void testTransformReduceEntriesToIntInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        int result = map.reduceToInt(IN_PARALLEL, new IncrementKeyToInt(), 0, Integer::sum);
+        assertEquals(MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+    }
+
+    @Test
+    public void testTransformReduceEntriesToLongSequentially() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        long result = map.reduceToLong(SEQUENTIALLY, new IncrementKeyToLong(), 0L, Long::sum);
+        assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+    }
+
+    @Test
+    public void testTransformReduceEntriesToLongInParallel() {
+        ConcurrentHashMap<Long, Long> map = createMap();
+        long result = map.reduceToLong(IN_PARALLEL, new IncrementKeyToLong(), 0L, Long::sum);
+        assertEquals((long)MAP_SIZE * (MAP_SIZE + 1) / 2, result);
+    }
+
+    @Test
+    public void testNewKeySetWithCapacity() {
+        final int capacity = 10;
+        Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+        assertTrue(set.isEmpty());
+        for (long i = 0; i < capacity; ++i) {
+            assertTrue(set.add(i));
+        }
+        assertFalse(set.isEmpty());
+        assertEquals(capacity, set.size());
+    }
+
+    @Test
+    public void testNewKeySetWithZeroCapacity() {
+        final int capacity = 0;
+        final int elements = 10;
+        Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+        assertTrue(set.isEmpty());
+        for (long i = 0; i < elements; ++i) {
+            assertTrue(set.add(i));
+        }
+        assertFalse(set.isEmpty());
+        assertEquals(elements, set.size());
+    }
+
+    @Test
+    public void testNewKeySetWithInvalidCapacity() {
+        try {
+            final int capacity = -10;
+            Set<Long> set = ConcurrentHashMap.<Long>newKeySet(capacity);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetOrDefault() {
+        MapDefaultMethodTester.test_getOrDefault(new ConcurrentHashMap<>(),
+                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
+                true /*getAcceptsAnyObject*/);
+    }
+
+    @Test
+    public void testForEach() {
+        MapDefaultMethodTester.test_forEach(new ConcurrentHashMap<>());
+    }
+
+    @Test
+    public void testPutIfAbsent() {
+        MapDefaultMethodTester
+                .test_putIfAbsent(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+                        false /*doesNotAcceptNullValue*/);
+    }
+
+    @Test
+    public void testRemove() {
+        MapDefaultMethodTester
+                .test_remove(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+                        false /*doesNotAcceptNullValue*/);
+    }
+
+    @Test
+    public void testReplace$K$V$V() {
+        MapDefaultMethodTester
+                .test_replace$K$V$V(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/,
+                        false /*doesNotAcceptNullValue*/);
+    }
+
+    @Test
+    public void testReplace$K$V() {
+        MapDefaultMethodTester.test_replace$K$V(new ConcurrentHashMap<>(),
+                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
+    }
+
+    @Test
+    public void testComputeIfAbsent() {
+        MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentHashMap<>(),
+                false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
+    }
+
+    @Test
+    public void testComputeIfPresent() {
+        MapDefaultMethodTester.test_computeIfPresent(new ConcurrentHashMap<>(),
+                false /*doesNotAcceptNullKey*/);
+    }
+
+    @Test
+    public void testCompute() {
+        MapDefaultMethodTester
+                .test_compute(new ConcurrentHashMap<>(), false /*doesNotAcceptNullKey*/);
+    }
+
+    @Test
+    public void testMerge() {
+        MapDefaultMethodTester.test_merge(new ConcurrentHashMap<>(),
+                false /*doesNotAcceptNullKey*/);
+    }
+
+    private ConcurrentHashMap.KeySetView<String, Boolean> createKeySet() {
+        final int count = 5;
+        ConcurrentHashMap.KeySetView<String, Boolean> set =
+            ConcurrentHashMap.<String>newKeySet(count);
+        assertTrue(set.isEmpty());
+        set.add("A");
+        set.add("B");
+        set.add("C");
+        set.add("D");
+        set.add("E");
+        assertFalse(set.isEmpty());
+        assertEquals(count, set.size());
+        return set;
+    }
+
+    @Test
+    public void testKeySetViewClear() {
+        ConcurrentHashMap.KeySetView set = createKeySet();
+        assertFalse(set.isEmpty());
+        set.clear();
+        assertEquals(0, set.size());
+        assertTrue(set.isEmpty());
+    }
+
+    @Test
+    public void testKeySetViewContainsAll() {
+        ConcurrentHashMap.KeySetView set = createKeySet();
+        assertTrue(set.containsAll(Arrays.asList()));
+        assertTrue(set.containsAll(Arrays.asList("A")));
+        assertTrue(set.containsAll(Arrays.asList("A", "E")));
+        assertTrue(set.containsAll(Arrays.asList("A", "B", "C", "D", "E")));
+        assertFalse(set.containsAll(Arrays.asList("A", "B", "F")));
+        assertFalse(set.containsAll(Arrays.asList("F")));
+    }
+
+    @Test
+    public void testKeySetViewForEach() {
+        final int count = 8;
+        ConcurrentHashMap.KeySetView<Integer, Boolean> set =
+            ConcurrentHashMap.<Integer>newKeySet(count);
+        for(int i = 0; i < count; ++i) {
+            set.add(i+1);
+        }
+        LongAdder adder = new LongAdder();
+        set.forEach((Integer x) -> adder.add(x.longValue()));
+        // The size is small enough for the sum not to overflow
+        assertEquals(set.size() * (set.size() + 1) / 2, adder.sum());
+    }
+
+    @Test
+    public void testKeySetViewRemoveAll() {
+        ConcurrentHashMap.KeySetView set = createKeySet();
+        assertTrue(set.removeAll(Arrays.asList("A", "C")));
+        assertEquals(set.size(), 3);
+        assertTrue(set.containsAll(Arrays.asList("B", "D", "E")));
+        assertFalse(set.removeAll(Arrays.asList("A", "C")));
+        assertEquals(set.size(), 3);
+        assertTrue(set.containsAll(Arrays.asList("B", "D", "E")));
+    }
+
+    @Test
+    public void testKeySetViewRetainAll() {
+        ConcurrentHashMap.KeySetView set = createKeySet();
+        assertTrue(set.retainAll(Arrays.asList("A", "C")));
+        assertEquals(set.size(), 2);
+        assertTrue(set.containsAll(Arrays.asList("A", "C")));
+        assertFalse(set.retainAll(Arrays.asList("A", "C")));
+        assertEquals(set.size(), 2);
+        assertTrue(set.containsAll(Arrays.asList("A", "C")));
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
index 54b354e..c175d0b 100644
--- a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListMapTest.java
@@ -16,62 +16,212 @@
 
 package libcore.java.util.concurrent;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentSkipListMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
 
 import libcore.java.util.MapDefaultMethodTester;
 
-public class ConcurrentSkipListMapTest extends junit.framework.TestCase {
+@RunWith(JUnit4.class)
+public class ConcurrentSkipListMapTest {
 
-    public void test_getOrDefault() {
+    @Test
+    public void testGetOrDefault() {
         MapDefaultMethodTester.test_getOrDefault(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/,
                 false /*getAcceptsAnyObject*/);
     }
 
-    public void test_forEach() {
+    @Test
+    public void testForEach() {
         MapDefaultMethodTester.test_forEach(new ConcurrentSkipListMap<>());
     }
 
-    public void test_putIfAbsent() {
+    @Test
+    public void testPutIfAbsent() {
         MapDefaultMethodTester
                 .test_putIfAbsent(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
                         false /*doesNotAcceptNullValue*/);
     }
 
-    public void test_remove() {
+    @Test
+    public void testRemove() {
         MapDefaultMethodTester
                 .test_remove(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
                         false /*doesNotAcceptNullValue*/);
     }
 
-    public void test_replace$K$V$V() {
+    @Test
+    public void testReplace$K$V$V() {
         MapDefaultMethodTester
                 .test_replace$K$V$V(new ConcurrentSkipListMap<>(), false /*doesNotAcceptNullKey*/,
                         false /*doesNotAcceptNullValue*/);
     }
 
-    public void test_replace$K$V() {
+    @Test
+    public void testReplace$K$V() {
         MapDefaultMethodTester.test_replace$K$V(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
     }
 
-    public void test_computeIfAbsent() {
+    @Test
+    public void testComputeIfAbsent() {
         MapDefaultMethodTester.test_computeIfAbsent(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/, false /*doesNotAcceptNullValue*/);
     }
 
-    public void test_computeIfPresent() {
+    @Test
+    public void testComputeIfPresent() {
         MapDefaultMethodTester.test_computeIfPresent(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/);
     }
 
-    public void test_compute() {
+    @Test
+    public void testCompute() {
         MapDefaultMethodTester.test_compute(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/);
     }
 
-    public void test_merge() {
+    @Test
+    public void testMerge() {
         MapDefaultMethodTester.test_merge(new ConcurrentSkipListMap<>(),
                 false /*doesNotAcceptNullKey*/);
     }
+
+    private ConcurrentSkipListMap createPopulatedMap() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        map.put("A", "a");
+        map.put("B", "b");
+        map.put("C", "c");
+        map.put("D", "d");
+        map.put("E", "e");
+        map.put("F", "f");
+        assertFalse(map.isEmpty());
+        return map;
+    }
+
+    @Test
+    public void testCloneFromSorted() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentSkipListMap mapClone = map.clone();
+        assertNotSame(map, mapClone);
+        Set set = map.entrySet();
+        Set setOfClone = mapClone.entrySet();
+        Iterator it = set.iterator();
+        Iterator itOfClone = setOfClone.iterator();
+        while ( it.hasNext() && itOfClone.hasNext() ) {
+            Map.Entry entry = (Map.Entry) it.next();
+            Map.Entry entryOfClone = (Map.Entry) itOfClone.next();
+            assertSame(entry.getKey(), entryOfClone.getKey());
+            assertSame(entry.getValue(), entryOfClone.getValue());
+        }
+        assertFalse(it.hasNext());
+        assertFalse(itOfClone.hasNext());
+    }
+
+    @Test
+    public void testFirstEntry() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        assertEquals("A", map.firstEntry().getKey());
+        assertEquals("a", map.firstEntry().getValue());
+    }
+
+    @Test
+    public void testLastEntry() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        assertEquals("F", map.lastEntry().getKey());
+        assertEquals("f", map.lastEntry().getValue());
+    }
+
+    @Test
+    public void testSubMap() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.subMap("B", "D");
+        assertEquals(2, subMap.size());
+        assertFalse(subMap.containsKey("A"));
+        assertTrue(subMap.containsKey("B"));
+        assertTrue(subMap.containsKey("C"));
+        assertFalse(subMap.containsKey("D"));
+        assertFalse(subMap.containsKey("E"));
+        assertFalse(subMap.containsKey("F"));
+    }
+
+    @Test
+    public void testSubMapEmpty() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.subMap("A", "A");
+        assertTrue(subMap.isEmpty());
+        assertFalse(subMap.containsKey("A"));
+        assertFalse(subMap.containsKey("B"));
+        assertFalse(subMap.containsKey("C"));
+        assertFalse(subMap.containsKey("D"));
+        assertFalse(subMap.containsKey("E"));
+        assertFalse(subMap.containsKey("F"));
+    }
+
+    @Test
+    public void testHeadMap() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.headMap("D");
+        assertEquals(3, subMap.size());
+        assertTrue(subMap.containsKey("A"));
+        assertTrue(subMap.containsKey("B"));
+        assertTrue(subMap.containsKey("C"));
+        assertFalse(subMap.containsKey("D"));
+        assertFalse(subMap.containsKey("E"));
+        assertFalse(subMap.containsKey("F"));
+    }
+
+    @Test
+    public void testHeadMapEmpty() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.headMap("A");
+        assertTrue(subMap.isEmpty());
+        assertFalse(subMap.containsKey("A"));
+        assertFalse(subMap.containsKey("B"));
+        assertFalse(subMap.containsKey("C"));
+        assertFalse(subMap.containsKey("D"));
+        assertFalse(subMap.containsKey("E"));
+        assertFalse(subMap.containsKey("F"));
+    }
+
+    @Test
+    public void testTailMap() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.tailMap("C");
+        assertEquals(4, subMap.size());
+        assertFalse(subMap.containsKey("A"));
+        assertFalse(subMap.containsKey("B"));
+        assertTrue(subMap.containsKey("C"));
+        assertTrue(subMap.containsKey("D"));
+        assertTrue(subMap.containsKey("E"));
+        assertTrue(subMap.containsKey("F"));
+    }
+
+    @Test
+    public void testTailMapSingleElement() {
+        ConcurrentSkipListMap map = createPopulatedMap();
+        ConcurrentNavigableMap subMap = map.tailMap("F");
+        assertEquals(1, subMap.size());
+        assertFalse(subMap.containsKey("A"));
+        assertFalse(subMap.containsKey("B"));
+        assertFalse(subMap.containsKey("C"));
+        assertFalse(subMap.containsKey("D"));
+        assertFalse(subMap.containsKey("E"));
+        assertTrue(subMap.containsKey("F"));
+    }
+
 }
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java
new file mode 100644
index 0000000..bd858b0
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ConcurrentSkipListSetTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Iterator;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ConcurrentSkipListSetTest {
+
+    private ConcurrentSkipListSet createPopulatedSet() {
+        ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+        set.add("A");
+        set.add("B");
+        set.add("C");
+        set.add("D");
+        set.add("E");
+        set.add("F");
+        assertFalse(set.isEmpty());
+        return set;
+    }
+
+    @Test
+    public void testConstructorFromSortedSet() {
+        TreeSet treeSet = new TreeSet();
+        treeSet.add("A");
+        treeSet.add("B");
+        treeSet.add("C");
+        treeSet.add("D");
+        treeSet.add("E");
+        treeSet.add("F");
+        ConcurrentSkipListSet skipListSet = new ConcurrentSkipListSet(treeSet);
+        assertEquals(treeSet.size(), skipListSet.size());
+        while (!treeSet.isEmpty()) {
+            assertFalse(skipListSet.isEmpty());
+            assertEquals(treeSet.pollFirst(), skipListSet.pollFirst());
+        }
+    }
+
+    @Test
+    public void testClone() {
+        ConcurrentSkipListSet set = createPopulatedSet();
+        ConcurrentSkipListSet setClone = set.clone();
+        assertNotSame(set, setClone);
+        Iterator it = set.iterator();
+        Iterator itOfClone = setClone.iterator();
+        while (it.hasNext() && itOfClone.hasNext()) {
+            String entry = (String) it.next();
+            String entryOfClone = (String) itOfClone.next();
+            assertSame(entry, entryOfClone);
+        }
+        assertFalse(it.hasNext());
+        assertFalse(itOfClone.hasNext());
+    }
+
+    @Test
+    public void testDescendingIterator() {
+        ConcurrentSkipListSet set = createPopulatedSet();
+        int size = set.size();
+        int i;
+        Iterator it = set.descendingIterator();
+        String lastVal = null;
+        for (i = 0; it.hasNext(); i++) {
+            String val = (String) it.next();
+            assertTrue(set.contains(val));
+            if(lastVal != null) {
+                assertTrue(0 <= lastVal.compareTo(val));
+            }
+            lastVal = val;
+        }
+        assertEquals(i, size);
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java b/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
index fc783c0..80005df 100644
--- a/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
+++ b/luni/src/test/java/libcore/java/util/concurrent/CopyOnWriteArrayListTest.java
@@ -101,6 +101,15 @@
         assertEquals(Arrays.asList("a", "d"), list);
     }
 
+    public void testRetainAll() {
+        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
+        list.addAll(Arrays.asList("a", "b", "c", "d", "e"));
+        assertTrue(list.retainAll(Arrays.asList("b", "d")));
+        assertEquals(2, list.size());
+        assertFalse(list.retainAll(Arrays.asList("b", "d")));
+        assertEquals(2, list.size());
+    }
+
     public void testSubListClear() {
         CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
         list.addAll(Arrays.asList("a", "b", "c", "d", "e"));
diff --git a/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java b/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java
new file mode 100644
index 0000000..3f14d14
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/CountedCompleterTest.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class CountedCompleterTest {
+
+    /**
+     * Exercises the completion of all tasks once one of them has a result.
+     *
+     * Instead of needing all tasks to be performed to get a result, this will only expect one of
+     * them to provide it. That task, given by choiceIndex, will just complete the root completer.
+     * All other tasks will remain "unfinished".
+     *
+     * The result is passed through setRawResult().
+     */
+    private static int chooseOne(Integer[] array, int choiceIndex) {
+        class Task extends CountedCompleter<Integer> {
+            final int lo;
+            final int hi;
+            AtomicInteger ai = new AtomicInteger(0);
+
+            Task(Task parent, int lo, int hi) {
+                super(parent);
+                this.lo = lo;
+                this.hi = hi;
+            }
+
+            @Override
+            public void compute() {
+                if (hi - lo >= 2) {
+                    int mid = (lo + hi) >>> 1;
+                    // must set pending count before fork
+                    setPendingCount(2);
+                    new Task(this, mid, hi).fork(); // right child
+                    new Task(this, lo, mid).fork(); // left child
+                } else if (hi > lo) {
+                    if (choiceIndex == lo) {
+                        final CountedCompleter root = getRoot();
+                        final Integer val = Integer.valueOf(array[lo]);
+                        if (root != null) {
+                            root.complete(val);
+                        } else {
+                            complete(val); // the current task is the root
+                        }
+                    }
+                }
+            }
+
+            public Integer getRawResult() {
+                return new Integer(ai.intValue());
+            }
+
+            protected void setRawResult(Integer val) {
+                ai.addAndGet(val.intValue());
+            }
+        }
+        return new Task(null, 0, array.length).invoke().intValue();
+    }
+
+    /**
+     * complete marks a task as complete regardless of the pending count.
+     *
+     * The test will only require one task to complete.
+     */
+    @Test
+    public void testRecursiveChoice() {
+        int n = 7;
+        Integer[] a = new Integer[n];
+        for (int i = 0; i < n; i++) {
+            a[i] = i + 1;
+        }
+        for (int chosenOne = 0; chosenOne < n; ++chosenOne) {
+            final int result = chooseOne(a, chosenOne);
+            assertEquals(chosenOne + 1, result);
+        }
+    }
+
+    /**
+     * Forces a task to complete all its children by running them its own pool.
+     *
+     * After a parent task adds its children tasks to it's own pool queue, it uses helpComplete to
+     * ensure that those tasks are run before it returns. As all tasks are queued to the same pool
+     * and the parallelism is set to 1, this will make the pool execute the children tasks from
+     * within the execution of the parent.
+     */
+    private static void completeAllChildren(Integer[] array, Consumer<Integer> action) {
+
+        /**
+         * Leaf task that just runs the action and then completes.
+         */
+        class Task extends CountedCompleter<Integer> {
+            final int idx;
+
+            Task(CountedCompleter<Integer> parent, int idx) {
+                super(parent);
+                this.idx = idx;
+            }
+
+            @Override
+            public void compute() {
+                action.accept(array[idx]);
+                tryComplete();
+            }
+        }
+
+        /**
+         * The parent task that creates and queues its children, then executes them on its own pool
+         * before completing.
+         */
+        class MainTask extends CountedCompleter<Integer> {
+            final ForkJoinPool pool;
+            final int lo;
+            final int hi;
+
+            MainTask(ForkJoinPool pool, int lo, int hi) {
+                super(null);
+                this.pool = pool;
+                this.lo = lo;
+                this.hi = hi;
+            }
+
+            @Override
+            public void compute() {
+                final int count = hi - lo;
+                setPendingCount(count);
+
+                for (int idx = lo; idx < hi; ++idx) {
+                    // Do not fork the task, rather add it to the parent's pool so that it is
+                    // guaranteed not to be running before this compute() returns, unless
+                    // helpComplete() is called.
+                    pool.submit(new Task(this, idx));
+                }
+
+                // Make the pool run all the children tasks before moving one
+                helpComplete(count);
+
+                // If helpComplete() worked properly, by this point the pending count should be back
+                // to 0, so the tryComplete will terminate this task. Otherwise, the task will not
+                // get completed.
+                if (getPendingCount() == 0) {
+                    tryComplete();
+                }
+            }
+        }
+
+        // Use a pool with parallelism set to 1 so the children tasks cannot run before the main
+        // task, unless helpComplete is used.
+        ForkJoinPool pool = new ForkJoinPool(1);
+        MainTask task = new MainTask(pool, 0, array.length);
+        pool.submit(task);
+        task.join();
+    }
+
+    /**
+     * helpComplete attempts to process at most a given number of unprocessed children tasks.
+     */
+    @Test
+    public void testHelpComplete() {
+        int n = 7;
+        Integer[] a = new Integer[n];
+        for (int i = 0; i < n; i++) {
+            a[i] = i + 1;
+        }
+        AtomicInteger ai = new AtomicInteger(0);
+        // Use an atomic add as the action for each task. This will add all the elements of the
+        // array into the ai variable. Since the elements are between 1 and 7, the number does not
+        // overflow.
+        completeAllChildren(a, ai::addAndGet);
+        assertEquals(n * (n + 1) / 2, ai.get());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java
new file mode 100644
index 0000000..d848403
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutionExceptionTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class ExecutionExceptionTest {
+
+    // Adding derived class to be able to test the protected constructors
+    private class TestExecutionException extends ExecutionException {
+        public TestExecutionException() {
+            super();
+        }
+        public TestExecutionException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * constructor creates exception without any details
+     */
+    @Test
+    public void testConstructNoMessage() {
+        ExecutionException exception = new TestExecutionException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with detail message
+     */
+    @Test
+    public void testConstructWithMessage() {
+        ExecutionException exception = new TestExecutionException("test");
+        assertEquals("test", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with detail message and cause
+     */
+    @Test
+    public void testConstructWithMessageAndCause() {
+        Throwable cause = new Exception();
+        ExecutionException exception = new ExecutionException("test", cause);
+        assertEquals("test", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java
new file mode 100644
index 0000000..2df0b29
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutorServiceAutoCloseable.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+final class ExecutorServiceAutoCloseable implements AutoCloseable {
+    private final ExecutorService service;
+
+    public ExecutorServiceAutoCloseable(ExecutorService service) {
+        this.service = service;
+    }
+
+    @Override
+    public void close() {
+        try {
+            service.shutdown();
+
+            if(!service.awaitTermination(5000, TimeUnit.MILLISECONDS)) {
+                service.shutdownNow();
+                service.awaitTermination(1000, TimeUnit.MILLISECONDS);
+                fail();
+            }
+        } catch(InterruptedException e) {
+            fail("Unexpected InterruptedException: " + e.getMessage());
+        }
+    };
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java b/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java
new file mode 100644
index 0000000..dc44a81
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ExecutorsTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ExecutorsTest {
+
+    class TestRunnable implements Runnable {
+        public void run() { }
+    }
+
+    @Test
+    public void testNewWorkStealingPoolDefault() {
+        final ExecutorService e = Executors.newWorkStealingPool();
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(e)) {
+            e.execute(new TestRunnable());
+            e.execute(new TestRunnable());
+            e.execute(new TestRunnable());
+        }
+    }
+
+    @Test
+    public void testNewWorkStealingPoolWithParallelism() {
+        final ExecutorService e = Executors.newWorkStealingPool(2);
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(e)) {
+            e.execute(new TestRunnable());
+            e.execute(new TestRunnable());
+            e.execute(new TestRunnable());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java b/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java
new file mode 100644
index 0000000..b6e564b
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/FlowTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.concurrent.Flow;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class FlowTest {
+
+    @Test
+    /**
+     * defaultBufferSize returns default value for Publisher or Subscriber buffering.
+     */
+    public void testDefaultBufferSize() {
+        // Currently the implementation always returns 256, as documented in the API. If this
+        // changes, the test would need to be adjusted as well. This, at least, can serve as a
+        // reminder to update the documentation.
+        assertEquals(256, Flow.defaultBufferSize());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java
new file mode 100644
index 0000000..578970e
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinPoolTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ForkJoinPoolTest {
+
+    @Test
+    public void testSubmit() {
+        final ForkJoinPool pool = new ForkJoinPool();
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+            final AtomicInteger result = new AtomicInteger(0);
+            ForkJoinTask task = pool.submit(() -> result.addAndGet(42), result);
+            assertSame(result, task.get());
+            assertEquals(42, result.get());
+        } catch(Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetRunningThreadCount() {
+        final ForkJoinPool pool = new ForkJoinPool();
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+            assertEquals(0, pool.getRunningThreadCount());
+
+            final AtomicInteger value = new AtomicInteger(0);
+            final AtomicBoolean stop = new AtomicBoolean(false);
+            ForkJoinTask task = pool.submit(new Runnable() {
+                    public void run() {
+                        while(!stop.get()) {
+                            value.incrementAndGet();
+                        }
+                        stop.set(false);
+                    }
+                });
+            assertEquals(1, pool.getRunningThreadCount());
+            stop.set(true);
+            task.join();
+            pool.awaitTermination(2000, TimeUnit.MILLISECONDS);
+            assertEquals(0, pool.getRunningThreadCount());
+        } catch(Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java
new file mode 100644
index 0000000..264aa6a
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ForkJoinTaskTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ForkJoinTaskTest {
+
+    /**
+     * adapt uses a Runnable to perform a task, returning as the result the provided object
+     */
+    @Test
+    public void testAdaptToRunnableWithResult() {
+
+        final AtomicInteger result = new AtomicInteger(0);
+        final ForkJoinTask task = ForkJoinTask.adapt(() -> result.addAndGet(42), result);
+        final ForkJoinPool pool = new ForkJoinPool(1);
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+            pool.execute(task);
+            assertSame(result, task.join());
+            assertEquals(42, result.get());
+        } catch(Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    /**
+     * adapt uses a Callable to perform a task, returning as the result the value returned from the
+     * call() function
+     */
+    @Test
+    public void testAdaptToCallable() {
+
+        Callable callable = () -> { return Integer.valueOf(42); };
+        final ForkJoinTask task = ForkJoinTask.adapt(callable);
+        final ForkJoinPool pool = new ForkJoinPool(1);
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+            pool.execute(task);
+            Integer result = (Integer)task.join();
+            assertEquals(42, result.intValue());
+        } catch(Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    /**
+     * adapt uses a Callable to perform a task, converting any checked exception into
+     * RuntimeException
+     */
+    @Test
+    public void testAdaptToCallableThrowsException() {
+
+        Callable callable = () -> { throw new Exception("Test passed"); };
+        final ForkJoinTask task = ForkJoinTask.adapt(callable);
+        final ForkJoinPool pool = new ForkJoinPool(1);
+        try (ExecutorServiceAutoCloseable cleaner = new ExecutorServiceAutoCloseable(pool)) {
+            pool.execute(task);
+            Integer result = (Integer)task.join();
+            fail("Expected RuntimeException");
+        } catch(RuntimeException e) {
+            assertTrue(e.getMessage().contains("Test passed"));
+        } catch(Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java b/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java
new file mode 100644
index 0000000..c489a2f
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/PhaserTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertSame;
+
+import java.util.concurrent.Phaser;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class PhaserTest {
+
+    /**
+     * The root ancestor of a phaser should be returned from getRoot
+     */
+    @Test
+    public void testGetRoot() {
+        Phaser root = new Phaser();
+        Phaser parent = new Phaser(root);
+        Phaser child = new Phaser(parent);
+        assertSame(root, root.getRoot());
+        assertSame(root, parent.getRoot());
+        assertSame(root, child.getRoot());
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java b/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java
new file mode 100644
index 0000000..861c498
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/RecursiveTaskTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.concurrent.RecursiveTask;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RecursiveTaskTest {
+
+    static final long MILLIS_TO_NANO = (1000 * 1000);
+
+    final class SumTask extends RecursiveTask<Integer> {
+        final int value;
+
+        SumTask(int value) {
+            this.value = value;
+        }
+
+        @Override
+        protected Integer compute() {
+            if (value <= 1)
+                return value;
+            SumTask subTask = new SumTask(value - 1);
+            subTask.fork();
+            return subTask.join() + value;
+        }
+
+        public void waitForCompletion(Integer forceResult) {
+            if(!TestUtils.waitWhileTrueOrTimeout(Duration.ofSeconds(10),
+                        () -> { return !isDone(); })) {
+                fail("timed out waiting for task completion");
+            }
+            if (forceResult != null) {
+                super.setRawResult(forceResult);
+            }
+        }
+    }
+
+    @Test
+    public void testSetRawResult() {
+        SumTask task = new SumTask(10);
+        final Integer expected = Integer.valueOf(-1);
+        task.fork();
+        task.waitForCompletion(expected);
+        Integer result = task.join();
+        assertSame(expected, result);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java b/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java
new file mode 100644
index 0000000..4497157
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/ReentrantReadWriteLockTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.Collection;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class ReentrantReadWriteLockTest {
+
+    class ReadLockRunnable implements Runnable {
+        final ReentrantReadWriteLock lock;
+
+        ReadLockRunnable(ReentrantReadWriteLock lock) {
+            this.lock = lock;
+        }
+
+        @Override
+        public void run() {
+            lock.readLock().lock();
+            lock.readLock().unlock();
+        }
+    }
+
+    class WriteLockRunnable implements Runnable {
+        final ReentrantReadWriteLock lock;
+
+        WriteLockRunnable(ReentrantReadWriteLock lock) {
+            this.lock = lock;
+        }
+
+        @Override
+        public void run() {
+            lock.writeLock().lock();
+            lock.writeLock().unlock();
+        }
+    }
+
+    static class DefaultReentrantReadWriteLock extends ReentrantReadWriteLock {
+
+        DefaultReentrantReadWriteLock() {
+            super();
+        }
+
+        @Override
+        public Collection<Thread> getQueuedReaderThreads() {
+            return super.getQueuedReaderThreads();
+        }
+
+        @Override
+        public Collection<Thread> getQueuedWriterThreads() {
+            return super.getQueuedWriterThreads();
+        }
+    }
+
+    private void waitForQueuedThread(DefaultReentrantReadWriteLock lock, Thread thread) {
+        if(!TestUtils.waitWhileTrueOrTimeout(Duration.ofSeconds(2),
+                    () -> { return !lock.hasQueuedThread(thread); })) {
+            fail("timed out waiting for queued thread");
+        }
+    }
+
+    @Test
+    public void testReadLockCondition() {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
+        try {
+            final Condition condition = lock.readLock().newCondition();
+            fail("Expected UnsupportedOperationException");
+        } catch (UnsupportedOperationException success) {
+        } catch (Throwable t) {
+            fail("Unexpected exception: " + t.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetQueuedReaderThreads() {
+        final DefaultReentrantReadWriteLock lock = new DefaultReentrantReadWriteLock();
+        Thread thread1 = new Thread(new ReadLockRunnable(lock));
+        Thread thread2 = new Thread(new ReadLockRunnable(lock));
+        lock.writeLock().lock();
+        assertTrue(lock.getQueuedReaderThreads().isEmpty());
+        thread1.start();
+        waitForQueuedThread(lock, thread1);
+        assertTrue(lock.getQueuedReaderThreads().contains(thread1));
+        thread2.start();
+        waitForQueuedThread(lock, thread2);
+        assertTrue(lock.getQueuedReaderThreads().contains(thread2));
+        lock.writeLock().unlock();
+        TestUtils.joinThreadOrFail(2000, thread1);
+        TestUtils.joinThreadOrFail(2000, thread2);
+        assertTrue(lock.getQueuedReaderThreads().isEmpty());
+    }
+
+    @Test
+    public void testGetQueuedWriterThreads() {
+        final DefaultReentrantReadWriteLock lock = new DefaultReentrantReadWriteLock();
+        Thread thread1 = new Thread(new WriteLockRunnable(lock));
+        Thread thread2 = new Thread(new WriteLockRunnable(lock));
+        lock.writeLock().lock();
+        assertTrue(lock.getQueuedWriterThreads().isEmpty());
+        thread1.start();
+        waitForQueuedThread(lock, thread1);
+        assertTrue(lock.getQueuedWriterThreads().contains(thread1));
+        thread2.start();
+        waitForQueuedThread(lock, thread2);
+        assertTrue(lock.getQueuedWriterThreads().contains(thread2));
+        lock.writeLock().unlock();
+        TestUtils.joinThreadOrFail(2000, thread1);
+        TestUtils.joinThreadOrFail(2000, thread2);
+        assertTrue(lock.getQueuedWriterThreads().isEmpty());
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java b/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java
new file mode 100644
index 0000000..14c1408
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/RejectedExecutionExceptionTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.concurrent.RejectedExecutionException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+public class RejectedExecutionExceptionTest {
+
+    // Adding derived class to be able to test the protected constructors
+    private class TestExecutionException extends RejectedExecutionException {
+        public TestExecutionException() {
+            super();
+        }
+        public TestExecutionException(String message) {
+            super(message);
+        }
+    }
+
+    /**
+     * constructor creates exception without any details
+     */
+    @Test
+    public void testConstructDefault() {
+        RejectedExecutionException exception = new TestExecutionException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with detail message and cause
+     */
+    @Test
+    public void testConstructWithMessageAndCause() {
+        Throwable cause = new Exception();
+        RejectedExecutionException exception = new RejectedExecutionException("test", cause);
+        assertEquals("test", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * constructor creates exception with cause
+     */
+    @Test
+    public void testConstructWithCause() {
+        Throwable cause = new Exception("root");
+        RejectedExecutionException exception = new RejectedExecutionException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java b/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java
new file mode 100644
index 0000000..eaa4330
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/concurrent/TestUtils.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.util.concurrent;
+
+import static org.junit.Assert.fail;
+
+import java.time.Duration;
+import java.util.function.BooleanSupplier;
+
+class TestUtils {
+
+    public static final long MILLIS_TO_NANO = (1000 * 1000);
+
+    public static void joinThreadOrFail(long timeoutMillis, Thread thread) {
+        try {
+            thread.join(timeoutMillis);
+        } catch (InterruptedException fail) {
+            fail("InterruptedException when joining thread");
+        } finally {
+            if (thread.getState() != Thread.State.TERMINATED) {
+                thread.interrupt();
+                fail("timed out waiting to join thread");
+            }
+        }
+    }
+
+    public static boolean waitWhileTrueOrTimeout(Duration timeout, BooleanSupplier conditionFn) {
+        Duration startTime = Duration.ofNanos(System.nanoTime());
+        while (conditionFn.getAsBoolean()) {
+            Duration now = Duration.ofNanos(System.nanoTime());
+            if (now.minus(startTime).compareTo(timeout) >= 0) {
+                return false;
+            }
+            Thread.yield();
+        }
+        return true;
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/concurrent/ThreadPoolExecutorTest.java b/luni/src/test/java/libcore/java/util/concurrent/ThreadPoolExecutorTest.java
index 4273598..48b2781 100644
--- a/luni/src/test/java/libcore/java/util/concurrent/ThreadPoolExecutorTest.java
+++ b/luni/src/test/java/libcore/java/util/concurrent/ThreadPoolExecutorTest.java
@@ -32,8 +32,8 @@
 
         // It should be illegal to set a core pool size that's larger than the max
         // pool size but apps have been allowed to get away with it so far. The pattern
-        // below occurs in a commonly used library. Note that the executor is in a sane
-        // state at the end of both method calls.
+        // below occurs in a commonly used library. Note that the executor is in a
+        // consistent state at the end of both method calls.
         tp.setCorePoolSize(5);
         tp.setMaximumPoolSize(5);
     }
diff --git a/luni/src/test/java/libcore/java/util/jar/Pack200Test.java b/luni/src/test/java/libcore/java/util/jar/Pack200Test.java
new file mode 100644
index 0000000..11078f6
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/jar/Pack200Test.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.util.jar;
+
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.jar.Pack200;
+
+@RunWith(JUnit4.class)
+public class Pack200Test {
+
+    @Test
+    public void newPacker_throwsNpe() {
+        try {
+            // Default implementation is removed and alternative is not available
+            Pack200.newPacker();
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    @Test
+    public void newUnpacker_throwsNpe() {
+        try {
+            // Default implementation is removed and alternative is not available
+            Pack200.newUnpacker();
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+
+}
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 c2d56ae..630cea4 100644
--- a/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
+++ b/luni/src/test/java/libcore/java/util/regex/OldMatcherTest.java
@@ -617,7 +617,7 @@
                             }
                             m.appendTail(sb);
                         } catch (Exception expected) {
-                            // This code is inherently unsafe and crazy;
+                            // This code is inherently unsafe;
                             // we're just trying to provoke native crashes!
                         }
                     }
diff --git a/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java b/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java
new file mode 100644
index 0000000..ecec61b
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/stream/CollectorsTest.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 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.util.stream;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import static java.util.stream.Collectors.counting;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.toList;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RunWith(JUnit4.class)
+public class CollectorsTest {
+
+    @Test
+    public void counting_countsNulls() {
+        long count = Stream.of(null, null, null).collect(counting());
+
+        assertEquals(3, count);
+    }
+
+    @Test
+    public void counting_emptyStream() {
+        assertEquals(0L, (long) Stream.empty().collect(counting()));
+    }
+
+    @Test
+    public void counting_nonEmptyStream() {
+        long count = Stream.of(null, 1, 2, "").collect(counting());
+
+        assertEquals(4, count);
+    }
+
+    @Test
+    public void counting_largeStream() {
+        int size = 10_000_000;
+
+        long actual = Stream.generate(() -> 1)
+                .limit(size)
+                .collect(counting());
+
+        assertEquals(size, actual);
+    }
+
+    @Test
+    public void collectorOf() {
+        Collector<Integer, int[], int[]> sqSumCollector =
+                Collector.of(
+                        () -> new int[] {0},
+                        (sum, next) -> sum[0] = sum[0] + next * next,
+                        (a, b) -> new int[] {a[0] + b[0]},
+                        Collector.Characteristics.UNORDERED);
+
+        int[] anArray = new int[] {10};
+        assertSame("Finisher is identity fn", anArray, sqSumCollector.finisher().apply(anArray));
+
+        assertArrayEquals(new int[]{0}, sqSumCollector.supplier().get());
+        assertArrayEquals(new int[] {20}, sqSumCollector.combiner().apply(anArray, anArray));
+
+        sqSumCollector.accumulator().accept(anArray, 10);
+        assertArrayEquals(new int[] {110}, anArray);
+        assertTrue(sqSumCollector.characteristics().contains(Collector.Characteristics.UNORDERED));
+
+        assertArrayEquals(new int[] {30}, Stream.of(1, 2, 3, 4).collect(sqSumCollector));
+    }
+
+    @Test
+    public void mapping_asArgumentToCollect() {
+        Collector<Integer, ?, List<Integer>> plusOneCollector =
+                Collectors.mapping((Integer x) -> x + 1, toList());
+
+        List<Integer> actual = Stream.of(1, 2, 10).collect(plusOneCollector);
+
+        assertEquals(List.of(2, 3, 11), actual);
+    }
+
+    @Test
+    public void mapping_asArgumentInGroupingBy() {
+        Collector<Integer, ?, List<Integer>> plusOneCollector =
+                Collectors.mapping((Integer x) -> x + 1, toList());
+
+        Map<Boolean, List<Integer>> actual = Stream.of(1, 2, 3, 4)
+                .collect(groupingBy(x -> x % 2 == 0, plusOneCollector));
+        Map<Boolean, List<Integer>> expected = Map.of(true, List.of(3, 5), false, List.of(2, 4));
+
+        assertEquals(expected, actual);
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java b/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java
new file mode 100644
index 0000000..3c36aa7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/util/stream/LongStreamTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2021 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.util.stream;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.stream.LongStream;
+
+@RunWith(JUnit4.class)
+public class LongStreamTest {
+
+    private static final int[] TEST_SIZES = {0, 1, 2, 10, 20, 100, 1000};
+
+    @Test
+    public void ofArraysWithDifferentSizes() {
+        for (int size : TEST_SIZES) {
+            long[] sourceArray = generate(size);
+            LongStream stream = LongStream.of(sourceArray);
+
+            long[] destArray = stream.toArray();
+
+            assertFalse("By default stream should be sequential", stream.isParallel());
+            assertNotSame("New array should be generated", sourceArray, destArray);
+            assertArrayEquals(sourceArray, destArray);
+        }
+    }
+
+    @Test
+    public void ofNullArray_shouldThrowNPE() {
+        try {
+            LongStream.of((long[]) null);
+            fail();
+        } catch (NullPointerException ignored) {
+            // expected
+        }
+    }
+
+    private long[] generate(int size) {
+        long[] array = new long[size];
+
+        for (int index = 0; index < size; ++index) {
+            array[index] = index + 1;
+        }
+
+        return array;
+    }
+}
diff --git a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
index 2175289..ae07e02 100644
--- a/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/ZipFileTest.java
@@ -26,6 +26,7 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.Charset;
 import java.util.Enumeration;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -85,4 +86,40 @@
             fail();
         } catch(FileNotFoundException expected) {}
     }
+
+    /**
+     * cp1251.zip archive has single empty file with cp1251 encoding name.
+     * Its name is 'имя файла'('file name' in Russian), but in cp1251.
+     * It was created using "convmv -f utf-8 -t cp1251 &lt;file&gt; --notest".
+     */
+    public void test_zipFileWith_cp1251_fileNames() throws Exception {
+        String resourceName = "/libcore/java/util/zip/cp1251.zip";
+
+        File tempFile = createTemporaryZipFile();
+        try (
+            InputStream is = ZipFileTest.class.getResourceAsStream(resourceName);
+            FileOutputStream fos = new FileOutputStream(tempFile)) {
+
+            int read;
+            byte[] arr = new byte[1024];
+
+            while ((read = is.read(arr)) > 0) {
+                fos.write(arr, 0, read);
+            }
+            fos.flush();
+
+            Charset cp1251 = Charset.forName("cp1251");
+            try (ZipFile zipFile = new ZipFile(tempFile, cp1251)) {
+                ZipEntry zipEntry = zipFile.entries().nextElement();
+
+                assertEquals("имя файла", zipEntry.getName());
+            }
+
+            try (ZipFile zipFile = new ZipFile(tempFile.getAbsolutePath(), cp1251)) {
+                ZipEntry zipEntry = zipFile.entries().nextElement();
+
+                assertEquals("имя файла", zipEntry.getName());
+            }
+        }
+    }
 }
diff --git a/luni/src/test/java/libcore/javax/crypto/MacTest.java b/luni/src/test/java/libcore/javax/crypto/MacTest.java
index bd2ad39..fb62018 100644
--- a/luni/src/test/java/libcore/javax/crypto/MacTest.java
+++ b/luni/src/test/java/libcore/javax/crypto/MacTest.java
@@ -113,7 +113,7 @@
     };
 
     /**
-     * Test that BC has the same results as the SunJCA provider for
+     * Test that default PBEWITHHMACSHA implementation has the same results as the SunJCA provider.
      */
     public void test_PBEWITHHMACSHA_Variants() throws Exception {
         byte[] plaintext = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
@@ -126,14 +126,14 @@
         for (int shaVariantIndex = 0; shaVariantIndex < shaVariants.length; shaVariantIndex++) {
             int shaVariant = shaVariants[shaVariantIndex];
             SecretKeyFactory secretKeyFactory =
-                    SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA" + shaVariant, "BC");
+                    SecretKeyFactory.getInstance("PBKDF2WITHHMACSHA" + shaVariant);
             PBEKeySpec pbeKeySpec = new PBEKeySpec(password,
                     salt,
                     iterationCount,
                     // Key depending on block size!
                     (shaVariant < 384) ? 64 : 128);
             SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
-            Mac mac = Mac.getInstance("PBEWITHHMACSHA" + shaVariant, "BC");
+            Mac mac = Mac.getInstance("PBEWITHHMACSHA" + shaVariant);
             mac.init(secretKey);
             byte[] bcResult = mac.doFinal(plaintext);
             assertEquals(
diff --git a/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java b/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java
new file mode 100644
index 0000000..d0217b4
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/net/ssl/SSLPermissionTest.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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 junit.framework.TestCase;
+
+import javax.net.ssl.SSLPermission;
+
+public final class SSLPermissionTest extends TestCase {
+
+    public void testSslPermissions_constructor_LString() {
+        SSLPermission permission = new SSLPermission("name");
+
+        assertEquals("", permission.getName());
+        assertEquals("", permission.getActions());
+    }
+
+    public void testSslPermission_constructor_LString_LString() {
+        SSLPermission permission = new SSLPermission("name", "actions");
+
+        assertEquals("", permission.getName());
+        assertEquals("", permission.getActions());
+    }
+}
diff --git a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
index 226952f..757e14b 100644
--- a/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
+++ b/luni/src/test/java/libcore/javax/security/auth/x500/X500PrincipalTest.java
@@ -65,41 +65,17 @@
      * Confirm DRLCertFactory uses a non-hex format for T61String encoding: http://b/2102191
      */
     public void testGetName() throws Exception {
-        CertificateFactory certFactBC = CertificateFactory.getInstance("X.509", "BC");
-        CertificateFactory certFactOpenSSL = CertificateFactory.getInstance("X.509",
-                "AndroidOpenSSL");
-
-        X509Certificate certBC = (X509Certificate)
-                certFactBC.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
-        X509Certificate certOpenSSL = (X509Certificate)
-                certFactOpenSSL.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
-
-        assertEquals(certBC, certOpenSSL);
-
-        assertEquals(certBC.getSubjectX500Principal(), certBC.getSubjectX500Principal());
-        assertEquals(certOpenSSL.getIssuerX500Principal(), certOpenSSL.getIssuerX500Principal());
-
-        assertEquals(certBC.getSubjectX500Principal(), certOpenSSL.getSubjectX500Principal());
-        assertEquals(certBC.getIssuerX500Principal(), certOpenSSL.getIssuerX500Principal());
-
-        String[] formats = {
-            X500Principal.CANONICAL,
-            X500Principal.RFC1779,
-            X500Principal.RFC2253
-        };
-        for (String format : formats) {
-            assertEquals(certBC.getSubjectX500Principal().getName(format),
-                         certOpenSSL.getSubjectX500Principal().getName(format));
-            assertEquals(certBC.getIssuerX500Principal().getName(format),
-                         certOpenSSL.getIssuerX500Principal().getName(format));
-        }
+        CertificateFactory certFact = CertificateFactory.getInstance("X.509");
+        X509Certificate cert = (X509Certificate)
+                certFact.generateCertificate(new ByteArrayInputStream(T61STRING_CERT));
+        
         String expected = ""
                 + "cn=entrust.net certification authority (2048),"
                 + "ou=(c) 1999 entrust.net limited,"
                 + "ou=www.entrust.net/cps_2048 incorp. by ref. (limits liab.),"
                 + "o=entrust.net";
         assertEquals(expected,
-                     certBC.getSubjectX500Principal().getName(X500Principal.CANONICAL));
+            cert.getSubjectX500Principal().getName(X500Principal.CANONICAL));
 
     }
 
diff --git a/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java b/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
index 764bad2..405aa84 100644
--- a/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
+++ b/luni/src/test/java/libcore/libcore/content/type/MimeMapTest.java
@@ -70,7 +70,7 @@
 
     @Test public void caseNormalization_key() {
         mimeMap = MimeMap.builder()
-                .put("application/msWord", Arrays.asList("Doc"))
+                .addMimeMapping("application/msWord", Arrays.asList("Doc"))
                 .build();
         assertEquals("application/msword", mimeMap.guessMimeTypeFromExtension("dOc"));
         assertEquals("doc", mimeMap.guessExtensionFromMimeType("appliCATion/mSWOrd"));
@@ -93,7 +93,7 @@
 
         // Known keys for a custom map
         mimeMap = MimeMap.builder()
-                .put("application/msWord", Arrays.asList("Doc"))
+                .addMimeMapping("application/msWord", Arrays.asList("Doc"))
                 .build();
         assertEquals("doc", mimeMap.guessExtensionFromMimeType("Application/mSWord"));
         assertEquals("application/msword", mimeMap.guessMimeTypeFromExtension("DoC"));
@@ -105,7 +105,7 @@
 
     @Test public void unmapped() {
         mimeMap = MimeMap.builder()
-                .put("mime/test", Arrays.asList("test", "tst"))
+                .addMimeMapping("mime/test", Arrays.asList("test", "tst"))
                 .build();
         assertNull(mimeMap.guessExtensionFromMimeType("mime/unknown"));
         assertFalse(mimeMap.hasMimeType("mime/unknown"));
@@ -122,7 +122,7 @@
         MimeMap originalDefault = MimeMap.getDefault();
         try {
             // Constructs a new instance every time it is called
-            MimeMap.setDefaultSupplier(() -> MimeMap.builder().put("mime/sup", "sup").build());
+            MimeMap.setDefaultSupplier(() -> MimeMap.builder().addMimeMapping("mime/sup", "sup").build());
             // Same instance is returned both times
             assertSame(MimeMap.getDefault(), MimeMap.getDefault());
             // Check that the supplier is in effect
@@ -165,7 +165,7 @@
                 mimeMap);
 
         mimeMap = mimeMap.buildUpon()
-                .put("text/plain", "txt")
+                .addMimeMapping("text/plain", "txt")
                 .build();
         assertMap(
                 makeMap("text/plain", "txt"),
@@ -173,7 +173,7 @@
                 mimeMap);
 
         mimeMap = mimeMap.buildUpon()
-                .put("audio/mpeg", Arrays.asList("mp2", "mp3"))
+                .addMimeMapping("audio/mpeg", Arrays.asList("mp2", "mp3"))
                 .build();
         assertMap(
                 makeMap("audio/mpeg", "mp2",
@@ -184,7 +184,7 @@
                 mimeMap);
 
         mimeMap = mimeMap.buildUpon()
-                .put("text/plain", "text")
+                .addMimeMapping("text/plain", "text")
                 .build();
         assertMap(
                 makeMap("audio/mpeg", "mp2",
@@ -198,12 +198,12 @@
 
     @Test public void put() {
         MimeMap a = MimeMap.builder()
-                .put("text/plain", Arrays.asList("txt", "text"))
-                .put("application/msword", "doc")
+                .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+                .addMimeMapping("application/msword", "doc")
                 .build();
         MimeMap b = MimeMap.builder()
-                .put("text/plain", Arrays.asList("txt", "text"))
-                .put("application/msword", "doc")
+                .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+                .addMimeMapping("application/msword", "doc")
                 .build();
         assertEqualsButNotSame(a, b);
         assertEqualsButNotSame(a, a.buildUpon().build());
@@ -219,7 +219,7 @@
 
     @Test public void put_noExtensions() {
         checkPut_noExtensions(emptyMap);
-        checkPut_noExtensions(MimeMap.builder().put("text/plain", "txt").build());
+        checkPut_noExtensions(MimeMap.builder().addMimeMapping("text/plain", "txt").build());
         checkPut_noExtensions(mimeMap);
     }
 
@@ -228,7 +228,7 @@
      */
     private static void checkPut_noExtensions(MimeMap baseMap) {
         MimeMap mimeMap = baseMap.buildUpon()
-                .put("mime/type", Collections.emptyList())
+                .addMimeMapping("mime/type", Collections.emptyList())
                 .build();
         assertEquals(baseMap, mimeMap);
     }
@@ -249,11 +249,11 @@
     }
 
     @Test public void put_String_String_nullOrEmpty() {
-        assertThrowsNpe(() -> MimeMap.builder().put(null, "ext"));
-        assertThrowsIae(() -> MimeMap.builder().put("", "ext"));
+        assertThrowsNpe(() -> MimeMap.builder().addMimeMapping(null, "ext"));
+        assertThrowsIae(() -> MimeMap.builder().addMimeMapping("", "ext"));
 
-        assertThrowsNpe(() -> MimeMap.builder().put("mime/type", (String) null));
-        assertThrowsIae(() -> MimeMap.builder().put("mime/type", ""));
+        assertThrowsNpe(() -> MimeMap.builder().addMimeMapping("mime/type", (String) null));
+        assertThrowsIae(() -> MimeMap.builder().addMimeMapping("mime/type", ""));
     }
 
     /**
@@ -262,8 +262,8 @@
     @Test public void putIfAbsent() {
         // Starting from an empty mapping, add a bunch more, some with and some without '?'.
         mimeMap = MimeMap.builder()
-                .put("?text/plain", "?txt")
-                .put("audio/mpeg", Arrays.asList("mpga", "mpega", "?mp2", "mp3"))
+                .addMimeMapping("?text/plain", "?txt")
+                .addMimeMapping("audio/mpeg", Arrays.asList("mpga", "mpega", "?mp2", "mp3"))
                 .build();
         assertEquals("txt", mimeMap.guessExtensionFromMimeType("text/plain"));
         assertEquals("text/plain", mimeMap.guessMimeTypeFromExtension("txt"));
@@ -273,14 +273,14 @@
 
         // Override a ext -> MIME mapping without overriding the MIME -> ext mapping.
         mimeMap = mimeMap.buildUpon()
-                .put("?audio/mpeg", "m4a")
+                .addMimeMapping("?audio/mpeg", "m4a")
                 .build();
         assertEquals("mpga", mimeMap.guessExtensionFromMimeType("audio/mpeg"));
         assertEquals("audio/mpeg", mimeMap.guessMimeTypeFromExtension("m4a"));
 
         // Override a MIME -> ext mapping without overriding the ext -> MIME mapping.
         mimeMap = mimeMap.buildUpon()
-                .put("audio/mpeg", "?txt")
+                .addMimeMapping("audio/mpeg", "?txt")
                 .build();
         assertEquals("txt", mimeMap.guessExtensionFromMimeType("audio/mpeg"));
         assertEquals("text/plain", mimeMap.guessMimeTypeFromExtension("txt"));
@@ -307,10 +307,10 @@
     @Test public void extensions() {
         assertEquals(Collections.emptySet(), emptyMap.extensions());
         mimeMap = MimeMap.builder()
-                .put("text/plain", Arrays.asList("txt", "text"))
-                .put("audi/mpeg", "m4a")
-                .put("application/msword", "doc")
-                .put("text/plain", "tx")
+                .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+                .addMimeMapping("audi/mpeg", "m4a")
+                .addMimeMapping("application/msword", "doc")
+                .addMimeMapping("text/plain", "tx")
                 .build();
         Set<String> extensions = new HashSet<>(Arrays.asList(
                 "txt", "text", "m4a", "doc", "tx"));
@@ -326,10 +326,10 @@
     @Test public void mimeTypes() {
         assertEquals(Collections.emptySet(), emptyMap.mimeTypes());
         mimeMap = MimeMap.builder()
-                .put("text/plain", Arrays.asList("txt", "text"))
-                .put("audio/mpeg", "m4a")
-                .put("application/msword", "doc")
-                .put("text/plain", "tx")
+                .addMimeMapping("text/plain", Arrays.asList("txt", "text"))
+                .addMimeMapping("audio/mpeg", "m4a")
+                .addMimeMapping("application/msword", "doc")
+                .addMimeMapping("text/plain", "tx")
                 .build();
         Set<String> mimeTypes = new HashSet<>(Arrays.asList(
                 "text/plain",
@@ -362,17 +362,17 @@
         assertPutThrowsIae("invalidmime", "ext");
 
         // During lookups, wrong arguments return null rather than throwing.
-        mimeMap = MimeMap.builder().put("mime/type", "ext").build();
+        mimeMap = MimeMap.builder().addMimeMapping("mime/type", "ext").build();
         assertNull(mimeMap.guessExtensionFromMimeType("ext")); // ext is no mime type
         assertNull(mimeMap.guessMimeTypeFromExtension("mime/type")); // mime/type is no extension
     }
 
     private static void assertPutThrowsNpe(String mime, String... exts) {
-        assertThrowsNpe(() -> MimeMap.builder().put(mime, Arrays.asList(exts)));
+        assertThrowsNpe(() -> MimeMap.builder().addMimeMapping(mime, Arrays.asList(exts)));
     }
 
     private static void assertPutThrowsIae(final String mime, final String... exts) {
-        assertThrowsIae(() -> MimeMap.builder().put(mime, Arrays.asList(exts)));
+        assertThrowsIae(() -> MimeMap.builder().addMimeMapping(mime, Arrays.asList(exts)));
     }
 
     private static void assertThrowsNpe(Runnable runnable) {
@@ -393,8 +393,8 @@
 
     @Test public void hashCodeValue() {
         assertEquals(0, emptyMap.hashCode());
-        MimeMap a = MimeMap.builder().put("mime/test", "test").build();
-        MimeMap b = a.buildUpon().put("foo/bar", "baz").build();
+        MimeMap a = MimeMap.builder().addMimeMapping("mime/test", "test").build();
+        MimeMap b = a.buildUpon().addMimeMapping("foo/bar", "baz").build();
         assertTrue(0 != a.hashCode());
         assertTrue((a.hashCode() != b.hashCode()));
     }
@@ -434,13 +434,13 @@
             String ext = entry.getKey();
             String mime = entry.getValue();
             assertEquals(ext + ": " + mimeMap, mime, mimeMap.guessMimeTypeFromExtension(ext));
-            expectedBuilder.put("?" + mime, ext);
+            expectedBuilder.addMimeMapping("?" + mime, ext);
         }
         for (Map.Entry<String, String> entry : expectedMimeToExt.entrySet()) {
             String mime = entry.getKey();
             String ext = entry.getValue();
             assertEquals(mime + ": "  + mimeMap, ext, mimeMap.guessExtensionFromMimeType(mime));
-            expectedBuilder.put(mime, "?" + ext);
+            expectedBuilder.addMimeMapping(mime, "?" + ext);
         }
         // Check that there are no unexpected additional mappings.
         assertEqualsButNotSame(expectedBuilder.build(), mimeMap);
diff --git a/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java b/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java
deleted file mode 100644
index c659f9d..0000000
--- a/luni/src/test/java/libcore/libcore/icu/AlphabeticIndexTest.java
+++ /dev/null
@@ -1,77 +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.icu;
-
-import org.junit.Test;
-import android.icu.text.AlphabeticIndex;
-import android.icu.text.UnicodeSet;
-import android.icu.util.LocaleData;
-import android.icu.util.ULocale;
-import java.util.Locale;
-
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Test for {@link android.icu.text.AlphabeticIndex}
- */
-public class AlphabeticIndexTest {
-
-    @Test
-    public void test_english() {
-        verifyIndex(Locale.ENGLISH);
-    }
-
-    // http://b/64953401
-    @Test
-    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) {
-        ULocale uLocale = ULocale.forLocale(locale);
-        AlphabeticIndex index = new AlphabeticIndex(uLocale);
-        LocaleData localeData = LocaleData.getInstance(uLocale);
-
-        // 0 = "default options", there is no constant for this.
-        UnicodeSet exemplarSet = localeData.getExemplarSet(0, LocaleData.ES_STANDARD);
-        for (String s : exemplarSet) {
-            index.addRecord(s, s);
-        }
-        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 55af0e2..da41559 100644
--- a/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/DateIntervalFormatTest.java
@@ -139,12 +139,12 @@
 
     assertEquals("19–22 de enero de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, 0));
     assertEquals("19–22 de ene. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-    assertEquals("lun., 19 de ene. – jue., 22 de ene. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+    assertEquals("lun, 19 de ene. – jue, 22 de ene. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
     assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
 
     assertEquals("19 de enero–22 de abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, 0));
     assertEquals("19 de ene. – 22 de abr. 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-    assertEquals("lun., 19 de ene. – mié., 22 de abr. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+    assertEquals("lun, 19 de ene. – mié, 22 de abr. de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
     assertEquals("enero–abril de 2009", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
 
     assertEquals("19 de ene. de 2009 – 9 de feb. de 2012", formatDateRange(es_US, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
@@ -155,17 +155,17 @@
     // The same tests but for es_ES.
 
     assertEquals("19–22 de enero de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, 0));
-    assertEquals("19–22 ene. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-    assertEquals("lun., 19 ene. – jue., 22 ene. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+    assertEquals("19–22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+    assertEquals("lun, 19 ene – jue, 22 ene 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
     assertEquals("lunes, 19 de enero–jueves, 22 de enero de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * DAY, FORMAT_SHOW_WEEKDAY));
 
     assertEquals("19 de enero–22 de abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, 0));
-    assertEquals("19 ene. – 22 abr. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-    assertEquals("lun., 19 ene. – mié., 22 abr. 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
+    assertEquals("19 ene – 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+    assertEquals("lun, 19 ene – mié, 22 abr 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_SHOW_WEEKDAY | FORMAT_ABBREV_ALL));
     assertEquals("enero–abril de 2009", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * MONTH, FORMAT_NO_MONTH_DAY));
 
-    assertEquals("19 ene. 2009 – 9 feb. 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
-    assertEquals("ene. 2009 – feb. 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
+    assertEquals("19 ene 2009 – 9 feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_DATE | FORMAT_ABBREV_ALL));
+    assertEquals("ene 2009 – feb 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_NO_MONTH_DAY | FORMAT_ABBREV_ALL));
     assertEquals("19 de enero de 2009–9 de febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, 0));
     assertEquals("lunes, 19 de enero de 2009–jueves, 9 de febrero de 2012", formatDateRange(es_ES, tz, fixedTime, fixedTime + 3 * YEAR, FORMAT_SHOW_WEEKDAY));
   }
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java b/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
deleted file mode 100644
index e01de4d..0000000
--- a/luni/src/test/java/libcore/libcore/icu/ICUCalendarTest.java
+++ /dev/null
@@ -1,56 +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.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/ICULocaleDataTest.java b/luni/src/test/java/libcore/libcore/icu/ICULocaleDataTest.java
deleted file mode 100644
index 7f0fc6b..0000000
--- a/luni/src/test/java/libcore/libcore/icu/ICULocaleDataTest.java
+++ /dev/null
@@ -1,55 +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.icu;
-
-import android.icu.util.LocaleData;
-import android.icu.util.ULocale;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-
-/**
- * Test for {@link android.icu.util.LocaleData}. Don't confuse with {@link libcore.icu.LocaleData}.
- */
-public class ICULocaleDataTest {
-
-    @Test
-    public void testGetDelimiter() {
-        LocaleData usLocaleData = LocaleData.getInstance(ULocale.US);
-        assertEquals("“", usLocaleData.getDelimiter(LocaleData.QUOTATION_START));
-        assertEquals("”", usLocaleData.getDelimiter(LocaleData.QUOTATION_END));
-        assertEquals("‘", usLocaleData.getDelimiter(LocaleData.ALT_QUOTATION_START));
-        assertEquals("’", usLocaleData.getDelimiter(LocaleData.ALT_QUOTATION_END));
-        LocaleData italianLocaleData = LocaleData.getInstance(ULocale.ITALIAN);
-        assertEquals("«", italianLocaleData.getDelimiter(LocaleData.QUOTATION_START));
-        assertEquals("»", italianLocaleData.getDelimiter(LocaleData.QUOTATION_END));
-        assertEquals("“", italianLocaleData.getDelimiter(LocaleData.ALT_QUOTATION_START));
-        assertEquals("”", italianLocaleData.getDelimiter(LocaleData.ALT_QUOTATION_END));
-
-        for (ULocale locale : ULocale.getAvailableLocales()) {
-            LocaleData localeData = LocaleData.getInstance(locale);
-            for (int type = LocaleData.QUOTATION_START; type <= LocaleData.ALT_QUOTATION_END;
-                    type++) {
-                String delimiter = localeData.getDelimiter(type);
-                assertNotNull("Delimiter is null in this locale " + locale, delimiter);
-                assertFalse("Delimiter is empty in this locale " + locale, delimiter.isEmpty());
-            }
-        }
-    }
-}
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/libcore/icu/ICUTest.java b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
index 30e3081..a5577a5 100644
--- a/luni/src/test/java/libcore/libcore/icu/ICUTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/ICUTest.java
@@ -44,6 +44,23 @@
     assertNotNull(ICU.getAvailableLocales()[0]);
   }
 
+  public void test_getCurrencyCode() {
+    assertEquals("USD", ICU.getCurrencyCode("US"));
+    assertEquals("CAD", ICU.getCurrencyCode("CA"));
+    assertEquals("HKD", ICU.getCurrencyCode("HK")); // a region
+
+    // Test invalid country codes
+    assertNull(ICU.getCurrencyCode("A"));
+    assertNull(ICU.getCurrencyCode(null));
+    assertNull(ICU.getCurrencyCode(""));
+    assertNull(ICU.getCurrencyCode("AA"));  // 2-charcter invalid country code
+    assertNull(ICU.getCurrencyCode("USA")); // 3-character country code
+    assertNull(ICU.getCurrencyCode("ZZZ"));
+    assertNull(ICU.getCurrencyCode("EURO"));
+    assertNull(ICU.getCurrencyCode("PREEURO"));
+    assertNull(ICU.getCurrencyCode("en_EURO"));
+  }
+
   public void test_getBestDateTimePattern() throws Exception {
     assertEquals("d MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("ca", "ES")));
     assertEquals("d 'de' MMMM", ICU.getBestDateTimePattern("MMMMd", new Locale("es", "ES")));
@@ -220,6 +237,32 @@
     assertTrue(c.compare("AF", "af") < 0);
   }
 
+  public void testTransformIcuDateTimePattern_forJavaTime() {
+    // Example patterns coming from locale my-MM
+    assertTransformIcuDateTimePattern("B H:mm", "H:mm");
+    assertTransformIcuDateTimePattern("B HH:mm:ss", "HH:mm:ss");
+    assertTransformIcuDateTimePattern("dd-MM-yy B HH:mm:ss", "dd-MM-yy HH:mm:ss");
+    assertTransformIcuDateTimePattern("y၊ MMM d B HH:mm:ss", "y၊ MMM d HH:mm:ss");
+
+    // Other examples
+    assertTransformIcuDateTimePattern("H:mm B", "H:mm");
+    assertTransformIcuDateTimePattern("H:mm b", "H:mm");
+    assertTransformIcuDateTimePattern("b H:mm", "H:mm");
+    assertTransformIcuDateTimePattern("B H:mm:ss, E", "H:mm:ss, E");
+
+    // Examples with no effect
+    assertTransformIcuDateTimePattern("hh:mm b", "hh:mm b"); // No change for 12-hour format
+    assertTransformIcuDateTimePattern("hh:mm B", "hh:mm B"); // No change for 12-hour format
+    assertTransformIcuDateTimePattern("B h:mm:ss, E", "B h:mm:ss, E");
+    // No change when no hour is specified
+    assertTransformIcuDateTimePattern("dd-MM-yy B", "dd-MM-yy B");
+  }
+
+  private static void assertTransformIcuDateTimePattern(String input, String expectedOutput) {
+    String pattern = ICU.transformIcuDateTimePattern_forJavaTime(input);
+    assertEquals("input:" + input, expectedOutput, pattern);
+  }
+
   public void testSetDefault() {
       String current = ICU.getDefaultLocale();
 
diff --git a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
index eace233..b524483 100644
--- a/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
+++ b/luni/src/test/java/libcore/libcore/icu/LocaleDataTest.java
@@ -23,6 +23,7 @@
 
 import android.icu.text.DateTimePatternGenerator;
 
+import java.text.DateFormat;
 import java.text.DateFormatSymbols;
 import java.text.DecimalFormatSymbols;
 import java.text.SimpleDateFormat;
@@ -42,25 +43,14 @@
 
 @RunWith(JUnit4.class)
 public class LocaleDataTest {
-  
+
   @Rule
   public TestRule switchTargetSdkVersionRule = SwitchTargetSdkVersionRule.getInstance();
 
   @Test
-  public void testAll() throws Exception {
-    // Test that we can get the locale data for all known locales.
-    for (Locale l : Locale.getAvailableLocales()) {
-      LocaleData d = LocaleData.get(l);
-      // System.err.format("%20s %s %s %s\n", l, d.yesterday, d.today, d.tomorrow);
-      // System.err.format("%20s %10s %10s\n", l, d.timeFormat_hm, d.timeFormat_Hm);
-    }
-  }
-
-  @Test
   public void test_en_US() throws Exception {
     LocaleData l = LocaleData.get(Locale.US);
     assertEquals("AM", l.amPm[0]);
-    assertEquals("a", l.narrowAm);
 
     assertEquals("BC", l.eras[0]);
 
@@ -80,18 +70,6 @@
     assertEquals("Sun", l.shortStandAloneWeekdayNames[1]);
     assertEquals("S", l.tinyStandAloneWeekdayNames[1]);
 
-    assertEquals("Yesterday", l.yesterday);
-    assertEquals("Today", l.today);
-    assertEquals("Tomorrow", l.tomorrow);
-  }
-
-  @Test
-  public void test_de_DE() throws Exception {
-    LocaleData l = LocaleData.get(new Locale("de", "DE"));
-
-    assertEquals("Gestern", l.yesterday);
-    assertEquals("Heute", l.today);
-    assertEquals("Morgen", l.tomorrow);
   }
 
   @Test
@@ -108,16 +86,6 @@
   }
 
   @Test
-  public void test_ko_KR() throws Exception {
-    LocaleData l = LocaleData.get(new Locale("ko", "KR"));
-
-    // Ensure the fix for http://b/14493853 doesn't mangle Hangul.
-    assertEquals("어제", l.yesterday);
-    assertEquals("오늘", l.today);
-    assertEquals("내일", l.tomorrow);
-  }
-
-  @Test
   public void test_ru_RU() throws Exception {
     LocaleData l = LocaleData.get(new Locale("ru", "RU"));
 
@@ -157,14 +125,23 @@
 
   // http://b/7924970
   @Test
-  public void testTimeFormat12And24() throws Exception {
-    LocaleData en_US = LocaleData.get(Locale.US);
-    assertEquals("h:mm a", en_US.timeFormat_hm);
-    assertEquals("HH:mm", en_US.timeFormat_Hm);
+  public void testTimeFormat12And24() {
+    Boolean originalSetting = DateFormat.is24Hour;
+    try {
+      LocaleData en_US = LocaleData.get(Locale.US);
+      DateFormat.is24Hour = false;
+      assertEquals("h:mm a", en_US.getTimeFormat(DateFormat.SHORT));
+      DateFormat.is24Hour = true;
+      assertEquals("HH:mm", en_US.getTimeFormat(DateFormat.SHORT));
 
-    LocaleData ja_JP = LocaleData.get(Locale.JAPAN);
-    assertEquals("aK:mm", ja_JP.timeFormat_hm);
-    assertEquals("H:mm", ja_JP.timeFormat_Hm);
+      LocaleData ja_JP = LocaleData.get(Locale.JAPAN);
+      DateFormat.is24Hour = false;
+      assertEquals("aK:mm", ja_JP.getTimeFormat(DateFormat.SHORT));
+      DateFormat.is24Hour = true;
+      assertEquals("H:mm", ja_JP.getTimeFormat(DateFormat.SHORT));
+    } finally {
+      DateFormat.is24Hour = originalSetting;
+    }
   }
 
   // http://b/26397197
@@ -264,11 +241,6 @@
     assertEquals(localeData.infinity, icuDecimalFormatSymbols.getInfinity());
     assertEquals(decimalFormatSymbols.getInfinity(), icuDecimalFormatSymbols.getInfinity());
 
-    assertEquals(localeData.timeFormat_Hm, dtpg.getBestPattern("Hm"));
-    assertEquals(localeData.timeFormat_hm, dtpg.getBestPattern("hm"));
-    assertEquals(localeData.timeFormat_Hms, dtpg.getBestPattern("Hms"));
-    assertEquals(localeData.timeFormat_hms, dtpg.getBestPattern("hms"));
-
     // Explicitly test Calendar and DateFormatSymbols here because they are known to
     // cache some part of LocaleData.
     assertEquals(calendar.getFirstDayOfWeek(), icuCalendar.getFirstDayOfWeek());
diff --git a/luni/src/test/java/libcore/libcore/icu/RelativeDateTimeFormatterTest.java b/luni/src/test/java/libcore/libcore/icu/RelativeDateTimeFormatterTest.java
deleted file mode 100644
index 651b9f9..0000000
--- a/luni/src/test/java/libcore/libcore/icu/RelativeDateTimeFormatterTest.java
+++ /dev/null
@@ -1,714 +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.icu;
-
-import java.util.Calendar;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import libcore.icu.RelativeDateTimeFormatter;
-
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_ALL;
-import static libcore.icu.DateUtilsBridge.FORMAT_ABBREV_RELATIVE;
-import static libcore.icu.DateUtilsBridge.FORMAT_NO_YEAR;
-import static libcore.icu.DateUtilsBridge.FORMAT_NUMERIC_DATE;
-import static libcore.icu.DateUtilsBridge.FORMAT_SHOW_YEAR;
-import static libcore.icu.RelativeDateTimeFormatter.DAY_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.HOUR_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.MINUTE_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.SECOND_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.WEEK_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.YEAR_IN_MILLIS;
-import static libcore.icu.RelativeDateTimeFormatter.getRelativeDateTimeString;
-import static libcore.icu.RelativeDateTimeFormatter.getRelativeTimeSpanString;
-
-public class RelativeDateTimeFormatterTest extends junit.framework.TestCase {
-
-  // Tests adopted from CTS tests for DateUtils.getRelativeTimeSpanString.
-  public void test_getRelativeTimeSpanStringCTS() throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("GMT");
-    Calendar cal = Calendar.getInstance(tz, en_US);
-    // Feb 5, 2015 at 10:50 GMT
-    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
-    final long baseTime = cal.getTimeInMillis();
-
-    assertEquals("0 minutes ago",
-                 getRelativeTimeSpanString(en_US, tz, baseTime - SECOND_IN_MILLIS, baseTime,
-                                           MINUTE_IN_MILLIS, 0));
-    assertEquals("In 0 minutes",
-                 getRelativeTimeSpanString(en_US, tz, baseTime + SECOND_IN_MILLIS, baseTime,
-                                           MINUTE_IN_MILLIS, 0));
-
-    assertEquals("1 minute ago",
-                 getRelativeTimeSpanString(en_US, tz, 0, MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 0));
-    assertEquals("In 1 minute",
-                 getRelativeTimeSpanString(en_US, tz, MINUTE_IN_MILLIS, 0, MINUTE_IN_MILLIS, 0));
-
-    assertEquals("42 minutes ago",
-      getRelativeTimeSpanString(en_US, tz, baseTime - 42 * MINUTE_IN_MILLIS, baseTime,
-                                MINUTE_IN_MILLIS, 0));
-    assertEquals("In 42 minutes",
-      getRelativeTimeSpanString(en_US, tz, baseTime + 42 * MINUTE_IN_MILLIS, baseTime,
-                                MINUTE_IN_MILLIS, 0));
-
-    final long TWO_HOURS_IN_MS = 2 * HOUR_IN_MILLIS;
-    assertEquals("2 hours ago",
-                 getRelativeTimeSpanString(en_US, tz, baseTime - TWO_HOURS_IN_MS, baseTime,
-                                           MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE));
-    assertEquals("In 2 hours",
-                 getRelativeTimeSpanString(en_US, tz, baseTime + TWO_HOURS_IN_MS, baseTime,
-                                           MINUTE_IN_MILLIS, FORMAT_NUMERIC_DATE));
-
-    assertEquals("In 42 min.",
-                 getRelativeTimeSpanString(en_US, tz, baseTime + (42 * MINUTE_IN_MILLIS), baseTime,
-                                           MINUTE_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-
-    assertEquals("Tomorrow",
-                 getRelativeTimeSpanString(en_US, tz, DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0));
-    assertEquals("In 2 days",
-                 getRelativeTimeSpanString(en_US, tz, 2 * DAY_IN_MILLIS, 0, DAY_IN_MILLIS, 0));
-    assertEquals("Yesterday",
-                 getRelativeTimeSpanString(en_US, tz, 0, DAY_IN_MILLIS, DAY_IN_MILLIS, 0));
-    assertEquals("2 days ago",
-                 getRelativeTimeSpanString(en_US, tz, 0, 2 * DAY_IN_MILLIS, DAY_IN_MILLIS, 0));
-
-    final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
-    assertEquals("5 days ago",
-                 getRelativeTimeSpanString(en_US, tz, baseTime - DAY_DURATION, baseTime,
-                                           DAY_IN_MILLIS, 0));
-  }
-
-  private void test_getRelativeTimeSpanString_helper(long delta, long minResolution, int flags,
-                                                     String expectedInPast,
-                                                     String expectedInFuture) throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-    Calendar cal = Calendar.getInstance(tz, en_US);
-    // Feb 5, 2015 at 10:50 PST
-    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
-    final long base = cal.getTimeInMillis();
-
-    assertEquals(expectedInPast,
-                 getRelativeTimeSpanString(en_US, tz, base - delta, base, minResolution, flags));
-    assertEquals(expectedInFuture,
-                 getRelativeTimeSpanString(en_US, tz, base + delta, base, minResolution, flags));
-  }
-
-  private void test_getRelativeTimeSpanString_helper(long delta, long minResolution,
-                                                     String expectedInPast,
-                                                     String expectedInFuture) throws Exception {
-    test_getRelativeTimeSpanString_helper(delta, minResolution, 0, expectedInPast, expectedInFuture);
-  }
-
-  public void test_getRelativeTimeSpanString() throws Exception {
-
-    test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, "0 seconds ago", "0 seconds ago");
-    test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago", "In 1 minute");
-    test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, "1 minute ago", "In 1 minute");
-    test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, "5 days ago", "In 5 days");
-
-    test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "0 seconds ago",
-                                          "0 seconds ago");
-    test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "1 second ago",
-                                          "In 1 second");
-    test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "2 seconds ago",
-                                          "In 2 seconds");
-    test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "25 seconds ago",
-                                          "In 25 seconds");
-    test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "1 minute ago",
-                                          "In 1 minute");
-    test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, "1 hour ago",
-                                          "In 1 hour");
-
-    test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "0 minutes ago",
-                                          "0 minutes ago");
-    test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "1 minute ago",
-                                          "In 1 minute");
-    test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "2 minutes ago",
-                                          "In 2 minutes");
-    test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "25 minutes ago",
-                                          "In 25 minutes");
-    test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "1 hour ago",
-                                          "In 1 hour");
-    test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, "12 hours ago",
-                                          "In 12 hours");
-
-    test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago",
-                                          "0 hours ago");
-    test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago",
-                                          "In 1 hour");
-    test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "2 hours ago",
-                                          "In 2 hours");
-    test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "5 hours ago",
-                                          "In 5 hours");
-    test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, "20 hours ago",
-                                          "In 20 hours");
-
-    test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today");
-    test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
-                                          "Tomorrow");
-    test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
-                                          "Tomorrow");
-    test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
-                                          "In 2 days");
-    test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, "January 11",
-                                          "March 2");
-
-    test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago",
-                                          "0 weeks ago");
-    test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago",
-                                          "In 1 week");
-    test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "2 weeks ago",
-                                          "In 2 weeks");
-    test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, "25 weeks ago",
-                                          "In 25 weeks");
-
-    // duration >= minResolution
-    test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, "30 seconds ago",
-                                          "In 30 seconds");
-    test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS,
-                                          "30 minutes ago", "In 30 minutes");
-    test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, "Yesterday",
-                                          "Tomorrow");
-    test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, "5 days ago",
-                                          "In 5 days");
-    test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS, "July 10, 2014",
-                                          "September 3");
-    test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS,
-                                          "February 6, 2010", "February 4, 2020");
-
-    test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, "1 minute ago",
-                                          "In 1 minute");
-    test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS,
-                                          "1 minute ago", "In 1 minute");
-    test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "1 hour ago",
-                                          "In 1 hour");
-    test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS, "1 hour ago",
-                                          "In 1 hour");
-    test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Today", "Today");
-    test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
-                                          "Today");
-    test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "Yesterday",
-                                          "Tomorrow");
-    test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
-                                          "In 2 days");
-    test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, "2 days ago",
-                                          "In 2 days");
-    test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, "1 week ago",
-                                          "In 1 week");
-    test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, "1 week ago",
-                                          "In 1 week");
-
-    // duration < minResolution
-    test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, "0 minutes ago",
-                                          "In 0 minutes");
-    test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, "0 hours ago",
-                                          "In 0 hours");
-    test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, "0 hours ago",
-                                          "In 0 hours");
-    test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, "Yesterday",
-                                          "Tomorrow");
-    test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, "0 weeks ago",
-                                          "In 0 weeks");
-    test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, "0 weeks ago",
-                                          "In 0 weeks");
-  }
-
-  public void test_getRelativeTimeSpanStringAbbrev() throws Exception {
-    int flags = FORMAT_ABBREV_RELATIVE;
-
-    test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, 0, flags, "0 sec. ago",
-                                          "0 sec. ago");
-    test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, 0, flags, "1 min. ago",
-                                          "In 1 min.");
-    test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, 0, flags, "5 days ago", "In 5 days");
-
-    test_getRelativeTimeSpanString_helper(0 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "0 sec. ago", "0 sec. ago");
-    test_getRelativeTimeSpanString_helper(1 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "1 sec. ago", "In 1 sec.");
-    test_getRelativeTimeSpanString_helper(2 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "2 sec. ago", "In 2 sec.");
-    test_getRelativeTimeSpanString_helper(25 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "25 sec. ago", "In 25 sec.");
-    test_getRelativeTimeSpanString_helper(75 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "1 min. ago", "In 1 min.");
-    test_getRelativeTimeSpanString_helper(5000 * SECOND_IN_MILLIS, SECOND_IN_MILLIS, flags,
-                                          "1 hr. ago", "In 1 hr.");
-
-    test_getRelativeTimeSpanString_helper(0 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "0 min. ago", "0 min. ago");
-    test_getRelativeTimeSpanString_helper(1 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "1 min. ago", "In 1 min.");
-    test_getRelativeTimeSpanString_helper(2 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "2 min. ago", "In 2 min.");
-    test_getRelativeTimeSpanString_helper(25 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "25 min. ago", "In 25 min.");
-    test_getRelativeTimeSpanString_helper(75 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "1 hr. ago", "In 1 hr.");
-    test_getRelativeTimeSpanString_helper(720 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "12 hr. ago", "In 12 hr.");
-
-    test_getRelativeTimeSpanString_helper(0 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "0 hr. ago", "0 hr. ago");
-    test_getRelativeTimeSpanString_helper(1 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "1 hr. ago", "In 1 hr.");
-    test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "2 hr. ago", "In 2 hr.");
-    test_getRelativeTimeSpanString_helper(5 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "5 hr. ago", "In 5 hr.");
-    test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "20 hr. ago", "In 20 hr.");
-
-    test_getRelativeTimeSpanString_helper(0 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags, "Today",
-                                          "Today");
-    test_getRelativeTimeSpanString_helper(20 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "Yesterday", "Tomorrow");
-    test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "Yesterday", "Tomorrow");
-    test_getRelativeTimeSpanString_helper(2 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "2 days ago", "In 2 days");
-    test_getRelativeTimeSpanString_helper(25 * DAY_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "January 11", "March 2");
-
-    test_getRelativeTimeSpanString_helper(0 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "0 wk. ago", "0 wk. ago");
-    test_getRelativeTimeSpanString_helper(1 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "1 wk. ago", "In 1 wk.");
-    test_getRelativeTimeSpanString_helper(2 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "2 wk. ago", "In 2 wk.");
-    test_getRelativeTimeSpanString_helper(25 * WEEK_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "25 wk. ago", "In 25 wk.");
-
-    // duration >= minResolution
-    test_getRelativeTimeSpanString_helper(30 * SECOND_IN_MILLIS, 0, flags, "30 sec. ago",
-                                          "In 30 sec.");
-    test_getRelativeTimeSpanString_helper(30 * MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "30 min. ago", "In 30 min.");
-    test_getRelativeTimeSpanString_helper(30 * HOUR_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "Yesterday", "Tomorrow");
-    test_getRelativeTimeSpanString_helper(5 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "5 days ago", "In 5 days");
-    test_getRelativeTimeSpanString_helper(30 * WEEK_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "July 10, 2014", "September 3");
-    test_getRelativeTimeSpanString_helper(5 * 365 * DAY_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "February 6, 2010", "February 4, 2020");
-
-    test_getRelativeTimeSpanString_helper(60 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "1 min. ago", "In 1 min.");
-    test_getRelativeTimeSpanString_helper(120 * SECOND_IN_MILLIS - 1, MINUTE_IN_MILLIS, flags,
-                                          "1 min. ago", "In 1 min.");
-    test_getRelativeTimeSpanString_helper(60 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "1 hr. ago", "In 1 hr.");
-    test_getRelativeTimeSpanString_helper(120 * MINUTE_IN_MILLIS - 1, HOUR_IN_MILLIS, flags,
-                                          "1 hr. ago", "In 1 hr.");
-    test_getRelativeTimeSpanString_helper(2 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags, "Today",
-                                          "Today");
-    test_getRelativeTimeSpanString_helper(12 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "Yesterday", "Today");
-    test_getRelativeTimeSpanString_helper(24 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "Yesterday", "Tomorrow");
-    test_getRelativeTimeSpanString_helper(48 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "2 days ago", "In 2 days");
-    test_getRelativeTimeSpanString_helper(45 * HOUR_IN_MILLIS, DAY_IN_MILLIS, flags,
-                                          "2 days ago", "In 2 days");
-    test_getRelativeTimeSpanString_helper(7 * DAY_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "1 wk. ago", "In 1 wk.");
-    test_getRelativeTimeSpanString_helper(14 * DAY_IN_MILLIS - 1, WEEK_IN_MILLIS, flags,
-                                          "1 wk. ago", "In 1 wk.");
-
-    // duration < minResolution
-    test_getRelativeTimeSpanString_helper(59 * SECOND_IN_MILLIS, MINUTE_IN_MILLIS, flags,
-                                          "0 min. ago", "In 0 min.");
-    test_getRelativeTimeSpanString_helper(59 * MINUTE_IN_MILLIS, HOUR_IN_MILLIS, flags,
-                                          "0 hr. ago", "In 0 hr.");
-    test_getRelativeTimeSpanString_helper(HOUR_IN_MILLIS - 1, HOUR_IN_MILLIS, flags,
-                                          "0 hr. ago", "In 0 hr.");
-    test_getRelativeTimeSpanString_helper(DAY_IN_MILLIS - 1, DAY_IN_MILLIS, flags,
-                                          "Yesterday", "Tomorrow");
-    test_getRelativeTimeSpanString_helper(20 * SECOND_IN_MILLIS, WEEK_IN_MILLIS, flags,
-                                          "0 wk. ago", "In 0 wk.");
-    test_getRelativeTimeSpanString_helper(WEEK_IN_MILLIS - 1, WEEK_IN_MILLIS, flags,
-                                          "0 wk. ago", "In 0 wk.");
-
-  }
-
-  public void test_getRelativeTimeSpanStringGerman() throws Exception {
-    // Bug: 19744876
-    // We need to specify the timezone and the time explicitly. Otherwise it
-    // may not always give a correct answer of "tomorrow" by using
-    // (now + DAY_IN_MILLIS).
-    Locale de_DE = new Locale("de", "DE");
-    TimeZone tz = TimeZone.getTimeZone("Europe/Berlin");
-    Calendar cal = Calendar.getInstance(tz, de_DE);
-    // Feb 5, 2015 at 10:50 CET
-    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
-    final long now = cal.getTimeInMillis();
-
-    // 42 minutes ago
-    assertEquals("Vor 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
-        now - 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
-    // In 42 minutes
-    assertEquals("In 42 Minuten", getRelativeTimeSpanString(de_DE, tz,
-        now + 42 * MINUTE_IN_MILLIS, now, MINUTE_IN_MILLIS, 0));
-    // Yesterday
-    assertEquals("Gestern", getRelativeTimeSpanString(de_DE, tz,
-        now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // The day before yesterday
-    assertEquals("Vorgestern", getRelativeTimeSpanString(de_DE, tz,
-        now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // Tomorrow
-    assertEquals("Morgen", getRelativeTimeSpanString(de_DE, tz,
-        now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // The day after tomorrow
-    assertEquals("Übermorgen", getRelativeTimeSpanString(de_DE, tz,
-        now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-  }
-
-  public void test_getRelativeTimeSpanStringFrench() throws Exception {
-    Locale fr_FR = new Locale("fr", "FR");
-    TimeZone tz = TimeZone.getTimeZone("Europe/Paris");
-    Calendar cal = Calendar.getInstance(tz, fr_FR);
-    // Feb 5, 2015 at 10:50 CET
-    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
-    final long now = cal.getTimeInMillis();
-
-    // 42 minutes ago
-    assertEquals("Il y a 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
-        now - (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
-    // In 42 minutes
-    assertEquals("Dans 42 minutes", getRelativeTimeSpanString(fr_FR, tz,
-        now + (42 * MINUTE_IN_MILLIS), now, MINUTE_IN_MILLIS, 0));
-    // Yesterday
-    assertEquals("Hier", getRelativeTimeSpanString(fr_FR, tz,
-        now - DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // The day before yesterday
-    assertEquals("Avant-hier", getRelativeTimeSpanString(fr_FR, tz,
-        now - 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // Tomorrow
-    assertEquals("Demain", getRelativeTimeSpanString(fr_FR, tz,
-        now + DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-    // The day after tomorrow
-    assertEquals("Après-demain", getRelativeTimeSpanString(fr_FR, tz,
-        now + 2 * DAY_IN_MILLIS, now, DAY_IN_MILLIS, 0));
-  }
-
-  // Tests adopted from CTS tests for DateUtils.getRelativeDateTimeString.
-  public void test_getRelativeDateTimeStringCTS() throws Exception {
-    Locale en_US = Locale.getDefault();
-    TimeZone tz = TimeZone.getDefault();
-    final long baseTime = System.currentTimeMillis();
-
-    final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
-    assertNotNull(getRelativeDateTimeString(en_US, tz, baseTime - DAY_DURATION, baseTime,
-                                            MINUTE_IN_MILLIS, DAY_IN_MILLIS,
-                                            FORMAT_NUMERIC_DATE));
-  }
-
-  public void test_getRelativeDateTimeString() throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-    Calendar cal = Calendar.getInstance(tz, en_US);
-    // Feb 5, 2015 at 10:50 PST
-    cal.set(2015, Calendar.FEBRUARY, 5, 10, 50, 0);
-    final long base = cal.getTimeInMillis();
-
-    assertEquals("5 seconds ago, 10:49 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * SECOND_IN_MILLIS, base, 0,
-                                           MINUTE_IN_MILLIS, 0));
-    assertEquals("5 min. ago, 10:45 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base, 0,
-                                           HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("0 hr. ago, 10:45 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * MINUTE_IN_MILLIS, base,
-                                           HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("5 hours ago, 5:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base,
-                                           HOUR_IN_MILLIS, DAY_IN_MILLIS, 0));
-    assertEquals("Yesterday, 7:50 PM",
-                 getRelativeDateTimeString(en_US, tz, base - 15 * HOUR_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("5 days ago, 10:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * DAY_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-    assertEquals("Jan 29, 10:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 7 * DAY_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-    assertEquals("11/27/2014, 10:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-    assertEquals("11/27/2014, 10:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
-                                           YEAR_IN_MILLIS, 0));
-
-    // User-supplied flags should be ignored when formatting the date clause.
-    final int FORMAT_SHOW_WEEKDAY = 0x00002;
-    assertEquals("11/27/2014, 10:50 AM",
-                 getRelativeDateTimeString(en_US, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS,
-                                           FORMAT_ABBREV_ALL | FORMAT_SHOW_WEEKDAY));
-  }
-
-  public void test_getRelativeDateTimeStringDST() throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-    Calendar cal = Calendar.getInstance(tz, en_US);
-
-    // DST starts on Mar 9, 2014 at 2:00 AM.
-    // So 5 hours before 3:15 AM should be formatted as 'Yesterday, 9:15 PM'.
-    cal.set(2014, Calendar.MARCH, 9, 3, 15, 0);
-    long base = cal.getTimeInMillis();
-    assertEquals("Yesterday, 9:15 PM",
-                 getRelativeDateTimeString(en_US, tz, base - 5 * HOUR_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-
-    // 1 hour after 2:00 AM should be formatted as 'In 1 hour, 4:00 AM'.
-    cal.set(2014, Calendar.MARCH, 9, 2, 0, 0);
-    base = cal.getTimeInMillis();
-    assertEquals("In 1 hour, 4:00 AM",
-                 getRelativeDateTimeString(en_US, tz, base + 1 * HOUR_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-
-    // DST ends on Nov 2, 2014 at 2:00 AM. Clocks are turned backward 1 hour to
-    // 1:00 AM. 8 hours before 5:20 AM should be 'Yesterday, 10:20 PM'.
-    cal.set(2014, Calendar.NOVEMBER, 2, 5, 20, 0);
-    base = cal.getTimeInMillis();
-    assertEquals("Yesterday, 10:20 PM",
-                 getRelativeDateTimeString(en_US, tz, base - 8 * HOUR_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-
-    cal.set(2014, Calendar.NOVEMBER, 2, 0, 45, 0);
-    base = cal.getTimeInMillis();
-    // 45 minutes after 0:45 AM should be 'In 45 minutes, 1:30 AM'.
-    assertEquals("In 45 minutes, 1:30 AM",
-                 getRelativeDateTimeString(en_US, tz, base + 45 * MINUTE_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-    // 45 minutes later, it should be 'In 45 minutes, 1:15 AM'.
-    assertEquals("In 45 minutes, 1:15 AM",
-                 getRelativeDateTimeString(en_US, tz, base + 90 * MINUTE_IN_MILLIS,
-                                           base + 45 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0));
-    // Another 45 minutes later, it should be 'In 45 minutes, 2:00 AM'.
-    assertEquals("In 45 minutes, 2:00 AM",
-                 getRelativeDateTimeString(en_US, tz, base + 135 * MINUTE_IN_MILLIS,
-                                           base + 90 * MINUTE_IN_MILLIS, 0, WEEK_IN_MILLIS, 0));
-  }
-
-
-  public void test_getRelativeDateTimeStringItalian() throws Exception {
-    Locale it_IT = new Locale("it", "IT");
-    TimeZone tz = TimeZone.getTimeZone("Europe/Rome");
-    Calendar cal = Calendar.getInstance(tz, it_IT);
-    // 05 febbraio 2015 20:15
-    cal.set(2015, Calendar.FEBRUARY, 5, 20, 15, 0);
-    final long base = cal.getTimeInMillis();
-
-    assertEquals("5 secondi fa, 20:14",
-                 getRelativeDateTimeString(it_IT, tz, base - 5 * SECOND_IN_MILLIS, base, 0,
-                                           MINUTE_IN_MILLIS, 0));
-    assertEquals("5 min fa, 20:10",
-                 getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base, 0,
-                                           HOUR_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("0 h fa, 20:10",
-                 getRelativeDateTimeString(it_IT, tz, base - 5 * MINUTE_IN_MILLIS, base,
-                                           HOUR_IN_MILLIS, DAY_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("Ieri, 22:15",
-                 getRelativeDateTimeString(it_IT, tz, base - 22 * HOUR_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-    assertEquals("5 giorni fa, 20:15",
-                 getRelativeDateTimeString(it_IT, tz, base - 5 * DAY_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-    assertEquals("27/11/2014, 20:15",
-                 getRelativeDateTimeString(it_IT, tz, base - 10 * WEEK_IN_MILLIS, base, 0,
-                                           WEEK_IN_MILLIS, 0));
-  }
-
-  // http://b/5252772: detect the actual date difference
-  public void test5252772() throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-
-    // Now is Sep 2, 2011, 10:23 AM PDT.
-    Calendar nowCalendar = Calendar.getInstance(tz, en_US);
-    nowCalendar.set(2011, Calendar.SEPTEMBER, 2, 10, 23, 0);
-    final long now = nowCalendar.getTimeInMillis();
-
-    // Sep 1, 2011, 10:24 AM
-    Calendar yesterdayCalendar1 = Calendar.getInstance(tz, en_US);
-    yesterdayCalendar1.set(2011, Calendar.SEPTEMBER, 1, 10, 24, 0);
-    long yesterday1 = yesterdayCalendar1.getTimeInMillis();
-    assertEquals("Yesterday, 10:24 AM",
-                 getRelativeDateTimeString(en_US, tz, yesterday1, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Sep 1, 2011, 10:22 AM
-    Calendar yesterdayCalendar2 = Calendar.getInstance(tz, en_US);
-    yesterdayCalendar2.set(2011, Calendar.SEPTEMBER, 1, 10, 22, 0);
-    long yesterday2 = yesterdayCalendar2.getTimeInMillis();
-    assertEquals("Yesterday, 10:22 AM",
-                 getRelativeDateTimeString(en_US, tz, yesterday2, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Aug 31, 2011, 10:24 AM
-    Calendar twoDaysAgoCalendar1 = Calendar.getInstance(tz, en_US);
-    twoDaysAgoCalendar1.set(2011, Calendar.AUGUST, 31, 10, 24, 0);
-    long twoDaysAgo1 = twoDaysAgoCalendar1.getTimeInMillis();
-    assertEquals("2 days ago, 10:24 AM",
-                 getRelativeDateTimeString(en_US, tz, twoDaysAgo1, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Aug 31, 2011, 10:22 AM
-    Calendar twoDaysAgoCalendar2 = Calendar.getInstance(tz, en_US);
-    twoDaysAgoCalendar2.set(2011, Calendar.AUGUST, 31, 10, 22, 0);
-    long twoDaysAgo2 = twoDaysAgoCalendar2.getTimeInMillis();
-    assertEquals("2 days ago, 10:22 AM",
-                 getRelativeDateTimeString(en_US, tz, twoDaysAgo2, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Sep 3, 2011, 10:22 AM
-    Calendar tomorrowCalendar1 = Calendar.getInstance(tz, en_US);
-    tomorrowCalendar1.set(2011, Calendar.SEPTEMBER, 3, 10, 22, 0);
-    long tomorrow1 = tomorrowCalendar1.getTimeInMillis();
-    assertEquals("Tomorrow, 10:22 AM",
-                 getRelativeDateTimeString(en_US, tz, tomorrow1, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Sep 3, 2011, 10:24 AM
-    Calendar tomorrowCalendar2 = Calendar.getInstance(tz, en_US);
-    tomorrowCalendar2.set(2011, Calendar.SEPTEMBER, 3, 10, 24, 0);
-    long tomorrow2 = tomorrowCalendar2.getTimeInMillis();
-    assertEquals("Tomorrow, 10:24 AM",
-                 getRelativeDateTimeString(en_US, tz, tomorrow2, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Sep 4, 2011, 10:22 AM
-    Calendar twoDaysLaterCalendar1 = Calendar.getInstance(tz, en_US);
-    twoDaysLaterCalendar1.set(2011, Calendar.SEPTEMBER, 4, 10, 22, 0);
-    long twoDaysLater1 = twoDaysLaterCalendar1.getTimeInMillis();
-    assertEquals("In 2 days, 10:22 AM",
-                 getRelativeDateTimeString(en_US, tz, twoDaysLater1, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-
-    // Sep 4, 2011, 10:24 AM
-    Calendar twoDaysLaterCalendar2 = Calendar.getInstance(tz, en_US);
-    twoDaysLaterCalendar2.set(2011, Calendar.SEPTEMBER, 4, 10, 24, 0);
-    long twoDaysLater2 = twoDaysLaterCalendar2.getTimeInMillis();
-    assertEquals("In 2 days, 10:24 AM",
-                 getRelativeDateTimeString(en_US, tz, twoDaysLater2, now, MINUTE_IN_MILLIS,
-                                           WEEK_IN_MILLIS, 0));
-  }
-
-  // b/19822016: show / hide the year based on the dates in the arguments.
-  public void test_bug19822016() throws Exception {
-    Locale en_US = new Locale("en", "US");
-    TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
-    Calendar cal = Calendar.getInstance(tz, en_US);
-    // Feb 5, 2012 at 10:50 PST
-    cal.set(2012, Calendar.FEBRUARY, 5, 10, 50, 0);
-    long base = cal.getTimeInMillis();
-
-    assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0));
-    assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
-    assertEquals("11/27/2011, 10:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
-
-    assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
-    assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
-    assertEquals("January 6, 2012", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
-    assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
-    assertEquals("December 7, 2011", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
-    assertEquals("December 7", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
-
-    // Feb 5, 2018 at 10:50 PST
-    cal.set(2018, Calendar.FEBRUARY, 5, 10, 50, 0);
-    base = cal.getTimeInMillis();
-    assertEquals("Feb 5, 5:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 5 * HOUR_IN_MILLIS, base, 0, MINUTE_IN_MILLIS, 0));
-    assertEquals("Jan 29, 10:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 7 * DAY_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
-    assertEquals("11/27/2017, 10:50 AM", getRelativeDateTimeString(en_US, tz,
-        base - 10 * WEEK_IN_MILLIS, base, 0, WEEK_IN_MILLIS, 0));
-
-    assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
-    assertEquals("January 6", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
-    assertEquals("January 6, 2018", getRelativeTimeSpanString(en_US, tz,
-        base - 30 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
-    assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, 0));
-    assertEquals("December 7, 2017", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_SHOW_YEAR));
-    assertEquals("December 7", getRelativeTimeSpanString(en_US, tz,
-        base - 60 * DAY_IN_MILLIS, base, DAY_IN_MILLIS, FORMAT_NO_YEAR));
-  }
-
-  // Check for missing ICU data. http://b/25821045
-  public void test_bug25821045() {
-    final TimeZone tz = TimeZone.getDefault();
-    final long now = System.currentTimeMillis();
-    final long time = now + 1000;
-    final int minResolution = 1000 * 60;
-    final int transitionResolution = minResolution;
-    final int flags = FORMAT_ABBREV_RELATIVE;
-    // Exercise all available locales, forcing the ICU implementation to pre-cache the data. This
-    // highlights data issues. It can take a while.
-    for (Locale locale : Locale.getAvailableLocales()) {
-      // In (e.g.) ICU56 an exception is thrown on the first use for a locale if required data for
-      // the "other" plural is missing. It doesn't matter what is actually formatted.
-      try {
-        RelativeDateTimeFormatter.getRelativeDateTimeString(
-            locale, tz, time, now, minResolution, transitionResolution, flags);
-      } catch (IllegalStateException e) {
-        fail("Failed to format for " + locale);
-      }
-    }
-  }
-
-  // Check for ICU data lookup fallback failure. http://b/25883157
-  public void test_bug25883157() {
-    final Locale locale = new Locale("en", "GB");
-    final TimeZone tz = TimeZone.getTimeZone("GMT");
-
-    final Calendar cal = Calendar.getInstance(tz, locale);
-    cal.set(2015, Calendar.JUNE, 19, 12, 0, 0);
-
-    final long base = cal.getTimeInMillis();
-    final long time = base + 2 * WEEK_IN_MILLIS;
-
-    assertEquals("In 2 wk", getRelativeTimeSpanString(
-        locale, tz, time, base, WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
-  }
-
-  // http://b/63745717
-  public void test_combineDateAndTime_apostrophe() {
-    final Locale locale = new Locale("fr");
-    android.icu.text.RelativeDateTimeFormatter icuFormatter =
-            android.icu.text.RelativeDateTimeFormatter.getInstance(locale);
-    assertEquals("D à T", icuFormatter.combineDateAndTime("D", "T"));
-    // Ensure single quote ' and curly braces {} are not interpreted in input values.
-    assertEquals("D'x' à T{0}", icuFormatter.combineDateAndTime("D'x'", "T{0}"));
-  }
-}
diff --git a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java b/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
deleted file mode 100644
index f24d8b1..0000000
--- a/luni/src/test/java/libcore/libcore/icu/TimeZoneIntegrationTest.java
+++ /dev/null
@@ -1,518 +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.icu;
-
-import org.junit.Test;
-
-import android.icu.text.TimeZoneNames;
-import android.icu.util.VersionInfo;
-import android.system.Os;
-
-import com.android.icu.util.Icu4cMetadata;
-
-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.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 = Icu4cMetadata.getTzdbVersion();
-
-        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 {
-        // The time zone data module is required.
-        String timeZoneModuleVersionFile =
-                TimeZoneDataFiles.getTimeZoneModuleTzFile(TzDataSetVersion.DEFAULT_FILE_NAME);
-        assertTzDataSetVersionIsCompatible(timeZoneModuleVersionFile);
-
-        // Check getTimeZoneModuleTzVersionFile() is doing the right thing.
-        // getTimeZoneModuleTzVersionFile() should go away when its one user, RulesManagerService,
-        // is removed from the platform code. http://b/123398797
-        assertEquals(TimeZoneDataFiles.getTimeZoneModuleTzVersionFile(), timeZoneModuleVersionFile);
-
-        // TODO: Remove this once the /system copy of time zone files have gone away. See also
-        // testTimeZoneDebugInfo().
-        assertTzDataSetVersionIsCompatible(
-                TimeZoneDataFiles.getSystemTzFile(TzDataSetVersion.DEFAULT_FILE_NAME));
-    }
-
-    private static void assertTzDataSetVersionIsCompatible(String versionFile) throws Exception {
-        TzDataSetVersion actualVersion = TzDataSetVersion.readFromFile(new File(versionFile));
-        assertEquals(
-                TzDataSetVersion.currentFormatMajorVersion(),
-                actualVersion.getFormatMajorVersion());
-        int minDeviceMinorVersion = TzDataSetVersion.currentFormatMinorVersion();
-        assertTrue(actualVersion.getFormatMinorVersion() >= 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 =
-                createModuleTzFiles(TimeZoneDataFiles::getTimeZoneModuleTzFile);
-        String icuOverlayFile = TimeZoneDataFiles.getTimeZoneModuleIcuFile("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);
-        }
-
-        String icuDatFileName = "icudt" + VersionInfo.ICU_VERSION.getMajor() + "l.dat";
-        String i18nModuleIcuData = TimeZoneDataFiles.getI18nModuleIcuFile(icuDatFileName);
-        assertFileExists(i18nModuleIcuData);
-
-        // 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.getSystemTzFile(TzDataSetVersion.DEFAULT_FILE_NAME));
-        assertFileExists(TimeZoneDataFiles.getSystemTzFile(ZoneInfoDb.TZDATA_FILE_NAME));
-        // The following files once existed in /system but have been removed as part of APEX work.
-        assertFileDoesNotExist(
-                TimeZoneDataFiles.getSystemTzFile(TimeZoneFinder.TZLOOKUP_FILE_NAME));
-
-        // 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(i18nModuleIcuData), Os.realpath(systemIcuData));
-        }
-    }
-
-    private static List<String> createModuleTzFiles(
-            Function<String, String> pathCreationFunction) {
-        List<String> relativePaths = Arrays.asList(
-                TzDataSetVersion.DEFAULT_FILE_NAME,
-                ZoneInfoDb.TZDATA_FILE_NAME,
-                TimeZoneFinder.TZLOOKUP_FILE_NAME);
-        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/TransliteratorTest.java b/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java
deleted file mode 100644
index d1e1483..0000000
--- a/luni/src/test/java/libcore/libcore/icu/TransliteratorTest.java
+++ /dev/null
@@ -1,97 +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 android.icu.text.Transliterator;
-
-import java.util.Enumeration;
-
-public class TransliteratorTest extends junit.framework.TestCase {
-  public void testAll() throws Exception {
-    Enumeration<String> ids = Transliterator.getAvailableIDs();
-    while (ids.hasMoreElements()) {
-      String id = ids.nextElement();
-      System.err.println(id);
-      Transliterator t = Transliterator.getInstance(id);
-      t.transliterate("hello");
-    }
-  }
-
-  public void test_Unknown() throws Exception {
-    try {
-      Transliterator t = Transliterator.getInstance("Unknown");
-      fail();
-    } catch (RuntimeException expected) {
-    }
-  }
-
-  public void test_null_id() throws Exception {
-    try {
-      Transliterator t = Transliterator.getInstance(null);
-      fail();
-    } catch (NullPointerException expected) {
-    }
-  }
-
-  public void test_Any_Upper() throws Exception {
-    Transliterator t = Transliterator.getInstance("Any-Upper");
-    assertEquals("HELLO WORLD!", t.transliterate("HeLlO WoRlD!"));
-    assertEquals("STRASSE", t.transliterate("Straße"));
-  }
-
-  public void test_Any_Lower() throws Exception {
-    Transliterator t = Transliterator.getInstance("Any-Lower");
-    assertEquals("hello world!", t.transliterate("HeLlO WoRlD!"));
-  }
-
-  public void test_Greek_Latin() throws Exception {
-    String greek = "Καλημέρα κόσμε!";
-
-    // Transliterate Greek to Latin, then to plain ASCII.
-    Transliterator t = Transliterator.getInstance("Greek-Latin");
-    String latin = t.transliterate(greek);
-    t = Transliterator.getInstance("Latin-Ascii");
-    String ascii = t.transliterate(latin);
-    assertEquals("Kalēméra kósme!", latin);
-    assertEquals("Kalemera kosme!", ascii);
-
-    // Use alternative transliteration variants.
-    t = Transliterator.getInstance("Greek-Latin/BGN");
-    assertEquals("Kaliméra kósme!", t.transliterate(greek));
-    t = Transliterator.getInstance("Greek-Latin/UNGEGN");
-    assertEquals("Kali̱méra kósme!",t.transliterate(greek));
-  }
-
-  public void test_Han_Latin() throws Exception {
-    Transliterator t = Transliterator.getInstance("Han-Latin");
-    assertEquals("hàn zì/hàn zì", t.transliterate("汉字/漢字"));
-
-    assertEquals("chén", t.transliterate("\u6c88"));
-    assertEquals("shěn", t.transliterate("\u700b"));
-    assertEquals("jiǎ", t.transliterate("\u8d3e"));
-
-    t = Transliterator.getInstance("Han-Latin/Names");
-    assertEquals("shěn", t.transliterate("\u6c88"));
-    assertEquals("shěn", t.transliterate("\u700b"));
-    assertEquals("jiǎ", t.transliterate("\u8d3e"));
-
-    t = Transliterator.getInstance("Han-Latin/Names; Latin-Ascii; Any-Upper");
-    assertEquals("SHEN", t.transliterate("\u6c88"));
-    assertEquals("SHEN", t.transliterate("\u700b"));
-    assertEquals("JIA", t.transliterate("\u8d3e"));
-  }
-}
diff --git a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
index 218678e..adbf399 100644
--- a/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/BlockGuardOsTest.java
@@ -17,10 +17,16 @@
 package libcore.libcore.io;
 
 import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
 import static android.system.OsConstants.IPPROTO_TCP;
 import static android.system.OsConstants.IPPROTO_UDP;
+import static android.system.OsConstants.F_SETFL;
 import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.O_NONBLOCK;
 import static android.system.OsConstants.SOCK_STREAM;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import org.junit.After;
 import org.junit.Before;
@@ -33,12 +39,14 @@
 import android.system.ErrnoException;
 import android.system.OsConstants;
 import android.system.StructAddrinfo;
+import android.system.UnixSocketAddress;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.net.InetAddress;
+import java.net.SocketAddress;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
@@ -143,6 +151,47 @@
     }
 
     @Test
+    public void test_nonblock() throws ErrnoException, IOException {
+        FileDescriptor unixSocket = Libcore.os.socket(AF_UNIX, SOCK_DGRAM, 0);
+        FileDescriptor udpSocket = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+        Libcore.os.fcntlInt(unixSocket, F_SETFL, O_NONBLOCK);
+        Libcore.os.fcntlInt(udpSocket, F_SETFL, O_NONBLOCK);
+        try {
+            assertTrue(BlockGuardOs.isNonBlockingFile(unixSocket));
+            assertTrue(BlockGuardOs.isNonBlockingFile(udpSocket));
+        } finally {
+            IoUtils.closeQuietly(unixSocket);
+        }
+    }
+
+    @Test
+    public void test_unixSocket() throws ErrnoException, IOException {
+        FileDescriptor unixSocket = Libcore.os.socket(AF_UNIX, SOCK_DGRAM, 0);
+        FileDescriptor udpSocket = Libcore.os.socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+        try {
+            assertTrue(BlockGuardOs.isUnixSocket(unixSocket));
+            assertFalse(BlockGuardOs.isUnixSocket(udpSocket));
+        } finally {
+            IoUtils.closeQuietly(unixSocket);
+        }
+    }
+
+    @Test
+    public void test_accept_networkPolicy() throws ErrnoException, IOException {
+        BlockGuardOs blockGuardOs = new BlockGuardOs(mockOsDelegate);
+
+        FileDescriptor unixSocket = Libcore.os.socket(AF_UNIX, SOCK_DGRAM, 0);
+        Libcore.os.fcntlInt(unixSocket, F_SETFL, O_NONBLOCK);
+        SocketAddress address = UnixSocketAddress.createAbstract("test_accept_networkPolicy");
+        Libcore.os.bind(unixSocket, address);
+        try {
+            assertNull(blockGuardOs.accept(unixSocket, address));
+        } finally {
+            IoUtils.closeQuietly(unixSocket);
+        }
+    }
+
+    @Test
     public void test_connect_networkPolicy() throws ErrnoException, IOException {
         BlockGuardOs blockGuardOs = new BlockGuardOs(mockOsDelegate);
 
@@ -220,7 +269,7 @@
                 "inet_pton(int,java.lang.String)",
                 "ioctlFlags(java.io.FileDescriptor,java.lang.String)",
                 "ioctlInetAddress(java.io.FileDescriptor,int,java.lang.String)",
-                "ioctlInt(java.io.FileDescriptor,int,android.system.Int32Ref)",
+                "ioctlInt(java.io.FileDescriptor,int)",
                 "ioctlMTU(java.io.FileDescriptor,java.lang.String)",
                 "isatty(java.io.FileDescriptor)",
                 "kill(int,int)",
diff --git a/luni/src/test/java/libcore/libcore/net/event/NetworkEventDispatcherTest.java b/luni/src/test/java/libcore/libcore/net/event/NetworkEventDispatcherTest.java
index 1a5cd40bb..361fadd 100644
--- a/luni/src/test/java/libcore/libcore/net/event/NetworkEventDispatcherTest.java
+++ b/luni/src/test/java/libcore/libcore/net/event/NetworkEventDispatcherTest.java
@@ -31,7 +31,7 @@
   }
 
   public void testAddListener_null() throws Exception {
-    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher();
     try {
       networkEventDispatcher.addListener(null);
       fail();
@@ -40,27 +40,27 @@
   }
 
   public void testOnNetworkConfigurationChanged_noListeners() throws Exception {
-    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
-    networkEventDispatcher.onNetworkConfigurationChanged();
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher();
+    networkEventDispatcher.dispatchNetworkConfigurationChange();
   }
 
   public void testFireNetworkEvent_oneListener() throws Exception {
     FakeNetworkEventListener listener = new FakeNetworkEventListener();
-    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher();
     networkEventDispatcher.addListener(listener);
 
-    networkEventDispatcher.onNetworkConfigurationChanged();
+    networkEventDispatcher.dispatchNetworkConfigurationChange();
 
     listener.assertNetworkConfigurationChangedEvent(1);
   }
 
   public void testRemoveEventListener() throws Exception {
     FakeNetworkEventListener listener = new FakeNetworkEventListener();
-    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher() {};
+    NetworkEventDispatcher networkEventDispatcher = new NetworkEventDispatcher();
     networkEventDispatcher.addListener(listener);
     networkEventDispatcher.removeListener(listener);
 
-    networkEventDispatcher.onNetworkConfigurationChanged();
+    networkEventDispatcher.dispatchNetworkConfigurationChange();
 
     listener.assertNetworkConfigurationChangedEvent(0);
   }
diff --git a/luni/src/test/java/libcore/libcore/net/http/HttpURLConnectionFactoryTest.java b/luni/src/test/java/libcore/libcore/net/http/HttpURLConnectionFactoryTest.java
new file mode 100644
index 0000000..09e78b2
--- /dev/null
+++ b/luni/src/test/java/libcore/libcore/net/http/HttpURLConnectionFactoryTest.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2021 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.http;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import libcore.net.http.HttpURLConnectionFactory;
+import libcore.net.http.Dns;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.SocketFactory;
+
+@RunWith(JUnit4.class)
+public class HttpURLConnectionFactoryTest {
+
+    @Test
+    public void testCreateInstance() {
+        final HttpURLConnectionFactory factory = HttpURLConnectionFactory.createInstance();
+        assertNotNull(factory);
+        assertTrue(factory instanceof HttpURLConnectionFactory);
+    }
+
+    @Test
+    public void testOpenConnection() throws IOException {
+        final Map<String, InetAddress> lookupResult = new HashMap();
+        lookupResult.put("test.com", Inet4Address.ANY);
+        final HttpURLConnectionFactory factory = HttpURLConnectionFactory.createInstance();
+        final Dns dns = hostname -> Arrays.asList(lookupResult.get(hostname));
+        factory.setDns(dns);
+        factory.setNewConnectionPool(5, 5000, TimeUnit.MILLISECONDS);
+        final URL url = new URL("http://test.com");
+        final URLConnection connection = factory.openConnection(url, SocketFactory.getDefault(),
+                java.net.Proxy.NO_PROXY);
+        assertEquals(connection.getURL(), url);
+    }
+
+    @Test
+    public void testDns() throws IOException  {
+        final String testHostName1 = "test1.com";
+        final String testHostName2 = "test2.com";
+        final String testHostName3 = "test3.com";
+        final List<InetAddress> testHostAddresses1 = List.of(Inet4Address.ALL);
+        final List<InetAddress> testHostAddresses2 = List.of(Inet6Address.ANY);
+        final List<InetAddress> testHostAddresses3 =
+                List.of(Inet4Address.ANY, Inet6Address.LOOPBACK);
+        final Map<String, List<InetAddress>> lookupResult = new HashMap();
+        lookupResult.put(testHostName1, testHostAddresses1);
+        lookupResult.put(testHostName2, testHostAddresses2);
+        lookupResult.put(testHostName3, testHostAddresses3);
+
+        final Dns dns = hostname -> lookupResult.get(hostname);
+        assertEquals(testHostAddresses1, dns.lookup(testHostName1));
+        assertEquals(testHostAddresses2, dns.lookup(testHostName2));
+        assertEquals(testHostAddresses3, dns.lookup(testHostName3));
+    }
+}
diff --git a/luni/src/test/java/libcore/libcore/timezone/CountryTimeZonesTest.java b/luni/src/test/java/libcore/libcore/timezone/CountryTimeZonesTest.java
deleted file mode 100644
index cf32896..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/CountryTimeZonesTest.java
+++ /dev/null
@@ -1,552 +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.timezone;
-
-import org.junit.Test;
-
-import android.icu.util.TimeZone;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Function;
-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. NY_TZ and LON_TZ chosen because they never overlap but both have
-    // DST.
-    private static final TimeZone NY_TZ = TimeZone.getTimeZone("America/New_York");
-    private static final TimeZone LON_TZ = TimeZone.getTimeZone("Europe/London");
-    // A zone that matches LON_TZ for WHEN_NO_DST. It does not have DST so differs for WHEN_DST.
-    private static final TimeZone REYK_TZ = TimeZone.getTimeZone("Atlantic/Reykjavik");
-    // Another zone that matches LON_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 LON_NO_DST_TOTAL_OFFSET = 0;
-    private static final int LON_DST_TOTAL_OFFSET = LON_NO_DST_TOTAL_OFFSET
-            + NORMAL_DST_ADJUSTMENT;
-
-    private static final int NY_NO_DST_TOTAL_OFFSET = -5 * HOUR_MILLIS;
-    private static final int NY_DST_TOTAL_OFFSET = NY_NO_DST_TOTAL_OFFSET
-            + NORMAL_DST_ADJUSTMENT;
-
-    @Test
-    public void createValidated() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", false /* defaultTimeZoneBoost */,
-                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());
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0 /* whenMillis */));
-    }
-
-    @Test
-    public void createValidated_nullDefault() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", null, false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London"), "test");
-        assertNull(countryTimeZones.getDefaultTimeZoneId());
-        assertNull(countryTimeZones.getDefaultTimeZone());
-    }
-
-    @Test
-    public void createValidated_invalidDefault() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", INVALID_TZ_ID, false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London", INVALID_TZ_ID), "test");
-        assertNull(countryTimeZones.getDefaultTimeZoneId());
-        assertNull(countryTimeZones.getDefaultTimeZone());
-        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0 /* whenMillis */));
-    }
-
-    @Test
-    public void createValidated_unknownTimeZoneIdIgnored() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Unknown_Id", "Europe/London"), "test");
-        assertEquals(timeZoneMappings("Europe/London"), countryTimeZones.getTimeZoneMappings());
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0 /* whenMillis */));
-    }
-
-    @Test
-    public void isForCountryCode() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London"), "test");
-
-        assertImmutableTimeZone(countryTimeZones.getDefaultTimeZone());
-
-        List<TimeZoneMapping> timeZoneMappings = countryTimeZones.getTimeZoneMappings();
-        assertEquals(1, timeZoneMappings.size());
-        assertImmutableList(timeZoneMappings);
-
-        List<TimeZoneMapping> effectiveTimeZoneMappings =
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0 /* whenMillis */);
-        assertEquals(1, effectiveTimeZoneMappings.size());
-        assertImmutableList(effectiveTimeZoneMappings);
-    }
-
-    @Test
-    public void lookupByOffsetWithBias_oneCandidate() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London"), "test");
-
-        OffsetResult lonMatch = new OffsetResult(LON_TZ, true /* oneMatch */);
-
-        // Placeholder constants to improve test case readability.
-        final Boolean isDst = true;
-        final Boolean notDst = false;
-        final Boolean unkIsDst = null;
-        final TimeZone noBias = null;
-        final OffsetResult noMatch = null;
-
-        Object[][] testCases = new Object[][] {
-                // totalOffsetMillis, isDst, whenMillis, bias, expectedMatch
-
-                // The parameters match the zone: total offset and time.
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, noBias, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, noBias, lonMatch },
-
-                // The parameters match the zone: total offset, isDst and time.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, noBias, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, notDst, WHEN_NO_DST, noBias, lonMatch },
-
-                // Some lookup failure cases where the total offset, isDst and time do not match the
-                // zone.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_DST_TOTAL_OFFSET, notDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, isDst, WHEN_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_DST_TOTAL_OFFSET, notDst, WHEN_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, notDst, WHEN_DST, noBias, noMatch },
-
-                // Some bias cases below.
-
-                // The bias is irrelevant here: it matches what would be returned anyway.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, LON_TZ, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, notDst, WHEN_NO_DST, LON_TZ, lonMatch },
-
-                // A sample of a non-matching case with bias.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, LON_TZ, noMatch },
-
-                // The bias should be ignored: it doesn't match any of the country's zones.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, NY_TZ, lonMatch },
-
-                // The bias should still be ignored even though it matches the offset information
-                // given it doesn't match any of the country's zones.
-                { NY_DST_TOTAL_OFFSET, isDst, WHEN_DST, NY_TZ, noMatch },
-        };
-        executeLookupByOffsetWithBiasTestCases(countryTimeZones, testCases);
-    }
-
-    @Test
-    public void lookupByOffsetWithBias_multipleNonOverlappingCandidates() throws Exception {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("America/New_York", "Europe/London"), "test");
-
-        OffsetResult lonMatch = new OffsetResult(LON_TZ, true /* oneMatch */);
-        OffsetResult nyMatch = new OffsetResult(NY_TZ, true /* oneMatch */);
-
-        // Placeholder constants to improve test case readability.
-        final Boolean isDst = true;
-        final Boolean notDst = false;
-        final Boolean unkIsDst = null;
-        final TimeZone noBias = null;
-        final OffsetResult noMatch = null;
-
-        Object[][] testCases = new Object[][] {
-                // totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias, expectedMatch
-
-                // The parameters match the zone: total offset and time.
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, noBias, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, noBias, lonMatch },
-                { NY_NO_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, noBias, nyMatch },
-                { NY_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, noBias, nyMatch },
-
-                // The parameters match the zone: total offset, isDst and time.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, noBias, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, notDst, WHEN_NO_DST, noBias, lonMatch },
-                { NY_DST_TOTAL_OFFSET, isDst, WHEN_DST, noBias, nyMatch },
-                { NY_NO_DST_TOTAL_OFFSET, notDst, WHEN_NO_DST, noBias, nyMatch },
-
-                // Some lookup failure cases where the total offset, isDst and time do not match the
-                // zone. This is a sample, not complete.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_DST_TOTAL_OFFSET, notDst, WHEN_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, isDst, WHEN_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, noBias, noMatch },
-                { LON_NO_DST_TOTAL_OFFSET, notDst, WHEN_DST, noBias, noMatch },
-
-                // Some bias cases below.
-
-                // The bias is irrelevant here: it matches what would be returned anyway.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, LON_TZ, lonMatch },
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, LON_TZ, lonMatch },
-                { LON_NO_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, LON_TZ, lonMatch },
-
-                // A sample of non-matching cases with bias.
-                { LON_NO_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, LON_TZ, noMatch },
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_NO_DST, LON_TZ, noMatch },
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_NO_DST, LON_TZ, noMatch },
-
-                // The bias should be ignored: it matches a zone, but the offset is wrong so
-                // should not be considered a match.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, NY_TZ, lonMatch },
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, NY_TZ, lonMatch },
-        };
-        executeLookupByOffsetWithBiasTestCases(countryTimeZones, testCases);
-    }
-
-    // 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", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Atlantic/Reykjavik", "Europe/London", "Etc/UTC"), "test");
-
-        // Placeholder constants to improve test case readability.
-        final Boolean isDst = true;
-        final Boolean notDst = false;
-        final Boolean unkIsDst = null;
-        final TimeZone noBias = null;
-        final OffsetResult noMatch = null;
-
-        // This is the no-DST offset for LON_TZ, REYK_TZ. UTC_TZ.
-        final int noDstTotalOffset = LON_NO_DST_TOTAL_OFFSET;
-        // This is the DST offset for LON_TZ.
-        final int dstTotalOffset = LON_DST_TOTAL_OFFSET;
-
-        OffsetResult lonOnlyMatch = new OffsetResult(LON_TZ, true /* oneMatch */);
-        OffsetResult lonBestMatch = new OffsetResult(LON_TZ, false /* oneMatch */);
-        OffsetResult reykBestMatch = new OffsetResult(REYK_TZ, false /* oneMatch */);
-        OffsetResult utcBestMatch = new OffsetResult(UTC_TZ, false /* oneMatch */);
-
-        Object[][] testCases = new Object[][] {
-                // totalOffsetMillis, isDst, dstOffsetMillis, whenMillis, bias, expectedMatch
-
-                // The parameters match one zone: total offset and time.
-                { dstTotalOffset, unkIsDst, WHEN_DST, noBias, lonOnlyMatch },
-                { dstTotalOffset, unkIsDst, WHEN_DST, noBias, lonOnlyMatch },
-
-                // The parameters match several zones: total offset and time.
-                { noDstTotalOffset, unkIsDst, WHEN_NO_DST, noBias, reykBestMatch },
-                { noDstTotalOffset, unkIsDst, WHEN_DST, noBias, reykBestMatch },
-
-                // The parameters match one zone: total offset, isDst and time.
-                { dstTotalOffset, isDst, WHEN_DST, noBias, lonOnlyMatch },
-                { dstTotalOffset, isDst, WHEN_DST, noBias, lonOnlyMatch },
-
-                { noDstTotalOffset, notDst, WHEN_NO_DST, noBias, reykBestMatch },
-                { noDstTotalOffset, notDst, WHEN_DST, noBias, reykBestMatch },
-
-                // Some lookup failure cases where the total offset, isDst and time do not match any
-                // zone.
-                { dstTotalOffset, isDst, WHEN_NO_DST, noBias, noMatch },
-                { dstTotalOffset, unkIsDst, WHEN_NO_DST, noBias, noMatch },
-                { noDstTotalOffset, isDst, WHEN_NO_DST, noBias, noMatch },
-                { noDstTotalOffset, isDst, WHEN_DST, noBias, noMatch },
-
-                // Some bias cases below.
-
-                // Multiple zones match but Reykjavik is the bias.
-                { noDstTotalOffset, notDst, WHEN_NO_DST, REYK_TZ, reykBestMatch },
-
-                // Multiple zones match but London is the bias.
-                { noDstTotalOffset, notDst, WHEN_NO_DST, LON_TZ, lonBestMatch },
-
-                // Multiple zones match but UTC is the bias.
-                { noDstTotalOffset, notDst, WHEN_NO_DST, UTC_TZ, utcBestMatch },
-
-                // The bias should be ignored: it matches a zone, but the offset is wrong so
-                // should not be considered a match.
-                { LON_DST_TOTAL_OFFSET, isDst, WHEN_DST, REYK_TZ, lonOnlyMatch },
-                { LON_DST_TOTAL_OFFSET, unkIsDst, WHEN_DST, REYK_TZ, lonOnlyMatch },
-        };
-        executeLookupByOffsetWithBiasTestCases(countryTimeZones, testCases);
-    }
-
-    private static void executeLookupByOffsetWithBiasTestCases(
-            CountryTimeZones countryTimeZones, Object[][] testCases) {
-
-        List<String> failures = new ArrayList<>();
-        for (int i = 0; i < testCases.length; i++) {
-            Object[] testCase = testCases[i];
-            int totalOffsetMillis = (int) testCase[0];
-            Boolean isDst = (Boolean) testCase[1];
-            long whenMillis = (Long) testCase[2];
-            TimeZone bias = (TimeZone) testCase[3];
-            OffsetResult expectedMatch = (OffsetResult) testCase[4];
-
-            OffsetResult actualMatch;
-            if (isDst == null) {
-                actualMatch = countryTimeZones.lookupByOffsetWithBias(
-                        whenMillis, bias, totalOffsetMillis);
-            } else {
-                actualMatch = countryTimeZones.lookupByOffsetWithBias(
-                        whenMillis, bias, totalOffsetMillis, isDst);
-            }
-
-            if (!offsetResultEquals(expectedMatch, actualMatch)) {
-                Function<TimeZone, String> timeZoneFormatter =
-                        x -> x == null ? "null" : x.getID();
-                Function<OffsetResult, String> offsetResultFormatter =
-                        x -> x == null ? "null"
-                                : "{" + x.getTimeZone().getID() + ", " + x.isOnlyMatch() + "}";
-                failures.add("Fail: case=" + i
-                        + ", totalOffsetMillis=" + totalOffsetMillis
-                        + ", isDst=" + isDst
-                        + ", whenMillis=" + whenMillis
-                        + ", bias=" + timeZoneFormatter.apply(bias)
-                        + ", expectedMatch=" + offsetResultFormatter.apply(expectedMatch)
-                        + ", actualMatch=" + offsetResultFormatter.apply(actualMatch)
-                        + "\n");
-            }
-        }
-        if (!failures.isEmpty()) {
-            fail("Failed:\n" + failures);
-        }
-    }
-
-    @Test
-    public void getEffectiveTimeZonesAt_noZones() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings(), "test");
-        assertEquals(timeZoneMappings(),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0 /* whenMillis */));
-        assertEquals(timeZoneMappings(),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MIN_VALUE));
-        assertEquals(timeZoneMappings(),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MAX_VALUE));
-    }
-
-    @Test
-    public void getEffectiveTimeZonesAt_oneZone() {
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London"), "test");
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(0));
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MIN_VALUE));
-        assertEquals(timeZoneMappings("Europe/London"),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MAX_VALUE));
-    }
-
-    @Test
-    public void getEffectiveTimeZonesAt_filtering() {
-        TimeZoneMapping alwaysUsed = timeZoneMapping("Europe/London", null /* notUsedAfter */);
-
-        long mappingNotUsedAfterMillis = 0L;
-        TimeZoneMapping notAlwaysUsed = timeZoneMapping("Europe/Paris",
-                mappingNotUsedAfterMillis /* notUsedAfter */);
-
-        List<TimeZoneMapping> timeZoneMappings = list(alwaysUsed, notAlwaysUsed);
-        CountryTimeZones countryTimeZones = CountryTimeZones.createValidated(
-                "xx", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings, "test");
-
-        // Before and at mappingNotUsedAfterMillis, both mappings are "effective".
-        assertEquals(list(alwaysUsed, notAlwaysUsed),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MIN_VALUE));
-        assertEquals(list(alwaysUsed, notAlwaysUsed),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(mappingNotUsedAfterMillis));
-
-        // The following should filter the second mapping because it's not "effective" after
-        // mappingNotUsedAfterMillis.
-        assertEquals(list(alwaysUsed),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(mappingNotUsedAfterMillis + 1));
-        assertEquals(list(alwaysUsed),
-                countryTimeZones.getEffectiveTimeZoneMappingsAt(Long.MAX_VALUE));
-    }
-
-    @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 /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */,
-                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 /* defaultTimeZoneBoost */, 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 /* defaultTimeZoneBoost */, false /* everUsesUtc */,
-                timeZoneMappings(INVALID_TZ_ID), "test");
-        assertTrue(countryTimeZones.getTimeZoneMappings().isEmpty());
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_DST));
-        assertFalse(countryTimeZones.hasUtcZone(WHEN_NO_DST));
-    }
-
-    @Test
-    public void timeZoneMapping_getTimeZone_badZoneId() {
-        TimeZoneMapping timeZoneMapping =
-                TimeZoneMapping.createForTests("DOES_NOT_EXIST", true, 1234L);
-        try {
-            timeZoneMapping.getTimeZone();
-            fail();
-        } catch (RuntimeException expected) {
-        }
-    }
-
-    @Test
-    public void timeZoneMapping_getTimeZone_validZoneId() {
-        TimeZoneMapping timeZoneMapping =
-                TimeZoneMapping.createForTests("Europe/London", true, 1234L);
-        TimeZone timeZone = timeZoneMapping.getTimeZone();
-        assertTrue(timeZone.isFrozen());
-        assertEquals("Europe/London", timeZone.getID());
-    }
-
-    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 boolean offsetResultEquals(OffsetResult expected, OffsetResult actual) {
-        return expected == actual
-                || (expected != null && actual != null
-                && Objects.equals(expected.getTimeZone().getID(), actual.getTimeZone().getID())
-                && expected.isOnlyMatch() == actual.isOnlyMatch());
-    }
-
-    /**
-     * Creates a list of default {@link TimeZoneMapping} objects with the specified time zone IDs.
-     */
-    private static TimeZoneMapping timeZoneMapping(String timeZoneId, Long notUsedAfterMillis) {
-        return TimeZoneMapping.createForTests(
-                        timeZoneId, true /* picker */, notUsedAfterMillis);
-    }
-
-    /**
-     * 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 TimeZone zone(String id) {
-        return TimeZone.getFrozenTimeZone(id);
-    }
-
-    private static <X> List<X> list(X... xes) {
-        return Arrays.asList(xes);
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java b/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java
deleted file mode 100644
index ecd5201..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/CountryZonesFinderTest.java
+++ /dev/null
@@ -1,117 +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.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", false /* defaultTimeZoneBoost */, true,
-            timeZoneMappings("Europe/London"), "test");
-
-    private static final CountryTimeZones IM_ZONES = CountryTimeZones.createValidated(
-            "im", "Europe/London", false /* defaultTimeZoneBoost */, true,
-            timeZoneMappings("Europe/London"), "test");
-
-    private static final CountryTimeZones FR_ZONES = CountryTimeZones.createValidated(
-            "fr", "Europe/Paris", false /* defaultTimeZoneBoost */, true,
-            timeZoneMappings("Europe/Paris"), "test");
-
-    private static final CountryTimeZones US_ZONES = CountryTimeZones.createValidated(
-            "us", "America/New_York", false /* defaultTimeZoneBoost */, 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/TelephonyLookupTest.java b/luni/src/test/java/libcore/libcore/timezone/TelephonyLookupTest.java
deleted file mode 100644
index 8b4d867..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/TelephonyLookupTest.java
+++ /dev/null
@@ -1,367 +0,0 @@
-/*
- * 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.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import libcore.timezone.TelephonyLookup;
-import libcore.timezone.TelephonyNetwork;
-import libcore.timezone.TelephonyNetworkFinder;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-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;
-
-public class TelephonyLookupTest {
-
-    private Path testDir;
-
-    @Before
-    public void setUp() throws Exception {
-        testDir = Files.createTempDirectory("TelephonyLookupTest");
-    }
-
-    @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 = "<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n";
-        TelephonyNetwork expectedTelephonyNetwork1 =
-                TelephonyNetwork.create("123", "456", "gb");
-
-        String validXml2 = "<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"234\" mnc=\"567\" country=\"fr\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n";
-        TelephonyNetwork expectedTelephonyNetwork2 =
-                TelephonyNetwork.create("234", "567", "fr");
-
-        String invalidXml = "<foo></foo>\n";
-        checkValidateThrowsParserException(invalidXml);
-
-        String validFile1 = createFile(validXml1);
-        String validFile2 = createFile(validXml2);
-        String invalidFile = createFile(invalidXml);
-        String missingFile = createMissingFile();
-
-        TelephonyLookup file1ThenFile2 =
-                TelephonyLookup.createInstanceWithFallback(validFile1, validFile2);
-        assertEquals(list(expectedTelephonyNetwork1),
-                file1ThenFile2.getTelephonyNetworkFinder().getAll());
-
-        TelephonyLookup missingFileThenFile1 =
-                TelephonyLookup.createInstanceWithFallback(missingFile, validFile1);
-        assertEquals(list(expectedTelephonyNetwork1),
-                missingFileThenFile1.getTelephonyNetworkFinder().getAll());
-
-        TelephonyLookup file2ThenFile1 =
-                TelephonyLookup.createInstanceWithFallback(validFile2, validFile1);
-        assertEquals(list(expectedTelephonyNetwork2),
-                file2ThenFile1.getTelephonyNetworkFinder().getAll());
-
-        // 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.
-        TelephonyLookup invalidThenValid =
-                TelephonyLookup.createInstanceWithFallback(invalidFile, validFile1);
-        assertNull(invalidThenValid.getTelephonyNetworkFinder());
-
-        // This is not a normal case: It would imply a device shipped without a file anywhere!
-        TelephonyLookup missingFiles =
-                TelephonyLookup.createInstanceWithFallback(missingFile, missingFile);
-        assertEmpty(missingFiles.getTelephonyNetworkFinder().getAll());
-    }
-
-    @Test
-    public void xmlParsing_emptyFile() throws Exception {
-        checkValidateThrowsParserException("");
-    }
-
-    @Test
-    public void xmlParsing_unexpectedRootElement() throws Exception {
-        checkValidateThrowsParserException("<foo></foo>\n");
-    }
-
-    @Test
-    public void xmlParsing_missingNetworks() throws Exception {
-        checkValidateThrowsParserException("<telephony_lookup></telephony_lookup>\n");
-    }
-
-    @Test
-    public void xmlParsing_emptyNetworksOk() throws Exception {
-        {
-            TelephonyLookup telephonyLookup =
-                    validate("<telephony_lookup>\n"
-                            + "  <networks>\n"
-                            + "  </networks>\n"
-                            + "</telephony_lookup>\n");
-            TelephonyNetworkFinder telephonyNetworkFinder = telephonyLookup
-                    .getTelephonyNetworkFinder();
-            assertEquals(list(), telephonyNetworkFinder.getAll());
-        }
-        {
-            TelephonyLookup telephonyLookup =
-                    validate("<telephony_lookup>\n"
-                            + "  <networks/>\n"
-                            + "</telephony_lookup>\n");
-            TelephonyNetworkFinder telephonyNetworkFinder = telephonyLookup
-                    .getTelephonyNetworkFinder();
-            assertEquals(list(), telephonyNetworkFinder.getAll());
-        }
-    }
-
-    @Test
-    public void xmlParsing_unexpectedComments() throws Exception {
-        TelephonyNetwork expectedTelephonyNetwork =
-                TelephonyNetwork.create("123", "456", "gb");
-
-        TelephonyLookup telephonyLookup = validate("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <!-- This is a comment -->"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertEquals(list(expectedTelephonyNetwork), telephonyLookup.getTelephonyNetworkFinder().getAll());
-    }
-
-    @Test
-    public void xmlParsing_unexpectedElementsIgnored() throws Exception {
-        TelephonyNetwork expectedTelephonyNetwork =
-                TelephonyNetwork.create("123", "456", "gb");
-        List<TelephonyNetwork> expectedNetworks = list(expectedTelephonyNetwork);
-
-        String unexpectedElement = "<unexpected-element>\n<a /></unexpected-element>\n";
-
-        // These tests are important because they ensure we can extend the format in future with
-        // more information but could continue using the same file on older devices.
-        TelephonyLookup telephonyLookup = validate("<telephony_lookup>\n"
-                + " " + unexpectedElement
-                + "  <networks>\n"
-                + "    " + unexpectedElement
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "    " + unexpectedElement
-                + "  </networks>\n"
-                + "  " + unexpectedElement
-                + "</telephony_lookup>\n");
-        assertEquals(expectedNetworks, telephonyLookup.getTelephonyNetworkFinder().getAll());
-
-        telephonyLookup = validate("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\">\n"
-                + "    " + unexpectedElement
-                + "    </network>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertEquals(expectedNetworks, telephonyLookup.getTelephonyNetworkFinder().getAll());
-
-        expectedNetworks = list(expectedTelephonyNetwork,
-                TelephonyNetwork.create("234", "567", "fr"));
-        telephonyLookup = validate("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "    " + unexpectedElement
-                + "    <network mcc=\"234\" mnc=\"567\" country=\"fr\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertEquals(expectedNetworks, telephonyLookup.getTelephonyNetworkFinder().getAll());
-    }
-
-    @Test
-    public void xmlParsing_unexpectedTextIgnored() throws Exception {
-        TelephonyNetwork expectedTelephonyNetwork =
-                TelephonyNetwork.create("123", "456", "gb");
-        List<TelephonyNetwork> expectedNetworks = list(expectedTelephonyNetwork);
-
-        String unexpectedText = "unexpected-text";
-        TelephonyLookup telephonyLookup = validate("<telephony_lookup>\n"
-                + "  " + unexpectedText
-                + "  <networks>\n"
-                + "  " + unexpectedText
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "    " + unexpectedText
-                + "  </networks>\n"
-                + "  " + unexpectedText
-                + "</telephony_lookup>\n");
-        assertEquals(expectedNetworks, telephonyLookup.getTelephonyNetworkFinder().getAll());
-
-        telephonyLookup = validate("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\">\n"
-                + "      " + unexpectedText
-                + "    </network>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertEquals(expectedNetworks, telephonyLookup.getTelephonyNetworkFinder().getAll());
-    }
-
-    @Test
-    public void xmlParsing_truncatedInput() throws Exception {
-        checkValidateThrowsParserException("<telephony_lookup>\n");
-
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n");
-
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n");
-
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "  </networks>\n");
-    }
-
-    @Test
-    public void validateDuplicateMccMnc() {
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" countryCode=\"gb\"/>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" countryCode=\"fr\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-    }
-
-    @Test
-    public void validateCountryCodeLowerCase() {
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" countryCode=\"GB\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-    }
-
-
-    @Test
-    public void getTelephonyNetworkFinder() throws Exception {
-        TelephonyLookup telephonyLookup = TelephonyLookup.createInstanceForTests(
-                "<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\" country=\"gb\"/>\n"
-                + "    <network mcc=\"234\" mnc=\"567\" country=\"fr\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-
-        TelephonyNetworkFinder telephonyNetworkFinder = telephonyLookup.getTelephonyNetworkFinder();
-        TelephonyNetwork expectedNetwork1 = TelephonyNetwork.create("123", "456", "gb");
-        TelephonyNetwork expectedNetwork2 = TelephonyNetwork.create("234", "567", "fr");
-        assertEquals(list(expectedNetwork1, expectedNetwork2), telephonyNetworkFinder.getAll());
-        assertEquals(expectedNetwork1, telephonyNetworkFinder.findNetworkByMccMnc("123", "456"));
-        assertEquals(expectedNetwork2, telephonyNetworkFinder.findNetworkByMccMnc("234", "567"));
-        assertNull(telephonyNetworkFinder.findNetworkByMccMnc("999", "999"));
-    }
-
-    @Test
-    public void xmlParsing_missingMccAttribute() throws Exception {
-        checkValidateThrowsParserException("<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mnc=\"456\" country=\"gb\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-    }
-
-    @Test
-    public void xmlParsing_missingMncAttribute() throws Exception {
-        TelephonyLookup telephonyLookup = TelephonyLookup.createInstanceForTests(
-                "<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" country=\"gb\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertNull(telephonyLookup.getTelephonyNetworkFinder());
-    }
-
-    @Test
-    public void xmlParsing_missingCountryCodeAttribute() throws Exception {
-        TelephonyLookup telephonyLookup = TelephonyLookup.createInstanceForTests(
-                "<telephony_lookup>\n"
-                + "  <networks>\n"
-                + "    <network mcc=\"123\" mnc=\"456\"/>\n"
-                + "  </networks>\n"
-                + "</telephony_lookup>\n");
-        assertNull(telephonyLookup.getTelephonyNetworkFinder());
-    }
-
-    private static void checkValidateThrowsParserException(String xml) {
-        try {
-            validate(xml);
-            fail();
-        } catch (IOException expected) {
-        }
-    }
-
-    private static TelephonyLookup validate(String xml) throws IOException {
-        TelephonyLookup telephonyLookup = TelephonyLookup.createInstanceForTests(xml);
-        telephonyLookup.validate();
-        return telephonyLookup;
-    }
-
-    private static void assertEmpty(Collection<?> collection) {
-        assertTrue("Expected empty:" + collection, collection.isEmpty());
-    }
-
-    private static <X> List<X> list(X... values) {
-        return Arrays.asList(values);
-    }
-
-    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/TelephonyNetworkFinderTest.java b/luni/src/test/java/libcore/libcore/timezone/TelephonyNetworkFinderTest.java
deleted file mode 100644
index 44dfc81..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/TelephonyNetworkFinderTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.timezone;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import libcore.timezone.TelephonyNetwork;
-import libcore.timezone.TelephonyNetworkFinder;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class TelephonyNetworkFinderTest {
-
-    @Test
-    public void testCreateAndLookups() {
-        TelephonyNetwork network = TelephonyNetwork.create("123", "456", "gb");
-        List<TelephonyNetwork> networkList = list(network);
-        TelephonyNetworkFinder finder = TelephonyNetworkFinder.create(networkList);
-        assertEquals(network, finder.findNetworkByMccMnc("123", "456"));
-        assertNull(finder.findNetworkByMccMnc("XXX", "XXX"));
-        assertNull(finder.findNetworkByMccMnc("123", "XXX"));
-        assertNull(finder.findNetworkByMccMnc("456", "123"));
-        assertNull(finder.findNetworkByMccMnc("111", "222"));
-        assertEquals(networkList, finder.getAll());
-    }
-
-    private static <X> List<X> list(X... values) {
-        return Arrays.asList(values);
-    }
-}
diff --git a/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java b/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java
deleted file mode 100644
index a74ba30..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/TimeZoneDataFilesTest.java
+++ /dev/null
@@ -1,76 +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.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_I18N_ROOT_ENV = "ANDROID_I18N_ROOT";
-    private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
-
-    @Test
-    public void expectedEnvironmentVariables() {
-        // These environment variables are required to locate data files used by libcore / ICU.
-        assertNotNull(System.getenv(ANDROID_DATA_ENV));
-        assertNotNull(System.getenv(ANDROID_TZDATA_ROOT_ENV));
-        assertNotNull(System.getenv(ANDROID_I18N_ROOT_ENV));
-    }
-
-    @Test
-    public void getTimeZoneFilePaths() {
-        String[] paths = TimeZoneDataFiles.getTimeZoneFilePaths("foo");
-        assertEquals(2, paths.length);
-
-        assertTrue(paths[0].startsWith(System.getenv(ANDROID_DATA_ENV)));
-        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"));
-    }
-
-    // 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.startsWith(System.getenv(ANDROID_DATA_ENV)));
-        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_I18N_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
deleted file mode 100644
index ef07371..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/TimeZoneFinderTest.java
+++ /dev/null
@@ -1,657 +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.timezone;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-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.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.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-public class TimeZoneFinderTest {
-
-    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", false /* defaultTimeZoneBoost */, 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 /* defaultTimeZoneBoost */, 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 device shipped without a file anywhere!
-        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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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", false /* defaultTimeZoneBoost */, 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_badCountryDefaultBoost() throws Exception {
-        checkValidateThrowsParserException("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" defaultBoost=\"nope\""
-                + "everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-    }
-
-    @Test
-    public void xmlParsing_countryDefaultBoost() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "    <country code=\"gb\" default=\"Europe/London\" defaultBoost=\"y\""
-                + "everutc=\"y\">\n"
-                + "      <id>Europe/London</id>\n"
-                + "    </country>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        CountryTimeZones countryTimeZones = finder.lookupCountryTimeZones("gb");
-        assertTrue(countryTimeZones.isDefaultTimeZoneBoosted());
-    }
-
-    @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 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",
-                false /* defaultTimeZoneBoost */, true, timeZoneMappings("Europe/London"), "test");
-        CountryTimeZones expectedFr = CountryTimeZones.createValidated("fr", "Europe/Paris",
-                false /* defaultTimeZoneBoost */, 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 lookupCountryTimeZones_caseInsensitive() 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");
-        CountryTimeZones expectedCountryTimeZones = CountryTimeZones.createValidated(
-                "gb", "Europe/London", false /* defaultTimeZoneBoost */, true /* everUsesUtc */,
-                timeZoneMappings("Europe/London"), "test");
-
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("gb"));
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("GB"));
-        assertEquals(expectedCountryTimeZones, finder.lookupCountryTimeZones("Gb"));
-    }
-
-    @Test
-    public void lookupCountryTimeZones_unknownCountryReturnsNull() throws Exception {
-        TimeZoneFinder finder = validate("<timezones ianaversion=\"2017b\">\n"
-                + "  <countryzones>\n"
-                + "  </countryzones>\n"
-                + "</timezones>\n");
-        assertNull(finder.lookupCountryTimeZones("gb"));
-    }
-
-    @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");
-        assertNull(finder.getIanaVersion());
-
-        assertNotNull(finder.lookupCountryTimeZones("gb"));
-    }
-
-    @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 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 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
deleted file mode 100644
index a653301..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/TzDataSetVersionTest.java
+++ /dev/null
@@ -1,105 +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.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.getFormatMajorVersion());
-        assertEquals(2, distroVersion.getFormatMinorVersion());
-        assertEquals(VALID_RULES_VERSION, distroVersion.getRulesVersion());
-        assertEquals(3, distroVersion.getRevision());
-    }
-
-    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
deleted file mode 100644
index 48eb286..0000000
--- a/luni/src/test/java/libcore/libcore/timezone/ZoneInfoDbTest.java
+++ /dev/null
@@ -1,264 +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.timezone;
-
-import java.io.File;
-import java.io.FileOutputStream;
-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.SIZEOF_INDEX_ENTRY;
-
-public class ZoneInfoDbTest extends junit.framework.TestCase {
-
-  // The base tzdata file, always present on a device.
-  private static final String TZDATA_FILE =
-          TimeZoneDataFiles.getTimeZoneModuleTzFile(ZoneInfoDb.TZDATA_FILE_NAME);
-
-  // An empty override file should fall back to the default file.
-  public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
-    String emptyFilePath = makeEmptyFile().getPath();
-    try (ZoneInfoDb data = ZoneInfoDb.loadTzData(TZDATA_FILE);
-         ZoneInfoDb dataWithEmptyOverride =
-                 ZoneInfoDb.loadTzDataWithFallback(emptyFilePath, 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 data = ZoneInfoDb.loadTzData(TZDATA_FILE);
-         ZoneInfoDb dataWithCorruptOverride =
-                 ZoneInfoDb.loadTzDataWithFallback(corruptFilePath, 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 data = ZoneInfoDb.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(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 dataWithOverride =
-              ZoneInfoDb.loadTzDataWithFallback(goodFile.getPath(), TZDATA_FILE);
-         ZoneInfoDb data = ZoneInfoDb.loadTzData(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(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.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.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.loadTzData(testFile.getPath()));
-    } finally {
-      testFile.delete();
-    }
-  }
-
-  // Confirms any caching that exists correctly handles TimeZone mutability.
-  public void testMakeTimeZone_timeZoneMutability() throws Exception {
-    try (ZoneInfoDb data = ZoneInfoDb.loadTzData(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 data = ZoneInfoDb.loadTzData(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 data = ZoneInfoDb.loadTzData(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/HexEncodingTest.java b/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
index 800928f..867932b 100644
--- a/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
+++ b/luni/src/test/java/libcore/libcore/util/HexEncodingTest.java
@@ -64,6 +64,7 @@
 
       assertArraysEqual(encodedUpper.toCharArray(), encode(bytes));
       assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, true /* upperCase */));
+      assertArraysEqual(encodedUpper.toCharArray(), encode(bytes, 0, bytes.length));
       assertArraysEqual(encodedLower.toCharArray(), encode(bytes, false /* upperCase */));
 
       assertArraysEqual(bytes, decode(encode(bytes), false /* allowSingleChar */));
diff --git a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
index 54c8876..9190452 100644
--- a/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
+++ b/luni/src/test/java/libcore/libcore/util/NativeAllocationRegistryTest.java
@@ -61,11 +61,11 @@
         assertEquals("Native bytes already allocated", 0, nativeBytes);
         long max = Runtime.getRuntime().maxMemory();
         long total = Runtime.getRuntime().totalMemory();
-        int size = 1024*1024;
-        final int nativeSize = size/2;
-        int javaSize = size/2;
-        int expectedMaxNumAllocations = (int)(max-total)/javaSize;
-        int numSavedAllocations = expectedMaxNumAllocations/2;
+        int size = 1024 * 1024;
+        final int nativeSize = size / 2;
+        int javaSize = size / 2;
+        int expectedMaxNumAllocations = (int)(max-total) / javaSize;
+        int numSavedAllocations = expectedMaxNumAllocations / 2;
         Allocation[] saved = new Allocation[numSavedAllocations];
 
         NativeAllocationRegistry registry = null;
@@ -90,21 +90,31 @@
             alloc.nativeAllocation = doNativeAllocation(nativeSize);
             registry.registerNativeAllocation(alloc, alloc.nativeAllocation);
 
-            saved[i%numSavedAllocations] = alloc;
+            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.
-        // Since native and java objects have the same size, and we can only have max
-        // Java bytes in use, there should be no more than max native bytes in use,
-        // once all enqueued deallocations have been processed. First make sure
-        // that the ReferenceQueueDaemon has processed all pending requests, and then
-        // check.
+        // 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.
+        //
+        // Since native and java objects have the same size, and we can only have max Java bytes
+        // in use, there should ideally be no more than max native bytes in use, once all enqueued
+        // deallocations have been processed. We call runFinalization() to make sure that the
+        // ReferenceQueueDaemon has processed all pending requests, and then check.
+        // (runFinalization() isn't documented to guarantee this, but it waits for a sentinel
+        // object to make it all the way through the pending reference queue, and hence has that
+        // effect.)
+        //
+        // However the garbage collector enqueues references asynchronously, by enqueuing
+        // another heap task. If the GC runs before we finish our allocation, but reference
+        // enqueueing is delayed, and runFinalization() runs between the time the GC reclaims
+        // memory and the references are enqueued, then runFinalization() may complete
+        // immediately, and further allocation may have occurred between the GC and the invocation
+        // of runFinalization(). Thus, under unlikely conditions, we may see up to twice as much
+        // native memory as the Java heap, and that's the actual condition we test.
         System.runFinalization();
         nativeBytes = getNumNativeBytesAllocated();
         assertTrue("Excessive native bytes still allocated (" + nativeBytes + ")"
-                + " given max memory of (" + max + ")", nativeBytes <= max);
+                + " given max memory of (" + max + ")", nativeBytes <= 2 * max);
         // Check that the array is fully populated, and sufficiently many native bytes
         // are live.
         long nativeReachableBytes = numSavedAllocations * nativeSize;
@@ -171,16 +181,32 @@
         Runtime.getRuntime().gc();
     }
 
+    public void testApplyFreeFunction() {
+        if (isNativeBridgedABI()) {
+            // See the explanation in testNativeAllocation.
+            System.logI("Skipping test for native bridged ABI");
+            return;
+        }
+        long size = 1234;
+        long nativePtr = doNativeAllocation(size);
+        long numBytesAllocatedBeforeFree = getNumNativeBytesAllocated();
+
+        // Applying the free function should cause the native finalizer to run.
+        NativeAllocationRegistry.applyFreeFunction(getNativeFinalizer(), nativePtr);
+        long numBytesAllocatedAfterFree = getNumNativeBytesAllocated();
+        assertEquals(numBytesAllocatedBeforeFree - size, numBytesAllocatedAfterFree);
+    }
+
     public void testNullArguments() {
         final NativeAllocationRegistry registry
             = new NativeAllocationRegistry(classLoader, getNativeFinalizer(), 1024);
-        final long dummyNativePtr = 0x1;
+        final long fakeNativePtr = 0x1;
         final Object referent = new Object();
 
         // referent should not be null
         assertThrowsIllegalArgumentException(new Runnable() {
             public void run() {
-                registry.registerNativeAllocation(null, dummyNativePtr);
+                registry.registerNativeAllocation(null, fakeNativePtr);
             }
         });
 
diff --git a/luni/src/test/java/libcore/libcore/util/SerializationTester.java b/luni/src/test/java/libcore/libcore/util/SerializationTester.java
index 48a58b4..4f8b357 100644
--- a/luni/src/test/java/libcore/libcore/util/SerializationTester.java
+++ b/luni/src/test/java/libcore/libcore/util/SerializationTester.java
@@ -69,7 +69,7 @@
             assertTrue("User-constructed value doesn't equal itself, reserialized",
                     equals(value, reserialized));
 
-            // just a sanity check! if this fails, verify() is probably broken
+            // just a confidence check! if this fails, verify() is probably broken
             verify(value);
             verify(deserialized);
             verify(reserialized);
diff --git a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
index 8b9715f..31da1f1 100644
--- a/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
+++ b/luni/src/test/java/libcore/libcore/util/ZoneInfoTest.java
@@ -15,19 +15,14 @@
  */
 package libcore.libcore.util;
 
+import com.android.i18n.timezone.ZoneInfoData;
 import junit.framework.TestCase;
 
-import java.io.IOException;
 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.timezone.ZoneInfoDb;
-import libcore.timezone.testing.ZoneInfoTestHelper;
+import java.util.TimeZone;
+
 import libcore.util.ZoneInfo;
 
 /**
@@ -36,586 +31,6 @@
 public class ZoneInfoTest extends TestCase {
 
   /**
-   * Checks that a {@link ZoneInfo} cannot be created without any types.
-   */
-  public void testMakeTimeZone_NoTypes() throws Exception {
-    long[][] transitions = {};
-    int[][] types = {};
-    try {
-      createZoneInfo(transitions, types);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  /**
-   * Checks that a {@link ZoneInfo} can be created with one type and no transitions.
-   */
-  public void testMakeTimeZone_OneType_NoTransitions() throws Exception {
-    long[][] transitions = {};
-    int[][] types = {
-        { 4800, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types);
-
-    // If there are no transitions then the offset should be constant irrespective of the time.
-    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());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-
-    // The raw offset should be the offset of the first type.
-    assertRawOffset(zoneInfo, offsetFromSeconds(4800));
-  }
-
-  /**
-   * Checks that a {@link ZoneInfo} can be created with one non-DST transition.
-   */
-  public void testReadTimeZone_OneNonDstTransition() throws Exception {
-    long[][] transitions = {
-        { 0, 0 }
-    };
-    int[][] types = {
-        { 3600, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types);
-
-    // Any time before the first transition is assumed to use the first standard transition.
-    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());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-
-    // The raw offset should be the offset of the first type.
-    assertRawOffset(zoneInfo, offsetFromSeconds(3600));
-  }
-
-  /**
-   * Checks that a {@link ZoneInfo} cannot be created with one DST but no non-DSTs transitions.
-   */
-  public void testReadTimeZone_OneDstTransition() throws Exception {
-    long[][] transitions = {
-        { 0, 0 }
-    };
-    int[][] types = {
-        { 3600, 1 }
-    };
-    try {
-      createZoneInfo(transitions, types);
-      fail("Did not detect no non-DST transitions");
-    } catch (IllegalStateException expected) {
-    }
-  }
-
-  /**
-   * Checks to make sure that rounding the time from milliseconds to seconds does not cause issues
-   * around the boundary of negative transitions.
-   */
-  public void testReadTimeZone_NegativeTransition() throws Exception {
-    long[][] transitions = {
-        { -2000, 0 },
-        { -5, 1 },
-        { 0, 2 },
-    };
-    int[][] types = {
-        { 1800, 0 },
-        { 3600, 1 },
-        { 5400, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types);
-    Instant transitionTime = timeFromSeconds(-5);
-
-    // Even a millisecond before a transition means that the transition is not active.
-    Instant beforeTransitionTime = transitionTime.minusMillis(1);
-    assertOffsetAt(zoneInfo, offsetFromSeconds(1800), beforeTransitionTime);
-    assertInDaylightTime(zoneInfo, beforeTransitionTime, false);
-
-    // A time equal to the transition point activates the transition.
-    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), transitionTime);
-    assertInDaylightTime(zoneInfo, transitionTime, true);
-
-    // A time after the transition point but before the next activates the transition.
-    Instant afterTransitionTime = transitionTime.plusMillis(1);
-    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), afterTransitionTime);
-    assertInDaylightTime(zoneInfo, afterTransitionTime, true);
-
-    assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-    assertRawOffset(zoneInfo, offsetFromSeconds(5400));
-  }
-
-  /**
-   * Checks to make sure that rounding the time from milliseconds to seconds does not cause issues
-   * around the boundary of positive transitions.
-   */
-  public void testReadTimeZone_PositiveTransition() throws Exception {
-    long[][] transitions = {
-        { 0, 0 },
-        { 5, 1 },
-        { 2000, 2 },
-    };
-    int[][] types = {
-        { 1800, 0 },
-        { 3600, 1 },
-        { 5400, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types);
-
-    Instant transitionTime = timeFromSeconds(5);
-
-    // Even a millisecond before a transition means that the transition is not active.
-    Instant beforeTransitionTime = transitionTime.minusMillis(1);
-    assertOffsetAt(zoneInfo, offsetFromSeconds(1800), beforeTransitionTime);
-    assertInDaylightTime(zoneInfo, beforeTransitionTime, false);
-
-    // A time equal to the transition point activates the transition.
-    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), transitionTime);
-    assertInDaylightTime(zoneInfo, transitionTime, true);
-
-    // A time after the transition point but before the next activates the transition.
-    Instant afterTransitionTime = transitionTime.plusMillis(1);
-    assertOffsetAt(zoneInfo, offsetFromSeconds(3600), afterTransitionTime);
-    assertInDaylightTime(zoneInfo, afterTransitionTime, true);
-
-    assertFalse("Doesn't use DST", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-    assertRawOffset(zoneInfo, offsetFromSeconds(5400));
-  }
-
-  /**
-   * Checks that creating a {@link ZoneInfo} with future DST transitions but no past DST
-   * transitions where the transition times are negative is not affected by rounding issues.
-   */
-  public void testReadTimeZone_HasFutureDST_NoPastDST_NegativeTransitions() throws Exception {
-    long[][] transitions = {
-        { -2000, 0 },
-        { -500, 1 },
-        { -100, 2 },
-    };
-    int[][] types = {
-        { 1800, 0 },
-        { 3600, 0 },
-        { 5400, 1 }
-    };
-    // 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
-    Duration expectedDSTSavings = offsetFromSeconds(5400 - 3600);
-
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-700));
-
-    assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    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, timeFromSeconds(-100).minusMillis(5));
-
-    assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, expectedDSTSavings);
-  }
-
-  /**
-   * Checks that creating a {@link ZoneInfo} with future DST transitions but no past DST
-   * transitions where the transition times are positive is not affected by rounding issues.
-   */
-  public void testReadTimeZone_HasFutureDST_NoPastDST_PositiveTransitions() throws Exception {
-    long[][] transitions = {
-        { 4000, 0 },
-        { 5500, 1 },
-        { 6000, 2 },
-    };
-    int[][] types = {
-        { 1800, 0 },
-        { 3600, 0 },
-        { 7200, 1 }
-    };
-    // 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
-    Duration expectedDSTSavings = offsetFromSeconds(7200 - 3600);
-
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(4500) /* currentTime */);
-
-    assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    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, timeFromSeconds(6000).minusMillis(5));
-
-    assertTrue("Should use DST but doesn't", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, expectedDSTSavings);
-  }
-
-  /**
-   * Checks that creating a {@link ZoneInfo} with past DST transitions but no future DST
-   * transitions where the transition times are negative is not affected by rounding issues.
-   */
-  public void testReadTimeZone_HasPastDST_NoFutureDST_NegativeTransitions() throws Exception {
-    long[][] transitions = {
-        { -5000, 0 },
-        { -2000, 1 },
-        { -500, 0 },
-        { 0, 2 },
-    };
-    int[][] types = {
-        { 3600, 0 },
-        { 1800, 1 },
-        { 5400, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(-1) /* currentTime */);
-
-    assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    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, timeFromSeconds(-2000).plusMillis(5));
-
-    assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-  }
-
-  /**
-   * Checks that creating a {@link ZoneInfo} with past DST transitions but no future DST
-   * transitions where the transition times are positive is not affected by rounding issues.
-   */
-  public void testReadTimeZone_HasPastDST_NoFutureDST_PositiveTransitions() throws Exception {
-    long[][] transitions = {
-        { 1000, 0 },
-        { 4000, 1 },
-        { 5500, 0 },
-        { 6000, 2 },
-    };
-    int[][] types = {
-        { 3600, 0 },
-        { 1800, 1 },
-        { 5400, 0 }
-    };
-    ZoneInfo zoneInfo = createZoneInfo(transitions, types, timeFromSeconds(4700));
-
-    assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    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, timeFromSeconds(4000).plusMillis(5));
-
-    assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-  }
-
-  /**
-   * TimeZone APIs use Java long times in millis.
-   *
-   * <p>Android has historically mishandled the lookup of offset for times before Integer.MIN_VALUE
-   * seconds for various reasons. 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 seconds with a java int.
-    Instant before32BitTime = timeFromSeconds(Integer.MIN_VALUE).minusMillis(1);
-
-    // Times around the 32-bit seconds minimum.
-    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 },
-    };
-
-    // Simulates a zone with a single transition.
-    {
-      long[][] 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);
-    }
-
-    // Simulation a zone where there is an explicit transition at Integer.MIN_VALUE seconds. This
-    // used to be common when Android used 32-bit data from the TZif file.
-    {
-      long[][] transitions = {
-              { Integer.MIN_VALUE, 1 /* type 1 */ },
-              { 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 seconds.
-   */
-  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 a zone where there is no explicit transition at Integer.MAX_VALUE
-    // seconds.
-    {
-      long[][] transitions = {
-              { 1000, 0 },
-              { 2000, 1 },
-      };
-      ZoneInfo oldZoneInfo = createZoneInfo(transitions, types, currentTime);
-      assertOffsetAt(oldZoneInfo, expectedLateOffset, timesToCheck);
-    }
-
-    // Create a simulation of a zone where there is an explicit transition at Integer.MAX_VALUE
-    // seconds.
-    {
-      long[][] transitions = {
-              { 1000, 0 },
-              { 2000, 1 },
-              { Integer.MAX_VALUE, 1}, // The extra transition.
-      };
-      ZoneInfo newZoneInfo = createZoneInfo(transitions, types, currentTime);
-      assertOffsetAt(newZoneInfo, expectedLateOffset, timesToCheck);
-    }
-  }
-
-  /**
-   * Checks to make sure that ZoneInfo can handle up to 256 types.
-   */
-  public void testReadTimeZone_MaxTypeCount() throws Exception {
-    long[][] transitions = {
-        { -2000, 255 },
-    };
-    // Create 256 types, each with zero offset and without DST except the last, which is offset by
-    // one hour but also without DST.
-    int[][] types = new int[256][];
-    Arrays.fill(types, new int[2]);
-    types[255] = new int[] { 3600, 0 };
-
-    ZoneInfo zoneInfo = createZoneInfo(getName(), transitions, types,
-            timeFromSeconds(Integer.MIN_VALUE));
-
-    assertFalse("Shouldn't use DST but does", zoneInfo.useDaylightTime());
-    assertDSTSavings(zoneInfo, offsetFromSeconds(0));
-
-    // Make sure that WallTime works properly with a ZoneInfo with 256 types.
-    ZoneInfo.WallTime wallTime = new ZoneInfo.WallTime();
-    wallTime.localtime(0, zoneInfo);
-    wallTime.mktime(zoneInfo);
-  }
-
-  /**
-   * Create an instance for every available time zone for which we have data to ensure that they
-   * can all be handled correctly.
-   *
-   * <p>This is to ensure that ZoneInfo can read all time zone data without failing, it doesn't
-   * check that it reads it correctly or that the data itself is correct. This is a sanity test
-   * to ensure that any additional checks added to the code that reads the data source and
-   * creates the {@link ZoneInfo} instances does not prevent any of the time zones being loaded.
-   */
-  public void testReadTimeZone_All() throws Exception {
-    ZoneInfoDb instance = ZoneInfoDb.getInstance();
-    String[] availableIDs = instance.getAvailableIDs();
-    Arrays.sort(availableIDs);
-    for (String id : availableIDs) {
-      BufferIterator bufferIterator = instance.getBufferIterator(id);
-
-      // Create a ZoneInfo at the earliest possible time to allow us to use the
-      // useDaylightTime() method to check whether it ever has or ever will support daylight
-      // savings time.
-      ZoneInfo zoneInfo = ZoneInfo.readTimeZone(id, bufferIterator, Long.MIN_VALUE);
-      assertNotNull("TimeZone " + id + " was not created", zoneInfo);
-      assertEquals(id, zoneInfo.getID());
-    }
-  }
-
-  public void testReadTimeZone_Valid() throws Exception {
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid();
-    assertNotNull(createZoneInfo(getName(), Instant.now(), builder.build()));
-  }
-
-  public void testReadTimeZone_BadMagic() {
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setMagic(0xdeadbeef); // Bad magic.
-    try {
-      createZoneInfo(getName(), Instant.now(), builder.build());
-      fail();
-    } catch (IOException expected) {}
-  }
-
-  /**
-   * Checks to make sure that ZoneInfo rejects more than 256 types.
-   */
-  public void testReadTimeZone_TooManyTypes() {
-    int typeCount = 257; // Max types allowed is 256
-    int transitionCount = 5;
-    long[][] transitions = createTransitions(transitionCount, typeCount);
-    int[][] types = createTypes(typeCount);
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setTransitionsAndTypes(transitions, types);
-    byte[] bytes = builder.build();
-    try {
-      createZoneInfo(getName(), Instant.now(), bytes);
-      fail("Did not detect too many types");
-    } catch (IOException expected) {
-    }
-  }
-
-  /**
-   * Checks to make sure that ZoneInfo rejects more than 2000 transitions.
-   */
-  public void testReadTimeZone_TooManyTransitions() {
-    int typeCount = 5;
-    int transitionCount = 2001; // Max transitions allowed is 2000.
-    long[][] transitions = createTransitions(transitionCount, typeCount);
-    int[][] types = createTypes(typeCount);
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setTransitionsAndTypes(transitions, types);
-    byte[] bytes = builder.build();
-    try {
-      createZoneInfo(getName(), Instant.now(), bytes);
-      fail("Did not detect too many transitions");
-    } catch (IOException expected) {
-    }
-  }
-
-  public void testReadTimeZone_TransitionsNotSorted() {
-    long[][] transitions = {
-            { 1000, 0 },
-            { 3000, 1 }, // Out of transition order.
-            { 2000, 0 },
-    };
-    int[][] types = {
-            { 3600, 0 },
-            { 1800, 1 },
-    };
-
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setTransitionsAndTypes(transitions, types);
-
-    byte[] bytes = builder.build();
-    try {
-      createZoneInfo(getName(), Instant.now(), bytes);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  public void testReadTimeZone_InvalidTypeIndex() {
-    long[][] transitions = {
-            { 1000, 0 },
-            { 2000, 2 }, // Invalid type index - only 0 and 1 defined below.
-            { 3000, 0 },
-    };
-    int[][] types = {
-            { 3600, 0 },
-            { 1800, 1 },
-    };
-
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setTransitionsAndTypes(transitions, types);
-
-    byte[] bytes = builder.build();
-    try {
-      createZoneInfo(getName(), Instant.now(), bytes);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  public void testReadTimeZone_InvalidIsDst() {
-    long[][] transitions = {
-            { 1000, 0 },
-            { 2000, 1 },
-            { 3000, 0 },
-    };
-    int[][] types = {
-            { 3600, 0 },
-            { 1800, 2 }, // Invalid isDst - must be 0 or 1
-    };
-
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .initializeToValid()
-                    .setTransitionsAndTypes(transitions, types);
-
-    byte[] bytes = builder.build();
-    try {
-      createZoneInfo(getName(), Instant.now(), bytes);
-      fail();
-    } catch (IOException expected) {
-    }
-  }
-
-  /**
    * Checks that we can read the serialized form of a {@link ZoneInfo} created in pre-OpenJDK
    * AOSP.
    *
@@ -634,19 +49,12 @@
       zoneInfoRead = (ZoneInfo) object;
     }
 
-    long[][] transitions = {
-        { -5000, 0 },
-        { -2000, 1 },
-        { -500, 0 },
-        { 0, 2 },
-    };
-    int[][] types = {
-        { 3600, 0 },
-        { 1800, 1 },
-        { 5400, 0 }
-    };
-    ZoneInfo zoneInfoCreated = createZoneInfo(
-            "test", transitions, types, timeFromSeconds(-1));
+    long[] transitions = { -5000, -2000, -500, 0 };
+    byte[] types =       { 0,     1,     0,    2 }; // align each entry with transitions
+    int[] offsets =    { 3600,  1800, 5400  };
+    boolean[] isDsts = { false, true, false }; // align each entry with offsets
+    ZoneInfo zoneInfoCreated = createZoneInfo("TimeZone for 'test'", transitions, types, offsets,
+            isDsts, timeFromSeconds(-1));
 
     assertEquals("Read ZoneInfo does not match created one", zoneInfoCreated, zoneInfoRead);
     assertEquals("useDaylightTime() mismatch",
@@ -655,23 +63,16 @@
         zoneInfoCreated.getDSTSavings(), zoneInfoRead.getDSTSavings());
   }
 
-  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()));
+  /**
+   * Test consistency among DST-related APIs supported by ZoneInfo.
+   *
+   * This test may use TimeZone APIs only, the implementation comes from ZoneInfo.
+   */
+  public void testUseDaylightTime_consistency() {
+    for (String tzId : TimeZone.getAvailableIDs()) {
+      TimeZone tz = TimeZone.getTimeZone(tzId);
+      assertEquals("TimeZone API does not report consistently in this zone:" + tzId,
+              tz.useDaylightTime(), tz.getDSTSavings() != 0);
     }
   }
 
@@ -679,148 +80,9 @@
     return Instant.ofEpochSecond(timeInSeconds);
   }
 
-  private static long timeToSeconds(Instant time) {
-    return time.getEpochSecond();
-  }
-
-  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(long[][] transitions, int[][] types)
-      throws Exception {
-    return createZoneInfo(getName(), transitions, types, Instant.now());
-  }
-
-  private ZoneInfo createZoneInfo(long[][] transitions, int[][] types, Instant currentTime)
-          throws Exception {
-    return createZoneInfo(getName(), transitions, types, currentTime);
-  }
-
-  private ZoneInfo createZoneInfo(String name, long[][] transitions, int[][] types,
-          Instant currentTime) throws Exception {
-
-    ZoneInfoTestHelper.ZicDataBuilder builder =
-            new ZoneInfoTestHelper.ZicDataBuilder()
-                    .setTransitionsAndTypes(transitions, types);
-    return createZoneInfo(name, currentTime, builder.build());
-  }
-
-  private static ZoneInfo createZoneInfo(String name, Instant currentTime, byte[] bytes)
-          throws IOException {
-    ByteBufferIterator bufferIterator = new ByteBufferIterator(ByteBuffer.wrap(bytes));
-    return ZoneInfo.readTimeZone(
-            "TimeZone for '" + name + "'", bufferIterator, currentTime.toEpochMilli());
-  }
-
-  /**
-   * Creates {@code typeCount} "types" for use with
-   * {@link ZoneInfoTestHelper.ZicDataBuilder#setTypes(int[][])} and related methods. Each type is
-   * given an arbitrary offset and "isDst" value.
-   */
-  private static int[][] createTypes(int typeCount) {
-    int[][] types = new int[typeCount][2];
-    for (int i = 0; i < typeCount; i++) {
-      // [0] holds the offset from UTC in seconds.
-      types[i][0] = typeCount;
-      // [1] holds isDst: 0 == STD, 1 == DST
-      types[i][1] = typeCount % 2;
-    }
-    return types;
-  }
-
-  /**
-   * Creates {@code transitionCount} "transition pairs" for use with
-   * {@link ZoneInfoTestHelper.ZicDataBuilder#setTransitions(long[][])} and related methods. Each
-   * transition is given an arbitrary (but increasing) time referencing an arbitrary type.
-   */
-  private static long[][] createTransitions(int transitionCount, int typeCount) {
-    long[][] transitions = new long[transitionCount][2];
-    for (int i = 0; i < transitionCount; i++) {
-      // [0] holds the transition time.
-      transitions[i][0] = (i * 3600) + 100;
-      // [1] holds the type index to use. Must be > 0 and < typeCount to be valid.
-      transitions[i][1] = i % typeCount;
-    }
-    return transitions;
-  }
-
-  /**
-   * A {@link BufferIterator} that wraps a {@link ByteBuffer}.
-   */
-  private static class ByteBufferIterator extends BufferIterator {
-
-    private final ByteBuffer buffer;
-
-    public ByteBufferIterator(ByteBuffer buffer) {
-      this.buffer = buffer;
-    }
-
-    @Override
-    public void seek(int offset) {
-      buffer.position(offset);
-    }
-
-    @Override
-    public void skip(int byteCount) {
-      buffer.position(buffer.position() + byteCount);
-    }
-
-    @Override
-    public int pos() {
-      return buffer.position();
-    }
-
-    @Override
-    public void readByteArray(byte[] bytes, int arrayOffset, int byteCount) {
-      buffer.get(bytes, arrayOffset, byteCount);
-    }
-
-    @Override
-    public byte readByte() {
-      return buffer.get();
-    }
-
-    @Override
-    public int readInt() {
-      int value = buffer.asIntBuffer().get();
-      // Using a separate view does not update the position of this buffer so do it
-      // explicitly.
-      skip(Integer.BYTES);
-      return value;
-    }
-
-    @Override
-    public void readIntArray(int[] ints, int arrayOffset, int intCount) {
-      buffer.asIntBuffer().get(ints, arrayOffset, intCount);
-      // Using a separate view does not update the position of this buffer so do it
-      // explicitly.
-      skip(Integer.BYTES * intCount);
-    }
-
-    @Override
-    public void readLongArray(long[] longs, int arrayOffset, int longCount) {
-      buffer.asLongBuffer().get(longs, arrayOffset, longCount);
-      // Using a separate view does not update the position of this buffer so do it
-      // explicitly.
-      skip(Long.BYTES * longCount);
-    }
-
-    @Override
-    public short readShort() {
-      short value = buffer.asShortBuffer().get();
-      // Using a separate view does not update the position of this buffer so do it
-      // explicitly.
-      skip(Short.BYTES);
-      return value;
-    }
+  private ZoneInfo createZoneInfo(String id, long[] transitions, byte[] types, int[] offsets,
+          boolean[] isDsts, Instant currentTime) {
+    ZoneInfoData data = ZoneInfoData.createInstance(id, transitions, types, offsets, isDsts);
+    return ZoneInfo.createZoneInfo(data, currentTime.toEpochMilli());
   }
 }
diff --git a/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java b/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java
index 8876671..45c857f 100644
--- a/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java
+++ b/luni/src/test/java/libcore/sun/security/jca/ProvidersTest.java
@@ -27,15 +27,25 @@
 import java.security.AlgorithmParameters;
 import java.security.GeneralSecurityException;
 import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.Security;
 import java.security.Signature;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+import javax.crypto.Cipher;
+import javax.crypto.KeyAgreement;
 import javax.crypto.KeyGenerator;
 import javax.crypto.Mac;
+import javax.crypto.SecretKeyFactory;
 
 import sun.security.jca.Providers;
 
@@ -66,65 +76,6 @@
     // getInstance calls that result in requests to Conscrypt
     private static final List<Algorithm> CONSCRYPT_ALGORITHMS = new ArrayList<>();
     static {
-        // A concrete algorithm, provider by name
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return Signature.getInstance("sha224withrsa", "BC");
-            }
-        });
-        // A concrete algorithm, provider by instance
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return KeyFactory.getInstance("EC", Security.getProvider("BC"));
-            }
-        });
-        // An alias for another algorithm, provider by name
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return Signature.getInstance("MD5withRSAEncryption", "BC");
-            }
-        });
-        // An alias for another algorithm, provider by instance
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return KeyGenerator.getInstance("HMAC-MD5", Security.getProvider("BC"));
-            }
-        });
-        // An alias with unusual characters, provider by name
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return Mac.getInstance("Hmac/sha256", "BC");
-            }
-        });
-        // An alias with unusual characters, provider by instance
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                return Signature.getInstance("SHA384/rsA", Security.getProvider("BC"));
-            }
-        });
-        // An alias by OID, provider by name
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                // OID for SHA-256
-                return MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC");
-            }
-        });
-        // An alias by OID, provider by instance
-        BC_ALGORITHMS.add(new Algorithm() {
-            @Override
-            public Object getInstance() throws GeneralSecurityException {
-                // OID for AES-128
-                return AlgorithmParameters.getInstance("2.16.840.1.101.3.4.1.2",
-                        Security.getProvider("BC"));
-            }
-        });
         // All the same algorithms as for BC, but with no provider, which should produce
         // the Conscrypt implementation
         CONSCRYPT_ALGORITHMS.add(new Algorithm() {
@@ -179,6 +130,194 @@
         });
     }
 
+    private static final Set<String> REMOVED_BC_ALGORITHMS = new HashSet<String>();
+    static {
+        REMOVED_BC_ALGORITHMS.addAll(Arrays.asList(
+                "ALGORITHMPARAMETERS.1.2.840.113549.3.7",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.2",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.22",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.26",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.42",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.46",
+                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.6",
+                "ALGORITHMPARAMETERS.AES",
+                "ALGORITHMPARAMETERS.DESEDE",
+                "ALGORITHMPARAMETERS.EC",
+                "ALGORITHMPARAMETERS.GCM",
+                "ALGORITHMPARAMETERS.OAEP",
+                "ALGORITHMPARAMETERS.TDEA",
+                "CERTIFICATEFACTORY.X.509",
+                "CERTIFICATEFACTORY.X509",
+                // List of Ciphers produced by ProviderOverlap:
+                "CIPHER.1.2.840.113549.3.4",
+                "CIPHER.2.16.840.1.101.3.4.1.26",
+                "CIPHER.2.16.840.1.101.3.4.1.46",
+                "CIPHER.2.16.840.1.101.3.4.1.6",
+                "CIPHER.AES/GCM/NOPADDING",
+                "CIPHER.ARC4",
+                "CIPHER.ARCFOUR",
+                "CIPHER.OID.1.2.840.113549.3.4",
+                "CIPHER.RC4",
+                // End of Ciphers produced by ProviderOverlap
+                // Additional ciphers transformations that will resolve to the same things as
+                // the automatically-produced overlap due to the Cipher transformation rules.
+                // These have been added manually.
+                "CIPHER.ARC4/ECB/NOPADDING",
+                "CIPHER.ARC4/NONE/NOPADDING",
+                "CIPHER.ARCFOUR/ECB/NOPADDING",
+                "CIPHER.ARCFOUR/NONE/NOPADDING",
+                "CIPHER.RC4/ECB/NOPADDING",
+                "CIPHER.RC4/NONE/NOPADDING",
+                // End of additional Ciphers
+                "KEYAGREEMENT.ECDH",
+                "KEYFACTORY.1.2.840.10045.2.1",
+                "KEYFACTORY.1.2.840.113549.1.1.1",
+                "KEYFACTORY.1.2.840.113549.1.1.7",
+                "KEYFACTORY.1.3.133.16.840.63.0.2",
+                "KEYFACTORY.2.5.8.1.1",
+                "KEYFACTORY.EC",
+                "KEYGENERATOR.1.2.840.113549.2.10",
+                "KEYGENERATOR.1.2.840.113549.2.11",
+                "KEYGENERATOR.1.2.840.113549.2.7",
+                "KEYGENERATOR.1.2.840.113549.2.8",
+                "KEYGENERATOR.1.2.840.113549.2.9",
+                "KEYGENERATOR.1.3.6.1.5.5.8.1.1",
+                "KEYGENERATOR.1.3.6.1.5.5.8.1.2",
+                "KEYGENERATOR.2.16.840.1.101.3.4.2.1",
+                "KEYGENERATOR.AES",
+                "KEYGENERATOR.DESEDE",
+                "KEYGENERATOR.HMAC-MD5",
+                "KEYGENERATOR.HMAC-SHA1",
+                "KEYGENERATOR.HMAC-SHA224",
+                "KEYGENERATOR.HMAC-SHA256",
+                "KEYGENERATOR.HMAC-SHA384",
+                "KEYGENERATOR.HMAC-SHA512",
+                "KEYGENERATOR.HMAC/MD5",
+                "KEYGENERATOR.HMAC/SHA1",
+                "KEYGENERATOR.HMAC/SHA224",
+                "KEYGENERATOR.HMAC/SHA256",
+                "KEYGENERATOR.HMAC/SHA384",
+                "KEYGENERATOR.HMAC/SHA512",
+                "KEYGENERATOR.HMACMD5",
+                "KEYGENERATOR.HMACSHA1",
+                "KEYGENERATOR.HMACSHA224",
+                "KEYGENERATOR.HMACSHA256",
+                "KEYGENERATOR.HMACSHA384",
+                "KEYGENERATOR.HMACSHA512",
+                "KEYGENERATOR.TDEA",
+                "KEYPAIRGENERATOR.1.2.840.10045.2.1",
+                "KEYPAIRGENERATOR.1.2.840.113549.1.1.1",
+                "KEYPAIRGENERATOR.1.2.840.113549.1.1.7",
+                "KEYPAIRGENERATOR.1.3.133.16.840.63.0.2",
+                "KEYPAIRGENERATOR.2.5.8.1.1",
+                "KEYPAIRGENERATOR.EC",
+                "KEYPAIRGENERATOR.RSA",
+                "MAC.1.2.840.113549.2.10",
+                "MAC.1.2.840.113549.2.11",
+                "MAC.1.2.840.113549.2.7",
+                "MAC.1.2.840.113549.2.8",
+                "MAC.1.2.840.113549.2.9",
+                "MAC.1.3.6.1.5.5.8.1.1",
+                "MAC.1.3.6.1.5.5.8.1.2",
+                "MAC.2.16.840.1.101.3.4.2.1",
+                "MAC.HMAC-MD5",
+                "MAC.HMAC-SHA1",
+                "MAC.HMAC-SHA224",
+                "MAC.HMAC-SHA256",
+                "MAC.HMAC-SHA384",
+                "MAC.HMAC-SHA512",
+                "MAC.HMAC/MD5",
+                "MAC.HMAC/SHA1",
+                "MAC.HMAC/SHA224",
+                "MAC.HMAC/SHA256",
+                "MAC.HMAC/SHA384",
+                "MAC.HMAC/SHA512",
+                "MAC.HMACMD5",
+                "MAC.HMACSHA1",
+                "MAC.HMACSHA224",
+                "MAC.HMACSHA256",
+                "MAC.HMACSHA384",
+                "MAC.HMACSHA512",
+                "MAC.PBEWITHHMACSHA224",
+                "MAC.PBEWITHHMACSHA256",
+                "MAC.PBEWITHHMACSHA384",
+                "MAC.PBEWITHHMACSHA512",
+                "MESSAGEDIGEST.1.2.840.113549.2.5",
+                "MESSAGEDIGEST.1.3.14.3.2.26",
+                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.1",
+                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.2",
+                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.3",
+                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.4",
+                "MESSAGEDIGEST.MD5",
+                "MESSAGEDIGEST.SHA",
+                "MESSAGEDIGEST.SHA-1",
+                "MESSAGEDIGEST.SHA-224",
+                "MESSAGEDIGEST.SHA-256",
+                "MESSAGEDIGEST.SHA-384",
+                "MESSAGEDIGEST.SHA-512",
+                "MESSAGEDIGEST.SHA1",
+                "MESSAGEDIGEST.SHA224",
+                "MESSAGEDIGEST.SHA256",
+                "MESSAGEDIGEST.SHA384",
+                "MESSAGEDIGEST.SHA512",
+                "SECRETKEYFACTORY.DESEDE",
+                "SECRETKEYFACTORY.TDEA",
+                "SIGNATURE.1.2.840.10045.4.1",
+                "SIGNATURE.1.2.840.10045.4.3.1",
+                "SIGNATURE.1.2.840.10045.4.3.2",
+                "SIGNATURE.1.2.840.10045.4.3.3",
+                "SIGNATURE.1.2.840.10045.4.3.4",
+                "SIGNATURE.1.2.840.113549.1.1.11",
+                "SIGNATURE.1.2.840.113549.1.1.12",
+                "SIGNATURE.1.2.840.113549.1.1.13",
+                "SIGNATURE.1.2.840.113549.1.1.14",
+                "SIGNATURE.1.2.840.113549.1.1.4",
+                "SIGNATURE.1.2.840.113549.1.1.5",
+                "SIGNATURE.1.3.14.3.2.29",
+                "SIGNATURE.ECDSA",
+                "SIGNATURE.ECDSAWITHSHA1",
+                "SIGNATURE.MD5/RSA",
+                "SIGNATURE.MD5WITHRSA",
+                "SIGNATURE.MD5WITHRSAENCRYPTION",
+                "SIGNATURE.NONEWITHECDSA",
+                "SIGNATURE.OID.1.2.840.10045.4.3.1",
+                "SIGNATURE.OID.1.2.840.10045.4.3.2",
+                "SIGNATURE.OID.1.2.840.10045.4.3.3",
+                "SIGNATURE.OID.1.2.840.10045.4.3.4",
+                "SIGNATURE.OID.1.2.840.113549.1.1.11",
+                "SIGNATURE.OID.1.2.840.113549.1.1.12",
+                "SIGNATURE.OID.1.2.840.113549.1.1.13",
+                "SIGNATURE.OID.1.2.840.113549.1.1.14",
+                "SIGNATURE.OID.1.2.840.113549.1.1.4",
+                "SIGNATURE.OID.1.2.840.113549.1.1.5",
+                "SIGNATURE.OID.1.3.14.3.2.29",
+                "SIGNATURE.SHA1/RSA",
+                "SIGNATURE.SHA1WITHECDSA",
+                "SIGNATURE.SHA1WITHRSA",
+                "SIGNATURE.SHA1WITHRSAENCRYPTION",
+                "SIGNATURE.SHA224/ECDSA",
+                "SIGNATURE.SHA224/RSA",
+                "SIGNATURE.SHA224WITHECDSA",
+                "SIGNATURE.SHA224WITHRSA",
+                "SIGNATURE.SHA224WITHRSAENCRYPTION",
+                "SIGNATURE.SHA256/ECDSA",
+                "SIGNATURE.SHA256/RSA",
+                "SIGNATURE.SHA256WITHECDSA",
+                "SIGNATURE.SHA256WITHRSA",
+                "SIGNATURE.SHA256WITHRSAENCRYPTION",
+                "SIGNATURE.SHA384/ECDSA",
+                "SIGNATURE.SHA384/RSA",
+                "SIGNATURE.SHA384WITHECDSA",
+                "SIGNATURE.SHA384WITHRSA",
+                "SIGNATURE.SHA384WITHRSAENCRYPTION",
+                "SIGNATURE.SHA512/ECDSA",
+                "SIGNATURE.SHA512/RSA",
+                "SIGNATURE.SHA512WITHECDSA",
+                "SIGNATURE.SHA512WITHRSA",
+                "SIGNATURE.SHA512WITHRSAENCRYPTION"
+        ));
+    }
+
     private static Provider getProvider(Object object) throws Exception {
         // Every JCA object has a getProvider() method
         Method m = object.getClass().getMethod("getProvider");
@@ -287,4 +426,47 @@
             Security.insertProviderAt(originalBouncyCastle, originalBouncyCastleIndex);
         }
     }
+    
+    @Test
+    public void testRemovedBCAlgorithms() throws Exception {
+        for (String fullAlgorithm : REMOVED_BC_ALGORITHMS) {
+            String[] parts = fullAlgorithm.split("\\.", 2);
+            assertEquals("Algortihm names are expected to be of format Type.Name",
+                2, parts.length);
+
+            Provider bcProvider = Security.getProvider("BC");
+            String type = parts[0];
+            String algorithm = parts[1];
+            try {
+                switch (parts[0]) {
+                    case "ALGORITHMPARAMETERS":
+                        AlgorithmParameters.getInstance(algorithm, bcProvider);
+                    case "CERTIFICATEFACTORY":
+                        CertificateFactory.getInstance(algorithm, bcProvider);
+                    case "CIPHER":
+                        Cipher.getInstance(algorithm, bcProvider);
+                    case "KEYAGREEMENT":
+                        KeyAgreement.getInstance(algorithm, bcProvider);
+                    case "KEYFACTORY":
+                        KeyFactory.getInstance(algorithm, bcProvider);
+                    case "KEYGENERATOR":
+                        KeyGenerator.getInstance(algorithm, bcProvider);
+                    case "KEYPAIRGENERATOR":
+                        KeyPairGenerator.getInstance(algorithm, bcProvider);
+                    case "MAC":
+                        Mac.getInstance(algorithm, bcProvider);
+                    case "MESSAGEDIGEST":
+                        MessageDigest.getInstance(algorithm, bcProvider);
+                    case "SECRETKEYFACTORY":
+                        SecretKeyFactory.getInstance(algorithm, bcProvider);
+                    case "SIGNATURE":
+                        Signature.getInstance(algorithm, bcProvider);
+                    default:
+                        fail("unhandled algorithm type " + parts[0]);
+                }
+                fail("getInstance should have thrown for type: " + parts[0] + ", name: " + algorithm);
+            } catch(CertificateException | NoSuchAlgorithmException expected) {
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/luni/src/test/java/libcore/xml/PullParserTest.java b/luni/src/test/java/libcore/xml/PullParserTest.java
index a52db1d..3c74bb6 100644
--- a/luni/src/test/java/libcore/xml/PullParserTest.java
+++ b/luni/src/test/java/libcore/xml/PullParserTest.java
@@ -770,7 +770,7 @@
         XmlPullParser parser = newPullParser();
         String test = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                 "<!DOCTYPE root [\n" +
-                "<!ENTITY dummy \"dummy\">\n" +
+                "<!ENTITY fake \"fake\">\n" +
                 "]>  \n" +
                 "<root></root>";
         assertParseSuccess(test, parser);
@@ -781,7 +781,7 @@
         XmlPullParser parser = newPullParser();
         String test = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                 "<!DOCTYPE root [\n" +
-                "<!ENTITY dummy \"dummy\">\n" +
+                "<!ENTITY fake \"fake\">\n" +
                 "]>  \n" +
                 "<root></root>";
         assertParseSuccess(test, parser);
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
index 2315492..0da2d1b 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/AlgorithmParametersTest.java
@@ -74,11 +74,11 @@
     public void test_getAlgorithm() throws Exception {
 
         // test: null value
-        AlgorithmParameters ap = new DummyAlgorithmParameters(null, p, null);
+        AlgorithmParameters ap = new FakeAlgorithmParameters(null, p, null);
         assertNull(ap.getAlgorithm());
 
         // test: not null value
-        ap = new DummyAlgorithmParameters(null, p, "AAA");
+        ap = new FakeAlgorithmParameters(null, p, "AAA");
         assertEquals("AAA", ap.getAlgorithm());
     }
 
@@ -95,7 +95,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         //
@@ -131,7 +131,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         //
@@ -161,7 +161,7 @@
             }
         };
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new MyAlgorithmParameterSpec());
         assertSame(enc, params.getEncoded(null));
     }
@@ -254,7 +254,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         //
@@ -293,7 +293,7 @@
             }
         };
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new MyAlgorithmParameterSpec());
         assertNull(params.getParameterSpec(null));
     }
@@ -340,11 +340,11 @@
      */
     public void test_getProvider() throws Exception {
         // test: null value
-        AlgorithmParameters ap = new DummyAlgorithmParameters(null, null, "AAA");
+        AlgorithmParameters ap = new FakeAlgorithmParameters(null, null, "AAA");
         assertNull(ap.getProvider());
 
         // test: not null value
-        ap = new DummyAlgorithmParameters(null, p, "AAA");
+        ap = new FakeAlgorithmParameters(null, p, "AAA");
         assertSame(p, ap.getProvider());
     }
 
@@ -367,7 +367,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         params.init(spec);
@@ -383,7 +383,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new byte[0]);
         try {
             params.init(spec);
@@ -392,7 +392,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new byte[0], "format");
         try {
             params.init(spec);
@@ -413,7 +413,7 @@
             }
         };
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init((AlgorithmParameterSpec) null);
         assertTrue(paramSpi.runEngineInit_AlgParamSpec);
     }
@@ -435,7 +435,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         params.init(enc);
@@ -451,7 +451,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new MyAlgorithmParameterSpec());
         try {
             params.init(enc);
@@ -460,7 +460,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(enc, "format");
         try {
             params.init(enc);
@@ -480,7 +480,7 @@
             }
         };
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init((byte[]) null);
         assertTrue(paramSpi.runEngineInitB$);
     }
@@ -506,7 +506,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         params.init(enc, strFormatParam);
@@ -522,7 +522,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(new MyAlgorithmParameterSpec());
         try {
             params.init(enc, strFormatParam);
@@ -531,7 +531,7 @@
             // expected
         }
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(enc);
         try {
             params.init(enc, strFormatParam);
@@ -557,7 +557,7 @@
             }
         };
 
-        params = new DummyAlgorithmParameters(paramSpi, p, "algorithm");
+        params = new FakeAlgorithmParameters(paramSpi, p, "algorithm");
         params.init(null, null);
         assertTrue(paramSpi.runEngineInitB$String);
     }
@@ -575,7 +575,7 @@
             }
         };
 
-        AlgorithmParameters params = new DummyAlgorithmParameters(paramSpi, p,
+        AlgorithmParameters params = new FakeAlgorithmParameters(paramSpi, p,
                 "algorithm");
 
         assertNull("unititialized", params.toString());
@@ -690,8 +690,8 @@
     private class MyAlgorithmParameterSpec implements java.security.spec.AlgorithmParameterSpec{
     }
 
-    private class DummyAlgorithmParameters extends AlgorithmParameters {
-        public DummyAlgorithmParameters(AlgorithmParametersSpi paramSpi,
+    private class FakeAlgorithmParameters extends AlgorithmParameters {
+        public FakeAlgorithmParameters(AlgorithmParametersSpi paramSpi,
                 Provider provider, String algorithm) {
             super(paramSpi, provider, algorithm);
         }
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
index 1362fc6..2cbf1ce 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/Identity2Test.java
@@ -253,6 +253,9 @@
         java.security.Certificate[] certs = sub.certificates();
         assertEquals("Certificate not contained in the identity",
                      certs[0], certImpl);
+
+        sub.removeCertificate(certs[0]);
+        assertEquals(0, sub.certificates().length);
     }
 
     /**
@@ -333,7 +336,7 @@
      * java.security.Identity#toString()
      */
     public void test_toString() throws Exception {
-        IdentitySubclass sub = new IdentitySubclass("test", null);
+        Identity sub = new IdentitySubclass("test", null);
         assertNotNull(sub.toString());
         assertTrue("The String returned is not valid", sub.toString().length() > 0);
         // Regression for HARMONY-1566
@@ -344,7 +347,7 @@
      * java.security.Identity#toString(boolean)
      */
     public void test_toStringZ() throws Exception {
-        IdentitySubclass sub = new IdentitySubclass("test", null);
+        Identity sub = new IdentitySubclass("test", null);
         assertNotNull(sub.toString(true));
         assertTrue("The String returned is not valid", sub.toString(true).length() > 0);
     }
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactory2Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactory2Test.java
index f6210a9..594219b 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactory2Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyFactory2Test.java
@@ -329,7 +329,14 @@
         while (e.hasMoreElements()) {
             String algorithm = (String) e.nextElement();
             if (algorithm.startsWith(KEYFACTORY_ID) && !algorithm.contains(" ")) {
-                algs.addElement(algorithm.substring(KEYFACTORY_ID.length()));
+                String keyFactoryName = algorithm.substring(KEYFACTORY_ID.length());
+                if ("XDH".equals(keyFactoryName)) {
+                    // Skip Elliptic curve DH as the KeySpec classes needed for this
+                    // test aren't yet available on Android. XDH is fully tested in Conscrypt
+                    // tests. b/179675498
+                    continue;
+                }
+                algs.addElement(keyFactoryName);
             }
         }
 
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
index 4178db0..de8a161 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStore4Test.java
@@ -271,7 +271,7 @@
         }
 
         try {
-            String certificateAlias = keyStore.getCertificateAlias(new MyCertificate("dummy", null));
+            String certificateAlias = keyStore.getCertificateAlias(new MyCertificate("fake", null));
             assertNull("alias was not null", certificateAlias);
         } catch (KeyStoreException e) {
             fail("unexpected exception: " + e);
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
index be3e6d1..494ba65 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/KeyStoreSpiTest.java
@@ -97,7 +97,7 @@
         BadKeyStoreEntry badEntry = new BadKeyStoreEntry();
         BadKeyStoreProtectionParameter badParameter = new BadKeyStoreProtectionParameter();
 
-        KeyStore.SecretKeyEntry dummyEntry = new KeyStore.SecretKeyEntry(new SecretKey() {
+        KeyStore.SecretKeyEntry fakeEntry = new KeyStore.SecretKeyEntry(new SecretKey() {
             @Override public String getAlgorithm() { return null; }
             @Override public String getFormat() { return null; }
             @Override public byte[] getEncoded() { return null; }
@@ -132,7 +132,7 @@
         } catch (KeyStoreException expected) {
         }
 
-        ksSpi.engineSetEntry("aaa", dummyEntry, null);
+        ksSpi.engineSetEntry("aaa", fakeEntry, null);
         assertTrue(keyEntryWasSet[0]);
     }
 
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/java/security/SignatureSpiTest.java b/luni/src/test/java/org/apache/harmony/security/tests/java/security/SignatureSpiTest.java
index ea0bd7f..97f66e6 100644
--- a/luni/src/test/java/org/apache/harmony/security/tests/java/security/SignatureSpiTest.java
+++ b/luni/src/test/java/org/apache/harmony/security/tests/java/security/SignatureSpiTest.java
@@ -80,7 +80,7 @@
         // or rather test that no UnsupportedOperationException is thrown?
 
         @SuppressWarnings("unused")
-        Signature s = new Signature("dummy") {
+        Signature s = new Signature("fake") {
             protected AlgorithmParameters engineGetParameters() {
                 engineGetParametersCalled = true;
                 try {
@@ -310,7 +310,7 @@
     }
 
     public void testEngineInitSign_PrivateKey_SecureRandom() {
-        MySignature signature = new MySignature("dummy");
+        MySignature signature = new MySignature("fake");
 
         try {
             signature.initSign(null, null);
@@ -323,7 +323,7 @@
 
     public void testEngineSetParameter()
     {
-        MySignature signature = new MySignature("dummy");
+        MySignature signature = new MySignature("fake");
 
         try {
             signature.setParameter(null);
@@ -337,7 +337,7 @@
     }
 
     public void testEngineSign_BII() {
-        MySignature signature = new MySignature("dummy");
+        MySignature signature = new MySignature("fake");
         try {
             signature.initSign(new PrivateKey() {
 
@@ -367,7 +367,7 @@
     }
 
     public void testEngineUpdate_ByteBuffer() {
-        MySignature signature = new MySignature("dummy");
+        MySignature signature = new MySignature("fake");
         try {
             signature.initSign(new PrivateKey() {
 
@@ -397,7 +397,7 @@
     }
 
     public void testEngineVerify_BII() {
-        MySignature signature = new MySignature("dummy");
+        MySignature signature = new MySignature("fake");
 
         try {
             signature.initVerify(new PublicKey() {
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/CertBlocklistTest.java
similarity index 73%
rename from luni/src/test/java/tests/com/android/org/bouncycastle/jce/provider/CertBlacklistTest.java
rename to luni/src/test/java/tests/com/android/org/bouncycastle/jce/provider/CertBlocklistTest.java
index 40ba176..4aebdb1 100644
--- 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/CertBlocklistTest.java
@@ -18,7 +18,7 @@
 
 import junit.framework.TestCase;
 
-import com.android.org.bouncycastle.jce.provider.CertBlacklist;
+import com.android.org.bouncycastle.jce.provider.CertBlocklist;
 import com.android.org.bouncycastle.util.encoders.Base64;
 import com.android.org.bouncycastle.util.encoders.Hex;
 
@@ -35,7 +35,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
-public class CertBlacklistTest extends TestCase {
+public class CertBlocklistTest extends TestCase {
 
     private File tmpFile;
 
@@ -125,7 +125,7 @@
                     "Y3ldKwvYBW3W3yNZdTHbPyNsPJdhqA55mDNsteE5YTp1PyySDb1MSVrbxDEruoH6ZE99Hob4Ih8A" +
                     "mn7MHZatGClECgjXWFZ2Gxa7OUCaQpcH8g==";
 
-    public CertBlacklistTest() throws IOException {
+    public CertBlocklistTest() throws IOException {
         tmpFile = File.createTempFile("test", "");
         DEFAULT_PUBKEYS = getDefaultPubkeys();
         DEFAULT_SERIALS = getDefaultSerials();
@@ -147,11 +147,11 @@
         }
     }
 
-    private Set<String> getPubkeyBlacklist(String path) throws IOException {
-        // set our blacklist path
-        CertBlacklist bl = new CertBlacklist(path, "");
-        // call readPubkeyBlacklist
-        Set<byte[]> arr = bl.pubkeyBlacklist;
+    private Set<String> getPubkeyBlocklist(String path) throws IOException {
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist(path, "");
+        // call readPubkeyBlocklist
+        Set<byte[]> arr = bl.pubkeyBlocklist;
         // convert the results to a hashset of strings
         Set<String> results = new HashSet<String>();
         for (byte[] value: arr) {
@@ -160,11 +160,11 @@
         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;
+    private Set<String> getSerialBlocklist(String path) throws IOException {
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist("", path);
+        // call readPubkeyBlocklist
+        Set<BigInteger> arr = bl.serialBlocklist;
         // convert the results to a hashset of strings
         Set<String> results = new HashSet<String>();
         for (BigInteger value: arr) {
@@ -181,28 +181,28 @@
     }
 
     private Set<String> getDefaultPubkeys() throws IOException {
-        return getPubkeyBlacklist("");
+        return getPubkeyBlocklist("");
     }
 
     private Set<String> getDefaultSerials() throws IOException {
-        return getSerialBlacklist("");
+        return getSerialBlocklist("");
     }
 
-    private Set<String> getCurrentPubkeyBlacklist() throws IOException {
-        return getPubkeyBlacklist(tmpFile.getCanonicalPath());
+    private Set<String> getCurrentPubkeyBlocklist() throws IOException {
+        return getPubkeyBlocklist(tmpFile.getCanonicalPath());
     }
 
-    private Set<String> getCurrentSerialBlacklist() throws IOException {
-        return getSerialBlacklist(tmpFile.getCanonicalPath());
+    private Set<String> getCurrentSerialBlocklist() throws IOException {
+        return getSerialBlocklist(tmpFile.getCanonicalPath());
     }
 
-    private void blacklistToFile(String blacklist) throws IOException {
+    private void blocklistToFile(String blocklist) throws IOException {
         FileOutputStream out = new FileOutputStream(tmpFile);
-        out.write(blacklist.toString().getBytes());
+        out.write(blocklist.toString().getBytes());
         out.close();
     }
 
-    private void writeBlacklist(HashSet<String> values) throws IOException {
+    private void writeBlocklist(HashSet<String> values) throws IOException {
         StringBuilder result = new StringBuilder();
         // join the values into a string
         for (String value : values) {
@@ -211,7 +211,7 @@
             }
             result.append(value);
         }
-        blacklistToFile(result.toString());
+        blocklistToFile(result.toString());
     }
 
     private static PublicKey createPublicKey(String cert) throws Exception {
@@ -229,203 +229,203 @@
         return xCert.getSerialNumber();
     }
 
-    public void testPubkeyBlacklistLegit() throws Exception {
-        // build the blacklist
+    public void testPubkeyBlocklistLegit() throws Exception {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default pubkeys into the bl
         bl.addAll(DEFAULT_PUBKEYS);
         // do the test
-        assertEquals(bl, getCurrentPubkeyBlacklist());
+        assertEquals(bl, getCurrentPubkeyBlocklist());
     }
 
-    public void testLegitPubkeyIsntBlacklisted() throws Exception {
+    public void testLegitPubkeyIsntBlocklisted() 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);
+        // write that to the test blocklist
+        writeBlocklist(new HashSet<String>());
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist(tmpFile.getCanonicalPath(), "");
+        // check to make sure it isn't blocklisted
+        assertEquals(bl.isPublicKeyBlockListed(pk), false);
     }
 
-    public void testPubkeyIsBlacklisted() throws Exception {
+    public void testPubkeyIsBlocklisted() 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));
+        // write that to the test blocklist
+        HashSet<String> testBlockList = new HashSet<String>();
+        testBlockList.add(hash);
+        writeBlocklist(testBlockList);
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist(tmpFile.getCanonicalPath(), "");
+        // check to make sure it isn't blocklited
+        assertTrue(bl.isPublicKeyBlockListed(pk));
     }
 
-    public void testSerialBlacklistLegit() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistLegit() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default serials into the bl
         bl.addAll(DEFAULT_SERIALS);
         // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
+        assertEquals(bl, getCurrentSerialBlocklist());
     }
 
-    public void testPubkeyBlacklistMultipleLegit() throws IOException {
-        // build the blacklist
+    public void testPubkeyBlocklistMultipleLegit() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default pubkeys into the bl
         bl.addAll(DEFAULT_PUBKEYS);
         // do the test
-        assertEquals(bl, getCurrentPubkeyBlacklist());
+        assertEquals(bl, getCurrentPubkeyBlocklist());
     }
 
-    public void testSerialBlacklistMultipleLegit() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistMultipleLegit() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
         bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default serials into the bl
         bl.addAll(DEFAULT_SERIALS);
         // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
+        assertEquals(bl, getCurrentSerialBlocklist());
     }
 
-    public void testPubkeyBlacklistMultipleBad() throws IOException {
-        // build the blacklist
+    public void testPubkeyBlocklistMultipleBad() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccc");
         bl.add("");
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091ccd");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(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());
+        assertEquals(bl, getCurrentPubkeyBlocklist());
     }
 
-    public void testSerialBlacklistMultipleBad() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistMultipleBad() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("22e514121e61c643b1e9b06bd4b9f7d0");
         bl.add("");
         bl.add("22e514121e61c643b1e9b06bd4b9f7d1");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(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());
+        assertEquals(bl, getCurrentSerialBlocklist());
     }
 
-    public void testPubkeyBlacklistDoesntExist() throws IOException {
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+    public void testPubkeyBlocklistDoesntExist() throws IOException {
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlocklist());
     }
 
-    public void testSerialBlacklistDoesntExist() throws IOException {
-        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
+    public void testSerialBlocklistDoesntExist() throws IOException {
+        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlocklist());
     }
 
-    public void testPubkeyBlacklistNotHexValues() throws IOException {
-        // build the blacklist
+    public void testPubkeyBlocklistNotHexValues() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // do the test
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlocklist());
     }
 
-    public void testSerialBlacklistNotHexValues() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistNotHexValues() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // do the test
-        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlacklist());
+        assertEquals(DEFAULT_SERIALS, getCurrentSerialBlocklist());
     }
 
-    public void testPubkeyBlacklistIncorrectLength() throws IOException {
-        // build the blacklist
+    public void testPubkeyBlocklistIncorrectLength() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("6ccabd7db47e94a5759901b6a7dfd45d1c091cc");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // do the test
-        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlacklist());
+        assertEquals(DEFAULT_PUBKEYS, getCurrentPubkeyBlocklist());
     }
 
-    public void testSerialBlacklistZero() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistZero() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("0");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default serials
         bl.addAll(DEFAULT_SERIALS);
         // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
+        assertEquals(bl, getCurrentSerialBlocklist());
     }
 
-    public void testSerialBlacklistNegative() throws IOException {
-        // build the blacklist
+    public void testSerialBlocklistNegative() throws IOException {
+        // build the blocklist
         HashSet<String> bl = new HashSet<String>();
         bl.add("-1");
-        // write the blacklist
-        writeBlacklist(bl);
+        // write the blocklist
+        writeBlocklist(bl);
         // add the default serials
         bl.addAll(DEFAULT_SERIALS);
         // do the test
-        assertEquals(bl, getCurrentSerialBlacklist());
+        assertEquals(bl, getCurrentSerialBlocklist());
     }
 
-    public void testTurkTrustIntermediate1PubkeyBlacklist() throws Exception {
+    public void testTurkTrustIntermediate1PubkeyBlocklist() 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);
+        // write that to the test blocklist
+        writeBlocklist(new HashSet<String>());
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist();
+        // check to make sure it isn't blocklisted
+        assertEquals(bl.isPublicKeyBlockListed(pk), true);
     }
 
-    public void testTurkTrustIntermediate2PubkeyBlacklist() throws Exception {
+    public void testTurkTrustIntermediate2PubkeyBlocklist() 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);
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist();
+        // check to make sure it isn't blocklisted
+        assertEquals(bl.isPublicKeyBlockListed(pk), true);
     }
 
-    public void testANSSIIntermediatePubkeyBlacklist() throws Exception {
+    public void testANSSIIntermediatePubkeyBlocklist() 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);
+        // set our blocklist path
+        CertBlocklist bl = new CertBlocklist();
+        // check to make sure it isn't blocklisted
+        assertEquals(bl.isPublicKeyBlockListed(pk), true);
     }
 
     private static void printHash(String cert) throws Exception {
diff --git a/luni/src/test/java/tests/java/security/SecureClassLoaderTest.java b/luni/src/test/java/tests/java/security/SecureClassLoaderTest.java
index 9a0761b..c88ff50 100644
--- a/luni/src/test/java/tests/java/security/SecureClassLoaderTest.java
+++ b/luni/src/test/java/tests/java/security/SecureClassLoaderTest.java
@@ -22,15 +22,12 @@
 
 package tests.java.security;
 
-import dalvik.annotation.KnownFailure;
-
 import junit.framework.TestCase;
 
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.nio.ByteBuffer;
 import java.security.CodeSource;
-import java.security.Permission;
 import java.security.PermissionCollection;
 import java.security.ProtectionDomain;
 import java.security.SecureClassLoader;
@@ -165,13 +162,24 @@
             (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00,
             (byte) 0x21, };
 
-    @KnownFailure("Android doesn't allow null parent.")
     public void testSecureClassLoaderClassLoader() throws Exception {
         URL[] urls = new URL[] { new URL("http://localhost") };
         URLClassLoader ucl = URLClassLoader.newInstance(urls);
-        new MyClassLoader(ucl);
+        MyClassLoader classLoader = new MyClassLoader(ucl);
 
         try {
+            classLoader.tryDefineClass("ClassA", new byte[0], 0, 0, null);
+            fail("SecureClassloader.defineClass doesn't throw");
+        } catch (UnsupportedOperationException e) {}
+
+        try {
+            classLoader.tryDefineClass("ClassB", ByteBuffer.wrap(new byte[0]), null);
+            fail("SecureClassloader.defineClass doesn't throw");
+        } catch (UnsupportedOperationException e) {}
+    }
+
+    public void testNullParent() {
+        try {
             new MyClassLoader(null);
         } catch (Exception e) {
             fail("unexpected exception: " + e);
@@ -233,5 +241,14 @@
             return defineClass(name, b, off, len, cs);
         }
 
+        public Class<?> tryDefineClass(String name, byte[] bytes, int off, int len,
+                CodeSource codeSource) {
+            return this.defineClass(name, bytes, off, len, codeSource);
+        }
+
+        public Class<?> tryDefineClass(String name, ByteBuffer byteBuffer, CodeSource codeSource) {
+            return this.defineClass(name, byteBuffer, codeSource);
+        }
+
     }
 }
diff --git a/luni/src/test/java/tests/java/sql/StressTest.java b/luni/src/test/java/tests/java/sql/StressTest.java
index b981d5e..03c6b85 100644
--- a/luni/src/test/java/tests/java/sql/StressTest.java
+++ b/luni/src/test/java/tests/java/sql/StressTest.java
@@ -16,31 +16,40 @@
 
 package tests.java.sql;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
-import java.sql.Driver;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.Properties;
 import java.util.Vector;
 import java.util.logging.Logger;
 
 import tests.support.DatabaseCreator;
 import tests.support.Support_SQL;
 import tests.support.ThreadPool;
-import junit.framework.TestCase;
 
-public class StressTest extends TestCase {
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class StressTest {
     Vector<Connection> vc = new Vector<Connection>();
 
     private static Connection conn;
 
     private static Statement statement;
 
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
         Support_SQL.loadDriver();
         conn = Support_SQL.getConnection();
         statement = conn.createStatement();
@@ -48,11 +57,11 @@
         vc.clear();
     }
 
-    protected void tearDown() throws Exception {
+    @After
+    public void tearDown() throws Exception {
         closeConnections();
         statement.close();
         conn.close();
-        super.tearDown();
     }
 
     private void createTestTables() {
@@ -105,6 +114,7 @@
      * StressTest#testManyConnectionsUsingOneThread(). Create many
      *        connections to the DataBase using one thread.
      */
+    @Test
     public void testManyConnectionsUsingOneThread() {
         try {
             int maxConnections = getConnectionNum();
@@ -120,6 +130,7 @@
      * StressTest#testManyConnectionsUsingManyThreads(). Create many
      *        connections to the DataBase using some threads.
      */
+    @Test
     public void testManyConnectionsUsingManyThreads() {
         int numTasks = getConnectionNum();
 
@@ -149,6 +160,7 @@
      * StressTest#testInsertOfManyRowsUsingOneThread(). Insert a lot of
      *        records to the Database using a maximum number of connections.
      */
+    @Test
     public void testInsertOfManyRowsUsingOneThread() {
 
         Logger.global
@@ -187,7 +199,10 @@
 
     /**
      * @tests
+     * TODO(b/169673091): Investigate why it could occasionally take 10min rather than 10s to
+     * finish.
      */
+    @Test
     public void testInsertOfManyRowsUsingManyThreads() {
         Logger.global.info("java.sql stress test: multiple threads and many operations.");
 
@@ -204,6 +219,7 @@
         }
         // close the pool and wait for all tasks to finish.
         threadPool.join();
+        Logger.global.info("All threads joined");
         assertEquals("Unable to create a connection", numConnections, vc.size());
 
         try {
@@ -211,11 +227,12 @@
                     .executeQuery("SELECT COUNT(*) as counter FROM "
                             + DatabaseCreator.TEST_TABLE2);
             assertTrue("RecordSet is empty", rs.next());
-
+            Logger.global.info("Counting statement returned");
 
             assertEquals("Incorrect number of records", tasksPerConnection
                     * numConnections, rs.getInt("counter"));
             rs.close();
+            Logger.global.info("ResultSet closed");
         } catch (SQLException sql) {
             fail("Unexpected SQLException " + sql.toString());
 
diff --git a/luni/src/test/java/tests/org/w3c/dom/LSExceptionTest.java b/luni/src/test/java/tests/org/w3c/dom/LSExceptionTest.java
new file mode 100644
index 0000000..cafe3fd
--- /dev/null
+++ b/luni/src/test/java/tests/org/w3c/dom/LSExceptionTest.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.org.w3c.dom;
+
+import junit.framework.TestCase;
+
+import org.w3c.dom.DOMError;
+import org.w3c.dom.ls.LSException;
+
+public class LSExceptionTest extends TestCase {
+
+    public void testConstructor() {
+        String msg = "Test message";
+        try {
+            throw new LSException(DOMError.SEVERITY_FATAL_ERROR, msg);
+        } catch (LSException e) {
+            assertEquals(DOMError.SEVERITY_FATAL_ERROR, e.code);
+            assertEquals(msg, e.getMessage());
+        }
+    }
+}
diff --git a/luni/src/test/java/tests/org/w3c/dom/OwnerDocument.java b/luni/src/test/java/tests/org/w3c/dom/OwnerDocument.java
index eb1a8df..e168bea 100644
--- a/luni/src/test/java/tests/org/w3c/dom/OwnerDocument.java
+++ b/luni/src/test/java/tests/org/w3c/dom/OwnerDocument.java
@@ -31,7 +31,7 @@
  *     The "getOwnerDocument()" method returns null if the target
  *     node itself is a DocumentType which is not used with any document yet.
  *
- *     Invoke the "getOwnerDocument()" method on the master
+ *     Invoke the "getOwnerDocument()" method on the root
  *     document.   The DocumentType returned should be null.
 * @author NIST
 * @author Mary Brady
diff --git a/luni/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java b/luni/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
index b5615cc..941db69 100644
--- a/luni/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
+++ b/luni/src/test/java/tests/security/cert/CertPathBuilderSpiTest.java
@@ -22,6 +22,8 @@
 
 package tests.security.cert;
 
+import java.security.cert.CertPathChecker;
+import java.security.cert.Certificate;
 import junit.framework.TestCase;
 
 import java.security.InvalidAlgorithmParameterException;
@@ -50,8 +52,55 @@
             certPathBuilder.engineBuild(cpp);
             fail("CertPathBuilderException must be thrown");
         } catch (CertPathBuilderException e) {
+            // Expected
         }
         CertPathBuilderResult cpbResult = certPathBuilder.engineBuild(cpp);
         assertNull("Not null CertPathBuilderResult", cpbResult);
     }
+
+    public void testEngineGetRevocationChecker_Unsupported() {
+        // MyCertPathBuilderSpi doesn't implement engineGetRevocationChecker()
+        CertPathBuilderSpi certPathBuilder = new MyCertPathBuilderSpi();
+        try {
+            certPathBuilder.engineGetRevocationChecker();
+            fail();
+        } catch (UnsupportedOperationException e) {
+            // Expected
+        }
+    }
+
+    public void testEngineGetRevocationChecker_Supported() {
+        CertPathBuilderSpi certPathBuilder = new PathBuilderSpi();
+        assertEquals(PathChecker.class, certPathBuilder.engineGetRevocationChecker().getClass());
+    }
+
+    // Stub CertPathBuilderSpi which has a revocation checker.
+    private static class PathBuilderSpi extends CertPathBuilderSpi {
+        @Override
+        public CertPathBuilderResult engineBuild(CertPathParameters params) {
+            throw new AssertionError("Stub");
+        }
+
+        @Override
+        public CertPathChecker engineGetRevocationChecker() {
+            return new PathChecker();
+        }
+    }
+
+    private static class PathChecker implements CertPathChecker {
+        @Override
+        public void init(boolean forward) {
+            throw new AssertionError("Stub");
+        }
+
+        @Override
+        public boolean isForwardCheckingSupported() {
+            throw new AssertionError("Stub");
+        }
+
+        @Override
+        public void check(Certificate cert) {
+            throw new AssertionError("Stub");
+        }
+    }
 }
diff --git a/luni/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java b/luni/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java
new file mode 100644
index 0000000..8235ee7
--- /dev/null
+++ b/luni/src/test/java/tests/security/cert/CertPathValidatorSpiTest.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.cert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.security.cert.CertPath;
+import java.security.cert.CertPathChecker;
+import java.security.cert.CertPathParameters;
+import java.security.cert.CertPathValidatorResult;
+import java.security.cert.CertPathValidatorSpi;
+import java.security.cert.Certificate;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class CertPathValidatorSpiTest {
+  // engineValidate() implementations are tested via the CertPathValidator*Tests.
+
+  @Test
+  public void engineGetRevocationChecker_Unsupported() {
+    CertPathValidatorSpi spi = new PathValidatorSpiNoRevocation();
+    try {
+      spi.engineGetRevocationChecker();
+      fail();
+    } catch (UnsupportedOperationException e) {
+      // Expected
+    }
+  }
+
+  @Test
+  public void engineGetRevocationChecker_Supported() {
+    CertPathValidatorSpi spi = new PathValidatorSpiWithRevocation();
+    assertEquals(PathChecker.class, spi.engineGetRevocationChecker().getClass());
+  }
+
+  // Stub CertPathValidatorSpi which has no revocation checker.
+  private static class PathValidatorSpiNoRevocation extends CertPathValidatorSpi {
+    @Override
+    public CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params) {
+      throw new AssertionError("Stub");
+    }
+  }
+
+  // Stub CertPathValidatorSpi which has a revocation checker.
+  private static class PathValidatorSpiWithRevocation extends CertPathValidatorSpi {
+
+    @Override
+    public CertPathValidatorResult engineValidate(CertPath certPath, CertPathParameters params) {
+      throw new AssertionError("Stub");
+    }
+
+    @Override
+    public CertPathChecker engineGetRevocationChecker() {
+      return new PathChecker();
+    }
+  }
+
+  private static class PathChecker implements CertPathChecker {
+    @Override
+    public void init(boolean forward) {
+      throw new AssertionError("Stub");
+    }
+
+    @Override
+    public boolean isForwardCheckingSupported() {
+      throw new AssertionError("Stub");
+    }
+
+    @Override
+    public void check(Certificate cert) {
+      throw new AssertionError("Stub");
+    }
+  }
+}
diff --git a/luni/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java b/luni/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
index 44a2fa4..ebf82b2 100644
--- a/luni/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
+++ b/luni/src/test/java/tests/security/cert/PKIXCertPathCheckerTest.java
@@ -74,21 +74,24 @@
         PKIXCertPathChecker pc = TestUtils.getTestCertPathChecker();
         pc.getSupportedExtensions();
     }
-    public final void testCheck() throws CertPathValidatorException {
+    public final void testCheck_Cert_Collection() throws CertPathValidatorException {
         PKIXCertPathChecker pc = TestUtils.getTestCertPathChecker();
-        pc.check(new MyCertificate("", null), new HashSet<String>());
+        pc.check(new MyCertificate("", null), new HashSet<>());
     }
 
-    class MyPKIXCertPathChecker extends PKIXCertPathChecker {
+    public final void testCheck_Cert() throws CertPathValidatorException {
+        PKIXCertPathChecker pc = TestUtils.getTestCertPathChecker();
+        pc.check(new MyCertificate("", null));
+    }
+
+    private static class MyPKIXCertPathChecker extends PKIXCertPathChecker {
 
         public MyPKIXCertPathChecker() {
             super();
         }
 
         @Override
-        public void check(Certificate cert,
-                Collection<String> unresolvedCritExts)
-        throws CertPathValidatorException {
+        public void check(Certificate cert, Collection<String> unresolvedCritExts) {
         }
 
         @Override
@@ -97,14 +100,12 @@
         }
 
         @Override
-        public void init(boolean forward) throws CertPathValidatorException {
+        public void init(boolean forward) {
         }
 
         @Override
         public boolean isForwardCheckingSupported() {
             return false;
         }
-
     }
-
 }
diff --git a/luni/src/test/java/tests/security/cert/X509Certificate2Test.java b/luni/src/test/java/tests/security/cert/X509Certificate2Test.java
index bf736d5..c1f5993 100644
--- a/luni/src/test/java/tests/security/cert/X509Certificate2Test.java
+++ b/luni/src/test/java/tests/security/cert/X509Certificate2Test.java
@@ -110,44 +110,47 @@
             + "XEa7ONzcHQTYTG10poHfOK/a0BaULF3GlctDESilwQYbW5BdfpAlZpbH"
             + "AFLcUDh6Eq50kc0A/anh/j3mgBNuvbIMo7hHNnZB6k/prswm2BszyLD"
             + "yw==";
-    private static String CERT_CORRECT =
-        "-----BEGIN CERTIFICATE-----\n"
-        + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
-        + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
-        + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
-        + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
-        + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAYGBFUdIAAwZwYDVR0RAQH/B"
-        + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
-        + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
-        + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
-        + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
-        + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
-        + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
-        + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
-        + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
-        + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
-        + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwGByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
-        + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
-        + "-----END CERTIFICATE-----";
+    private static String CERT_CORRECT = "-----BEGIN CERTIFICATE-----\n"
+        + "MIIDWzCCAxmgAwIBAgICAiswCgYIKoZIzj0EAwIwHTEbMBkGA1UEChMSQ2VydGlm\n"
+        + "aWNhdGUgSXNzdWVyMCIYDzE5NzAwMTEyMTM0NjQwWhgPMTk3MDAxMjQwMzMzMjBa\n"
+        + "MB8xHTAbBgNVBAoTFFN1YmplY3QgT3JnYW5pemF0aW9uMFkwEwYHKoZIzj0CAQYI\n"
+        + "KoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aX\n"
+        + "qAoY+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwYECAKqCAgBVo4ICOTCCAjUwDwYD\n"
+        + "VR0PAQH/BAUDAwGqgDASBgNVHRMBAf8ECDAGAQH/AgEFMBQGA1UdIAEB/wQKMAgw\n"
+        + "BgYEVR0gADBpBgNVHREBAf8EXzBdgQxyZmNAODIyLk5hbWWCB2ROU05hbWWkGTAX\n"
+        + "MRUwEwYDVQQKEwxPcmdhbml6YXRpb26GGmh0dHA6Ly91bmlmb3JtLlJlc291cmNl\n"
+        + "LklkhwT///8AiAcqA6Jcg7IDMAwGA1UdHgEB/wQCMAAwDAYDVR0kAQH/BAIwADCB\n"
+        + "mQYDVR0lAQH/BIGOMIGLBgRVHSUABggrBgEFBQcDAQYIKwYBBQUHAwEGCCsGAQUF\n"
+        + "BwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUFBwMFBggrBgEFBQcDBgYIKwYB\n"
+        + "BQUHAwcGCCsGAQUFBwMIBggrBgEFBQcDCQYIKwYBBQUIAgIGCisGAQQBgjcKAwMG\n"
+        + "CWCGSAGG+EIEATANBgNVHTYBAf8EAwIBATAOBgQqTYYJAQH/BAMBAQEwZgYDVR0S\n"
+        + "BF8wXYEMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBkwFzEVMBMGA1UEChMMT3JnYW5p\n"
+        + "emF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvdXJjZS5JZIcE////AIgHKgOiXIOy\n"
+        + "AzAJBgNVHR8EAjAAMAwGA1UdIwQFMAOAAQEwCgYDVR0OBAMEAQEwKQYDVR0hBCIw\n"
+        + "IDAeBg0qhkiG9xIEAYS3CQIBBg0qhkiG9xIEAYS3CQICMAoGCCqGSM49BAMCAzAA\n"
+        + "MC0CFAC+EL6GszVj+464/OPxmZYZtPQ7AhUAgShighm6z+uFbVLeCT5i41tVcUA=\n"
+        + "-----END CERTIFICATE-----\n";
 
     private static String CERT_TAMPERED = "-----BEGIN CERTIFICATE-----\n"
-        + "MIIC+jCCAragAwIBAgICAiswDAYHKoZIzjgEAwEBADAdMRswGQYDVQQKExJDZXJ0a"
-        + "WZpY2F0ZSBJc3N1ZXIwIhgPMTk3MDAxMTIxMzQ2NDBaGA8xOTcwMDEyNDAzMzMyMF"
-        + "owHzEdMBsGA1UEChMUU3ViamVjdCBPcmdhbml6YXRpb24wGTAMBgcqhkjOOAQDAQE"
-        + "AAwkAAQIDBAUGBwiBAgCqggIAVaOCAhQwggIQMA8GA1UdDwEB/wQFAwMBqoAwEgYD"
-        + "VR0TAQH/BAgwBgEB/wIBBTAUBgNVHSABAf8ECjAIMAyGBFUdIAAwZwYDVR0RAQH/B"
-        + "F0wW4EMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBcxFTATBgNVBAoTDE9yZ2FuaXphdG"
-        + "lvboYaaHR0cDovL3VuaWZvcm0uUmVzb3VyY2UuSWSHBP///wCIByoDolyDsgMwDAY"
-        + "DVR0eAQH/BAIwADAMBgNVHSQBAf8EAjAAMIGZBgNVHSUBAf8EgY4wgYsGBFUdJQAG"
-        + "CCsGAQUFBwMBBggrBgEFBQcDAQYIKxYBBQUHAwIGCCsGAQUFBwMDBggrBgEFBQcDB"
-        + "AYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEFBQcDBwYIKwYBBQUHAwgGCCsGAQUFBw"
-        + "MJBggrBgEFBQgCAgYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GA1UdNgEB/wQDAgE"
-        + "BMA4GBCpNhgkBAf8EAwEBATBkBgNVHRIEXTBbgQxyZmNAODIyLk5hbWWCB2ROU05h"
-        + "bWWkFzEVMBMGA1UEChMMT3JnYW5pemF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvd"
-        + "XJjZS5JZIcE////AIgHKgOiXIOyAzAJBgNVHR8EAjAAMAoGA1UdIwQDAQEBMAoGA1"
-        + "UdDgQDAQEBMAoGA1UdIQQDAQEBMAwHByqGSM44BAMBAQADMAAwLQIUAL4QvoazNWP"
-        + "7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
-        + "-----END CERTIFICATE-----";
+        + "MIIDWjCCAxmgAwIBAgICAiswCgYIKoZIzj0EAwIwHTEbMBkGA1UEChMSQ2VydGlm\n"
+        + "aWNhdGUgSXNzdWVyMCIYDzE5NzAwMTEyMTM0NjQwWhgPMTk3MDAxMjQwMzMzMjBa\n"
+        + "MB8xHTAbBgNVBAoTFFN1YmplY3QgT3JnYW5pemF0aW9uMFkwEwYHKoZIzj0CAQYI\n"
+        + "KoZIzj0DAQcDQgAE5itp4r9ln5e+Lx4NlIpM1Zdrt6keDUb73ampHp3culoB59aX\n"
+        + "qAoY+cPEox5W4nyDSNsWGhz1HX7xlC1Lz3IiwYECAKqCAgBVo4ICOTCCAjUwDwYD\n"
+        + "VR0PAQH/BAUDAwGqgDASBgNVHRMBAf8ECDAGAQH/AgEFMBQGA1UdIAEB/wQKMAgw\n"
+        + "DIYEVR0gADBpBgNVHREBAf8EXzBdgQxyZmNAODIyLk5hbWWCB2ROU05hbWWkGTAX\n"
+        + "MRUwEwYDVQQKEwxPcmdhbml6YXRpb26GGmh0dHA6Ly91bmlmb3JtLlJlc291cmNl\n"
+        + "LklkhwT///8AiAcqA6Jcg7IDMAwGA1UdHgEB/wQCMAAwDAYDVR0kAQH/BAIwADCB\n"
+        + "mQYDVR0lAQH/BIGOMIGLBgRVHSUABggrBgEFBQcDAQYIKwYBBQUHAwEGCCsWAQUF\n"
+        + "BwMCBggrBgEFBQcDAwYIKwYBBQUHAwQGCCsGAQUFBwMFBggrBgEFBQcDBgYIKwYB\n"
+        + "BQUHAwcGCCsGAQUFBwMIBggrBgEFBQcDCQYIKwYBBQUIAgIGCisGAQQBgjcKAwMG\n"
+        + "CWCGSAGG+EIEATANBgNVHTYBAf8EAwIBATAOBgQqTYYJAQH/BAMBAQEwZgYDVR0S\n"
+        + "BF8wXYEMcmZjQDgyMi5OYW1lggdkTlNOYW1lpBkwFzEVMBMGA1UEChMMT3JnYW5p\n"
+        + "emF0aW9uhhpodHRwOi8vdW5pZm9ybS5SZXNvdXJjZS5JZIcE////AIgHKgOiXIOy\n"
+        + "AzAJBgNVHR8EAjAAMAwGA1UdIwQFMAOAAQEwCgYDVR0OBAMEAQEwKQYDVR0hBCIw\n"
+        + "IDAeBg0qhkiG9xIEAYS3CQIBBg0qhkiG9xIEAYS3CQICMAkHByqGSM44BAMDMAAw\n"
+        + "LQIUAL4QvoazNWP7jrj84/GZlhm09DsCFQCBKGKCGbrP64VtUt4JPmLjW1VxQA==\n"
+        + "-----END CERTIFICATE-----\n";
 
     // Base64 encoded form of ASN.1 DER encoded X.509 CRL
     // (see RFC 3280 at http://www.ietf.org/rfc/rfc3280.txt)
diff --git a/luni/src/test/java9language/Android.bp b/luni/src/test/java9language/Android.bp
index dddc184..5c10041 100644
--- a/luni/src/test/java9language/Android.bp
+++ b/luni/src/test/java9language/Android.bp
@@ -15,6 +15,14 @@
 // Android tests related to Java 9 language features.
 
 // Use jarjar to repackage Java9LanguageFeatures, to be used in tests below.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
 java_library {
     name: "core-java-9-language-features-repackaged-for-test",
     hostdex: true,
diff --git a/luni/src/test/parameter_metadata/Android.bp b/luni/src/test/parameter_metadata/Android.bp
index 0eec841..d5ec1c7 100644
--- a/luni/src/test/parameter_metadata/Android.bp
+++ b/luni/src/test/parameter_metadata/Android.bp
@@ -19,6 +19,14 @@
 //
 // Included as a resource by //libcore:core-tests and loaded into its own
 // class loader by libcore.java.lang.reflect.ParameterTest.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_luni_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_luni_license"],
+}
+
 java_library {
     name: "parameter-metadata-test",
     visibility: [
diff --git a/luni/src/test/resources/libcore/java/util/zip/cp1251.zip b/luni/src/test/resources/libcore/java/util/zip/cp1251.zip
new file mode 100644
index 0000000..30426f9
--- /dev/null
+++ b/luni/src/test/resources/libcore/java/util/zip/cp1251.zip
Binary files differ
diff --git a/luni/src/test/resources/math_java_only.csv b/luni/src/test/resources/math_java_only.csv
index 7497244..336e737 100644
--- a/luni/src/test/resources/math_java_only.csv
+++ b/luni/src/test/resources/math_java_only.csv
@@ -240,15 +240,15 @@
 toDegrees,Infinity,0x1.fbc8d827034c3p1022
 toDegrees,Infinity,0x1.18a1877e00a5fp1023
 toDegrees,-Infinity,-0x1.424779e743077p1022
-toRadians,-0x1.bd6ca335c8f8bp1017,-0x1.8ec3beb2d4185p1023
-toRadians,-0x1.d5d636d37463cp1017,-0x1.a49ea827e7d05p1023
+toRadians,-0x1.bd6ca335c8f8cp1017,-0x1.8ec3beb2d4185p1023
+toRadians,-0x1.d5d636d37463bp1017,-0x1.a49ea827e7d05p1023
 toRadians,-0x1.6e07b010242a3p1015,-0x1.47afe754a89fep1021
 toRadians,-0x1.11c7c808a0662p1017,-0x1.ea33b08c7fbfbp1022
 toRadians,0x1.6651facd75f48p1017,0x1.40c8f2c416881p1023
 toRadians,-0x1.048574b80ff57p1017,-0x1.d2762c5e7c22bp1022
 toRadians,0x1.2b69e24b71de8p1015,0x1.0c0c8b67b7daep1021
-toRadians,-0x1.acfe9cbf85fcep1017,-0x1.800e50b80ea85p1023
-toRadians,0x1.0173811fff46ap1015,0x1.ccf6eeb86909cp1020
+toRadians,-0x1.acfe9cbf85fcfp1017,-0x1.800e50b80ea85p1023
+toRadians,0x1.0173811fff46bp1015,0x1.ccf6eeb86909cp1020
 toRadians,-0x1.982fa40f44f9ap1016,-0x1.6d6d5ccb7231fp1022
 toRadians,0x1.61a934e496335p1017,0x1.3c9d1f4fb1b51p1023
 toRadians,-0x1.6cf8ccc8ea027p1016,-0x1.46bd646b348a7p1022
@@ -256,15 +256,15 @@
 toRadians,0x1.1456c8928aff4p1018,0x1.eec87765e84c1p1023
 toRadians,0x1.235fec19c543cp1015,0x1.04da2953b2f46p1021
 toRadians,0x1.882719ca8a188p1016,0x1.5f12c97e6cc4fp1022
-toRadians,-0x1.c2f640afddd61p1016,-0x1.93b8dc284f903p1022
+toRadians,-0x1.c2f640afddd62p1016,-0x1.93b8dc284f903p1022
 toRadians,-0x1.40992763eae48p1017,-0x1.1f03b54fdb6b3p1023
 toRadians,-0x1.8205d95283762p1017,-0x1.5995eb7752bb1p1023
 toRadians,-0x1.00db6068f8009p1015,-0x1.cbe68c7a0015cp1020
 toRadians,0x1.ff045cc909d01p1016,0x1.c97c7a91bfb13p1022
-toRadians,-0x1.dd58c2d344925p1017,-0x1.ab57cf7150fc7p1023
-toRadians,-0x1.e8c0b050f0382p1016,-0x1.b58ddd93bfea3p1022
+toRadians,-0x1.dd58c2d344926p1017,-0x1.ab57cf7150fc7p1023
+toRadians,-0x1.e8c0b050f0383p1016,-0x1.b58ddd93bfea3p1022
 toRadians,-0x1.125c16633ee83p1018,-0x1.eb3d3b0b459ffp1023
-toRadians,-0x1.4390148899c34p1017,-0x1.21ab226ac9ce9p1023
+toRadians,-0x1.4390148899c35p1017,-0x1.21ab226ac9ce9p1023
 toRadians,-0x1.1663e3e36d831p1017,-0x1.f274aa94c0813p1022
 toRadians,0x1.0c15cb5b07c69p1018,0x1.e0012c863f62bp1023
 toRadians,0x1.1b99b34e2a2c9p1017,0x1.fbc8d827034c3p1022
@@ -3530,26 +3530,26 @@
 signum,0x1.0p0,0x1.c31faf27fa01ep3
 signum,-0x1.0p0,-0x1.06058171a93d9p0
 signum,-0x1.0p0,-0x1.852592119514fp0
-toDegrees,0x1.9cc4da55f56cbp4,0x1.cd113dd73a73cp-2
-toDegrees,-0x1.94c416d548e15p2,-0x1.c420c0252959cp-4
+toDegrees,0x1.9cc4da55f56ccp4,0x1.cd113dd73a73cp-2
+toDegrees,-0x1.94c416d548e14p2,-0x1.c420c0252959cp-4
 toDegrees,-0x1.7b02a36e7559fp5,-0x1.a75bcb9bdae6fp-1
-toDegrees,0x1.0f6e61abce825p7,0x1.2f31087c78663p1
-toDegrees,-0x1.be896265c1388p6,-0x1.f2c946a2c6a66p0
-toDegrees,-0x1.560657ad9eebdp4,-0x1.7e0b9b7822823p-2
+toDegrees,0x1.0f6e61abce826p7,0x1.2f31087c78663p1
+toDegrees,-0x1.be896265c1387p6,-0x1.f2c946a2c6a66p0
+toDegrees,-0x1.560657ad9eebcp4,-0x1.7e0b9b7822823p-2
 toDegrees,0x1.c97fc36ec2798p0,0x1.ff080809e5354p-6
 toDegrees,-0x1.231218346bfap6,-0x1.45210ae12d5dep0
-toDegrees,0x1.acd981a0f8f16p5,0x1.df07967013bfbp-1
+toDegrees,0x1.acd981a0f8f17p5,0x1.df07967013bfbp-1
 toDegrees,0x1.ffc04d8008847p5,0x1.1dd0d6e0a9014p0
 toDegrees,-0x1.22b4bf371bcefp6,-0x1.44b8c5afa5478p0
-toDegrees,-0x1.38f0f9d667f87p6,-0x1.5d8f0d930782dp0
-toDegrees,-0x1.516ecfff380abp7,-0x1.78ea87163eeabp1
+toDegrees,-0x1.38f0f9d667f88p6,-0x1.5d8f0d930782dp0
+toDegrees,-0x1.516ecfff380acp7,-0x1.78ea87163eeabp1
 toDegrees,-0x1.2ae526db45ae4p7,-0x1.4dde7a996b9c8p1
-toDegrees,-0x1.a6b4650d4c965p5,-0x1.d82a67b42deaap-1
+toDegrees,-0x1.a6b4650d4c964p5,-0x1.d82a67b42deaap-1
 toDegrees,0x1.7773b321056e7p6,0x1.a362445ee7c18p0
 toDegrees,-0x1.190c89382e7e9p4,-0x1.39ef493e52db9p-2
 toDegrees,0x1.42d69a1fb31b4p6,0x1.689d23fbea30ap0
 toDegrees,0x1.c8f48084d3c8fp6,0x1.fe6c7995f196fp0
-toDegrees,0x1.c5c438960265fp6,0x1.fadcae2a0e937p0
+toDegrees,0x1.c5c438960265ep6,0x1.fadcae2a0e937p0
 toDegrees,-0x1.a296ca69d0b03p4,-0x1.d391849fee2e3p-2
 toDegrees,-0x1.90854d79fef1ep-1,-0x1.bf62cc5fffe35p-7
 toDegrees,-0x1.8e1570b872b7ap9,-0x1.bca9effb7253dp3
@@ -3560,8 +3560,8 @@
 toDegrees,0x1.c4324f9a9f8bdp5,0x1.f91bbe117d1cp-1
 toDegrees,0x1.18467de646d62p7,0x1.3912118f3c746p1
 toDegrees,0x1.0eed528a37375p9,0x1.2ea0df6c23f34p3
-toDegrees,-0x1.450d273c40222p6,-0x1.6b15fbfe1b148p0
-toDegrees,0x1.dd9b163174e74p3,0x1.0abed2c6e1761p-2
+toDegrees,-0x1.450d273c40223p6,-0x1.6b15fbfe1b148p0
+toDegrees,0x1.dd9b163174e75p3,0x1.0abed2c6e1761p-2
 toDegrees,0x1.60880fe3738a2p3,0x1.89c80d8ae0428p-3
 toDegrees,0x1.12bfe174fb77ap2,0x1.32e5eecd756dbp-4
 toDegrees,0x1.90c57dddec21ap1,0x1.bfaa7f87fb8a7p-5
@@ -3569,10 +3569,10 @@
 toDegrees,0x1.75031f7ed32cdp6,0x1.a0a89bb3a76ap0
 toDegrees,0x1.fcb5dee07145fp4,0x1.1c1e14b2b9db4p-1
 toDegrees,0x1.69114d2c22ba8p4,0x1.9350fd1d452d5p-2
-toDegrees,-0x1.526b1f129d2c1p5,-0x1.7a045c02d25bfp-1
-toDegrees,0x1.e2dfecd8124b2p3,0x1.0db028288dd15p-2
+toDegrees,-0x1.526b1f129d2c2p5,-0x1.7a045c02d25bfp-1
+toDegrees,0x1.e2dfecd8124b1p3,0x1.0db028288dd15p-2
 toDegrees,-0x1.0dd14c6709a48p7,-0x1.2d639d6b5ce98p1
-toDegrees,0x1.2a01518efb356p6,0x1.4cdffc9db8986p0
+toDegrees,0x1.2a01518efb357p6,0x1.4cdffc9db8986p0
 toDegrees,-0x1.9bc784f0c6b48p5,-0x1.cbf643e726dd8p-1
 toDegrees,-0x1.4f0025a5e36cep6,-0x1.763300f441a5p0
 toDegrees,0x1.689f3d35e9e25p3,0x1.92d19471a60b9p-3
@@ -3581,42 +3581,42 @@
 toDegrees,-0x1.713bef68c5494p3,-0x1.9c703fc03e9d5p-3
 toDegrees,0x1.6618e48537401p3,0x1.8fff9a9c68351p-3
 toDegrees,-0x1.358164697bc5cp4,-0x1.59b88c71a52ddp-2
-toDegrees,0x1.7717dd5882015p6,0x1.a2fbafb0d679cp0
+toDegrees,0x1.7717dd5882014p6,0x1.a2fbafb0d679cp0
 toDegrees,-0x1.1b5f7b4512444p5,-0x1.3c87d8bc0f4f4p-1
 toDegrees,0x1.044ba83c26953p6,0x1.22c0be546d685p0
 toDegrees,-0x1.6d40cb9cad76ep9,-0x1.97fddbe158cc3p3
-toDegrees,0x1.3708b29f0dc25p5,0x1.5b6da41c12f38p-1
+toDegrees,0x1.3708b29f0dc24p5,0x1.5b6da41c12f38p-1
 toDegrees,-0x1.975ed02c432d9p6,-0x1.c7097d08166fp0
 toDegrees,0x1.4c557ad19a278p6,0x1.733875000be6cp0
 toDegrees,0x1.4734be48e506dp5,0x1.6d7e1dc7db526p-1
-toDegrees,0x1.485976815821dp6,0x1.6ec51657a80b1p0
+toDegrees,0x1.485976815821ep6,0x1.6ec51657a80b1p0
 toDegrees,0x1.f2596d0c82a2fp5,0x1.1654ad221e6ep0
-toDegrees,0x1.8eff75442afa9p5,0x1.bdaf56785b7cbp-1
+toDegrees,0x1.8eff75442afa8p5,0x1.bdaf56785b7cbp-1
 toDegrees,0x1.e8e4b12a2aba2p8,0x1.110caef53c05dp3
 toDegrees,-0x1.c4fa982ea8112p6,-0x1.f9fb761682d11p0
 toDegrees,0x1.1a5f7514640c3p5,0x1.3b69dd67cf39fp-1
 toDegrees,-0x1.794600ac5da92p7,-0x1.a56b21e64998p1
-toDegrees,0x1.e35d13fe74edfp5,0x1.0df60e3206348p0
+toDegrees,0x1.e35d13fe74eep5,0x1.0df60e3206348p0
 toDegrees,-0x1.c4e1b476eda0ep4,-0x1.f9dfa8cf9b3d5p-2
 toDegrees,0x1.69682c8023cc2p5,0x1.93b206aeab843p-1
 toDegrees,-0x1.6b3653d3330f4p4,-0x1.95b641b33e0c1p-2
-toDegrees,0x1.b4a966dff8b42p5,0x1.e7c17e0aedc62p-1
-toDegrees,0x1.90ec5ba49fbb5p4,0x1.bfd5e989b0585p-2
+toDegrees,0x1.b4a966dff8b41p5,0x1.e7c17e0aedc62p-1
+toDegrees,0x1.90ec5ba49fbb4p4,0x1.bfd5e989b0585p-2
 toDegrees,-0x1.e889680f077cap5,-0x1.10d9b32fdd367p0
 toDegrees,-0x1.3730338445bfcp7,-0x1.5b99c4527ddd1p1
 toDegrees,-0x1.022c00433be75p5,-0x1.20617946cc6bep-1
 toDegrees,0x1.12162302b21bp7,0x1.322853b853541p1
 toDegrees,0x1.b9be356b5ae5p6,0x1.ed6e81ec514c4p0
-toDegrees,0x1.9e768d7447387p3,0x1.cef5b0528789cp-3
-toDegrees,0x1.2adffc78f9eb4p6,0x1.4dd8b57b73478p0
+toDegrees,0x1.9e768d7447386p3,0x1.cef5b0528789cp-3
+toDegrees,0x1.2adffc78f9eb3p6,0x1.4dd8b57b73478p0
 toDegrees,-0x1.3f4e073a6bbd3p7,-0x1.64aab8cf9710fp1
 toDegrees,0x1.c0aa08f3f6bbap4,0x1.f529a80fabcc6p-2
 toDegrees,-0x1.e192542d3cd5ap2,-0x1.0cf5d76d8bc39p-3
 toDegrees,0x1.04ab229374e59p6,0x1.232b64afd152ep0
 toDegrees,-0x1.f9e0a77142ffdp-1,-0x1.1a890b24927f6p-6
 toDegrees,0x1.e97f3f3966932p5,0x1.116300d074b9bp0
-toDegrees,-0x1.1cec99f1b0757p6,-0x1.3e436f08204c9p0
-toDegrees,-0x1.7d252f6ad8e33p6,-0x1.a9be4b43df93ap0
+toDegrees,-0x1.1cec99f1b0756p6,-0x1.3e436f08204c9p0
+toDegrees,-0x1.7d252f6ad8e32p6,-0x1.a9be4b43df93ap0
 toDegrees,-0x1.8a42007322f05p3,-0x1.b863e4e12bc6fp-3
 toDegrees,-0x1.278d84dfc3f4cp4,-0x1.4a22ba5b4331p-2
 toDegrees,-0x1.ed3a5058db8abp3,-0x1.137869c4a0318p-2
@@ -3625,68 +3625,68 @@
 toDegrees,-0x1.4b23ed2f49fp5,-0x1.71e32698a8e3fp-1
 toDegrees,-0x1.df05855cfd054p8,-0x1.0b893eacbacc4p3
 toDegrees,-0x1.40573e27c281fp6,-0x1.65d2f82c221f3p0
-toDegrees,-0x1.68c5edf3d9b3ep5,-0x1.92fccc2599ddp-1
+toDegrees,-0x1.68c5edf3d9b3fp5,-0x1.92fccc2599ddp-1
 toDegrees,0x1.16f591c9d9791p7,0x1.3799b906d8ee9p1
 toDegrees,0x1.2c9a73b1f03b8p3,0x1.4fc6f2a6f562cp-3
 toDegrees,-0x1.98e03048c019dp4,-0x1.c8b7f4f73266cp-2
-toDegrees,-0x1.be6f129011c73p6,-0x1.f2abe2a2e1c9dp0
+toDegrees,-0x1.be6f129011c74p6,-0x1.f2abe2a2e1c9dp0
 toDegrees,0x1.e5d4c67fad724p8,0x1.0f56dc9cfb8ddp3
 toDegrees,0x1.e8a586d34db52p7,0x1.10e967bc9c3f8p2
 toDegrees,0x1.0acde77827a8ep7,0x1.2a05f5915fde8p1
-toDegrees,-0x1.66c7f595b3323p4,-0x1.90c327c09c62ap-2
-toDegrees,0x1.8dd01c0733ae9p4,0x1.bc5c7e80a714cp-2
+toDegrees,-0x1.66c7f595b3322p4,-0x1.90c327c09c62ap-2
+toDegrees,0x1.8dd01c0733aeap4,0x1.bc5c7e80a714cp-2
 toDegrees,0x1.1b088597a996dp6,0x1.3c26b633ca24fp0
 toDegrees,-0x1.cddf63ec90861p3,-0x1.01f55555933f7p-2
 toDegrees,-0x1.02b7b8b3d1fe1p6,-0x1.20fd8b01dd796p0
-toDegrees,-0x1.559d98a788a77p7,-0x1.7d969accdb9d9p1
+toDegrees,-0x1.559d98a788a76p7,-0x1.7d969accdb9d9p1
 toDegrees,-0x1.3f5f0d0bfb216p6,-0x1.64bdbc8a7e518p0
 toDegrees,0x1.16226547ded9dp4,0x1.36add6dc29f2ap-2
-toDegrees,0x1.d4d4543876317p3,0x1.05d7ff438dc75p-2
-toDegrees,0x1.1d28bbaefee9dp5,0x1.3e869a00f7c61p-1
-toDegrees,-0x1.86579970698fap5,-0x1.b404332954a1ep-1
-toDegrees,0x1.2ef51ad45c23bp9,0x1.52681e197503fp3
+toDegrees,0x1.d4d4543876316p3,0x1.05d7ff438dc75p-2
+toDegrees,0x1.1d28bbaefee9ep5,0x1.3e869a00f7c61p-1
+toDegrees,-0x1.86579970698fbp5,-0x1.b404332954a1ep-1
+toDegrees,0x1.2ef51ad45c23ap9,0x1.52681e197503fp3
 toDegrees,-0x1.3cf9701fe3407p6,-0x1.621052ffaaa7ap0
 toDegrees,0x1.e7244245038d5p3,0x1.10123b28dd00ap-2
-toDegrees,0x1.a5a03aa78362p5,0x1.d6f5ecd5f2423p-1
-toDegrees,0x1.e8f39b8a61b6ap3,0x1.1115038a9416bp-2
+toDegrees,0x1.a5a03aa78361fp5,0x1.d6f5ecd5f2423p-1
+toDegrees,0x1.e8f39b8a61b6bp3,0x1.1115038a9416bp-2
 toDegrees,0x1.3bf51b0182135p5,0x1.60ed87afc67a6p-1
-toDegrees,0x1.5b13311fb6c09p7,0x1.83afbbe37580cp1
+toDegrees,0x1.5b13311fb6c0ap7,0x1.83afbbe37580cp1
 toDegrees,0x1.395e71b8dc57ap9,0x1.5e09548dca6fap3
-toDegrees,0x1.b5fd9e97cb653p7,0x1.e93d84e4beffdp1
+toDegrees,0x1.b5fd9e97cb652p7,0x1.e93d84e4beffdp1
 toDegrees,0x1.0b5531c717ccdp10,0x1.2a9d14762cdbep4
-toDegrees,-0x1.0f7be127bd95dp6,-0x1.2f401c4c8c6dap0
+toDegrees,-0x1.0f7be127bd95cp6,-0x1.2f401c4c8c6dap0
 toDegrees,-0x1.f8a402b4d979cp5,-0x1.19d832498ae13p0
-toDegrees,-0x1.8d2c07dfa6e11p5,-0x1.bba537696177bp-1
+toDegrees,-0x1.8d2c07dfa6e12p5,-0x1.bba537696177bp-1
 toDegrees,-0x1.c154bc5577641p5,-0x1.f5e854bcf804bp-1
 toDegrees,-0x1.39d507bcace13p3,-0x1.5e8dcac830903p-3
 toDegrees,0x1.11e06dc88ae51p4,0x1.31ec55af95699p-2
-toDegrees,0x1.1ebf16f38b1d9p7,0x1.404c8193c1f93p1
+toDegrees,0x1.1ebf16f38b1d8p7,0x1.404c8193c1f93p1
 toDegrees,-0x1.708e7799a7b4ep4,-0x1.9bae7bc08c7c8p-2
-toDegrees,-0x1.5c8a2d06523abp9,-0x1.85529856c320fp3
-toDegrees,-0x1.5e2b963a36dp7,-0x1.8724d8fae038fp1
+toDegrees,-0x1.5c8a2d06523aap9,-0x1.85529856c320fp3
+toDegrees,-0x1.5e2b963a36cffp7,-0x1.8724d8fae038fp1
 toDegrees,0x1.3e13287c19be7p7,0x1.634b0236da71bp1
 toDegrees,0x1.a3ff712c87297p6,0x1.d5245e9b2e50cp0
 toDegrees,0x1.80d8a3f61cf0dp5,0x1.ade09c96d6ep-1
 toDegrees,0x1.cbaa19fa7d4edp5,0x1.00b99dd1e4d8ep0
 toDegrees,0x1.dc522f7f9e4e9p4,0x1.0a07215ac31f7p-1
 toDegrees,-0x1.2c3cf84f90a7ep3,-0x1.4f5e870a148f8p-3
-toDegrees,-0x1.1dc120f5ca3afp7,-0x1.3f30d4407fa7fp1
+toDegrees,-0x1.1dc120f5ca3aep7,-0x1.3f30d4407fa7fp1
 toDegrees,0x1.6e2c3ba13a4d3p5,0x1.9904d85ecc7c9p-1
 toDegrees,-0x1.ea38a3aa95e47p7,-0x1.11ca8bb9c2c15p2
 toDegrees,-0x1.322c04414ec4cp8,-0x1.55ff51a36f15dp2
 toDegrees,-0x1.4fe90d155a88dp6,-0x1.773728f881204p0
-toDegrees,0x1.ff58a2d82d4b1p8,0x1.1d96f0e567a04p3
+toDegrees,0x1.ff58a2d82d4bp8,0x1.1d96f0e567a04p3
 toDegrees,-0x1.a25d798c48c75p5,-0x1.d3517ee076ecap-1
 toDegrees,0x1.6c39408ca491fp4,0x1.96d77a72adc61p-2
-toDegrees,0x1.58be156cc8725p7,0x1.8114c1f74781cp1
-toDegrees,-0x1.45cb34c0c3921p3,-0x1.6bea467e50e53p-3
-toDegrees,0x1.cf7a84939fa02p6,0x1.02daf3455c5ebp1
+toDegrees,0x1.58be156cc8724p7,0x1.8114c1f74781cp1
+toDegrees,-0x1.45cb34c0c392p3,-0x1.6bea467e50e53p-3
+toDegrees,0x1.cf7a84939fa03p6,0x1.02daf3455c5ebp1
 toDegrees,0x1.c8d9ec779379ap5,0x1.fe4ec9630f342p-1
 toDegrees,0x1.40f290dd23f99p5,0x1.6680778b4b4dbp-1
 toDegrees,-0x1.d007e807137ccp5,-0x1.0329ea9fd53c5p0
 toDegrees,-0x1.0b45c757e1c32p5,-0x1.2a8bdc408764ap-1
 toDegrees,-0x1.260688556fd89p3,-0x1.486dfdea7261dp-3
-toDegrees,-0x1.e5e3535741671p8,-0x1.0f5efcf51e5d2p3
+toDegrees,-0x1.e5e3535741672p8,-0x1.0f5efcf51e5d2p3
 toDegrees,-0x1.0086c685a5706p6,-0x1.1e8af5d50c276p0
 toDegrees,0x1.57a34296c3044p7,0x1.7fd8d738cb1ddp1
 toDegrees,0x1.2a33a57def28bp7,0x1.4d18341b9bfep1
@@ -3694,13 +3694,13 @@
 toDegrees,0x1.7128c6132b42ap3,0x1.9c5ad8709aa79p-3
 toDegrees,-0x1.688e096df3805p7,-0x1.92be5d5f8c398p1
 toDegrees,0x1.000dfdac23b5cp3,0x1.1e040ae962b82p-3
-toDegrees,-0x1.1af109f43a815p5,-0x1.3c0c7b234319cp-1
+toDegrees,-0x1.1af109f43a816p5,-0x1.3c0c7b234319cp-1
 toDegrees,0x1.fc9f8ecba486dp6,0x1.1c119e785bc66p1
 toDegrees,-0x1.aab953e1cd1d7p5,-0x1.dca7bbf503ce4p-1
 toDegrees,-0x1.5e8928b59890ep7,-0x1.878d5e64a5e27p1
 toDegrees,0x1.836a93ac41202p3,0x1.b0bf889de387cp-3
 toDegrees,0x1.3b7cdcc880872p6,0x1.6067379d26339p0
-toDegrees,0x1.c8056c371e64dp5,0x1.fd616bb8f3785p-1
+toDegrees,0x1.c8056c371e64cp5,0x1.fd616bb8f3785p-1
 toDegrees,-0x1.ec401ac74c4bcp4,-0x1.12ecab81b3564p-1
 toDegrees,-0x1.ca28aa208a7a4p5,-0x1.ffc4b21fba5b4p-1
 toDegrees,-0x1.1a006a6cef937p6,-0x1.3affb3cdd2bf1p0
@@ -3716,17 +3716,17 @@
 toDegrees,-0x1.2eb22726e4acdp3,-0x1.521d54e55310dp-3
 toDegrees,-0x1.3ef9ae1414208p7,-0x1.644c8107f5d37p1
 toDegrees,-0x1.2a6babb40908dp8,-0x1.4d56c882fd11ap2
-toDegrees,-0x1.6eb2ba40302ebp4,-0x1.999b13be37afp-2
+toDegrees,-0x1.6eb2ba40302eap4,-0x1.999b13be37afp-2
 toDegrees,-0x1.1f825cdc83933p8,-0x1.4126a0d7b7ec8p2
 toDegrees,0x1.196d47a93599dp6,0x1.3a5b599fc865dp0
-toDegrees,-0x1.152cb9e9e5ap2,-0x1.359b6c87594cep-4
+toDegrees,-0x1.152cb9e9e59ffp2,-0x1.359b6c87594cep-4
 toDegrees,0x1.e8033ad066cefp5,0x1.108ec2f31fd2p0
 toDegrees,-0x1.380d292404d8ap1,-0x1.5c9094bb0fa5ap-5
 toDegrees,-0x1.e3b0170b51c6cp8,-0x1.0e246b0558ec9p3
-toDegrees,0x1.5292d8b4c17e7p7,0x1.7a30bb99bbf7ap1
+toDegrees,0x1.5292d8b4c17e6p7,0x1.7a30bb99bbf7ap1
 toDegrees,0x1.a643cd81be412p8,0x1.d7aca37eb05a1p2
-toDegrees,-0x1.6202c5199be34p2,-0x1.8b6f12d9e8ceap-4
-toDegrees,-0x1.5c58d80880982p5,-0x1.851b7d9eba78dp-1
+toDegrees,-0x1.6202c5199be33p2,-0x1.8b6f12d9e8ceap-4
+toDegrees,-0x1.5c58d80880983p5,-0x1.851b7d9eba78dp-1
 toDegrees,-0x1.43b8e1a23e479p7,-0x1.6999e5a23a02fp1
 toDegrees,-0x1.8815f8f42cea6p5,-0x1.b5f6cdab230d6p-1
 toDegrees,-0x1.4bf63f89b2173p7,-0x1.72ce151501a48p1
@@ -3735,18 +3735,18 @@
 toRadians,-0x1.269dd1f61b4dfp-6,-0x1.07c11fe9ef09ap0
 toRadians,0x1.8f9413ec4afd4p-5,0x1.65b8a1590af12p1
 toRadians,-0x1.d5e34359a07fep-6,-0x1.a4aa56bfa319bp0
-toRadians,0x1.dccef5cda0302p-8,0x1.aadc71cf68e4p-2
+toRadians,0x1.dccef5cda0303p-8,0x1.aadc71cf68e4p-2
 toRadians,-0x1.756bb6c6074bp-6,-0x1.4e4dbbcc2fa9fp0
 toRadians,0x1.bd04cff56f47ep-7,0x1.8e66cbb71fd56p-1
 toRadians,0x1.78fefa23b96fap-6,0x1.51811ea8e898bp0
 toRadians,0x1.0d4d232276716p-6,0x1.e22ea197722cep-1
 toRadians,-0x1.33d9fd2988496p-4,-0x1.139a5efe42b6ap2
-toRadians,-0x1.229982e2b8d7cp-5,-0x1.042888e04d436p1
+toRadians,-0x1.229982e2b8d7dp-5,-0x1.042888e04d436p1
 toRadians,-0x1.29c7dd4973314p-6,-0x1.0a965060eb912p0
 toRadians,0x1.20d720e76b068p-5,0x1.029554c15c57ap1
 toRadians,0x1.7f5bf73fdde9cp-7,0x1.5733775f2d25p-1
 toRadians,0x1.42170369d60b3p-4,0x1.2059910e0b436p2
-toRadians,0x1.a8b0ae7ecdabdp-3,0x1.7c33d0cf9cf15p3
+toRadians,0x1.a8b0ae7ecdabep-3,0x1.7c33d0cf9cf15p3
 toRadians,0x1.630ea69bd5949p-5,0x1.3ddd1f7cf69b8p1
 toRadians,0x1.7f69b05ec6601p-3,0x1.573fc07b23f0dp3
 toRadians,0x1.af6c649a981abp-5,0x1.823af65afedeap1
@@ -3755,7 +3755,7 @@
 toRadians,0x1.5fc99f56b4abap-7,0x1.3aefc6b5b91b7p-1
 toRadians,-0x1.517b699ec7bep-4,-0x1.2e21320a4ff91p2
 toRadians,-0x1.0bb8960d4d455p-7,-0x1.df5a490650c4ap-2
-toRadians,-0x1.ec1e137eb7753p-7,-0x1.b891050802839p-1
+toRadians,-0x1.ec1e137eb7754p-7,-0x1.b891050802839p-1
 toRadians,0x1.29829f741d254p-6,0x1.0a5853632a0e3p0
 toRadians,-0x1.4f91fde8cb341p-6,-0x1.2c6b0b115881dp0
 toRadians,0x1.33d962b6df19p-6,0x1.1399d4b969204p0
@@ -3763,7 +3763,7 @@
 toRadians,0x1.8a562054567fdp-5,0x1.610740b5d01cbp1
 toRadians,-0x1.f38e2489f0cc6p-9,-0x1.bf39a0f24dfa5p-3
 toRadians,0x1.d8241c6f90ae7p-6,0x1.a6aec291de8e6p0
-toRadians,0x1.ea933e48ad7p-7,0x1.b72f8c019babcp-1
+toRadians,0x1.ea933e48ad701p-7,0x1.b72f8c019babcp-1
 toRadians,0x1.3a4dc8294ed8p-7,0x1.1961220e2d1bfp-1
 toRadians,-0x1.19ba22c2bb686p-7,-0x1.f86e2feb49188p-2
 toRadians,-0x1.85b38b279cecbp-9,-0x1.5ce0f7fbeaff5p-3
@@ -3784,87 +3784,87 @@
 toRadians,-0x1.3a41e6900b66ep-7,-0x1.19567f131b0b3p-1
 toRadians,0x1.ef7b1d4585839p-6,0x1.bb93dc72c9319p0
 toRadians,0x1.62d84b7aedaa3p-5,0x1.3dac76046aacep1
-toRadians,-0x1.0f20042155341p-6,-0x1.e572931c5417bp-1
+toRadians,-0x1.0f2004215534p-6,-0x1.e572931c5417bp-1
 toRadians,-0x1.690ea94f0a1b8p-6,-0x1.433c3b2cb5df1p0
-toRadians,-0x1.94c307b06c295p-8,-0x1.6a5c9464a575dp-2
-toRadians,-0x1.c7c50a49a546cp-9,-0x1.9806b7e00001p-3
-toRadians,0x1.73099f305d1fep-4,0x1.4c2b8cfb45c8bp2
+toRadians,-0x1.94c307b06c294p-8,-0x1.6a5c9464a575dp-2
+toRadians,-0x1.c7c50a49a546bp-9,-0x1.9806b7e00001p-3
+toRadians,0x1.73099f305d1fdp-4,0x1.4c2b8cfb45c8bp2
 toRadians,-0x1.389be50a6fd97p-8,-0x1.17dcb26fb38ap-2
 toRadians,0x1.5fbc85728b899p-8,0x1.3ae40c2677db1p-2
 toRadians,0x1.ef94c7f3a2ecfp-6,0x1.bbaad6d3bf4d2p0
 toRadians,-0x1.8f2d697a05737p-9,-0x1.655cb8140865dp-3
-toRadians,0x1.b20508bdffb78p-5,0x1.848dfae3dca6ep1
+toRadians,0x1.b20508bdffb79p-5,0x1.848dfae3dca6ep1
 toRadians,-0x1.bdb35ca54ab81p-7,-0x1.8f030f8701c68p-1
 toRadians,0x1.0861b9ad91254p-5,0x1.d95fa9ae542c1p0
-toRadians,0x1.a76bd0ab65c66p-7,0x1.7b10fae457027p-1
+toRadians,0x1.a76bd0ab65c67p-7,0x1.7b10fae457027p-1
 toRadians,0x1.54c5e8e9a7843p-7,0x1.3113702f0fc4fp-1
 toRadians,-0x1.13d8a20895e4fp0,-0x1.ede6983faab45p5
 toRadians,-0x1.cebc35c4a890bp-8,-0x1.9e43184cdea2ap-2
-toRadians,0x1.3d3e1280d3313p-4,0x1.1c029e507fabcp2
+toRadians,0x1.3d3e1280d3314p-4,0x1.1c029e507fabcp2
 toRadians,-0x1.5f6a1f54ab2a4p-7,-0x1.3a9a47b707798p-1
 toRadians,-0x1.3c0058e027e76p-6,-0x1.1ae62d156322p0
 toRadians,0x1.91a20082f74adp-3,0x1.678f764a36e11p3
 toRadians,0x1.5a7a88c4fde6ep-8,0x1.362f0ea5bddffp-2
-toRadians,-0x1.dd2d62c4677b5p-7,-0x1.ab30fa92aab8ep-1
-toRadians,0x1.c090beda0a1ebp-4,0x1.91939eabe933ep2
-toRadians,-0x1.fa64fbfece91ep-8,-0x1.c559104a2fc35p-2
+toRadians,-0x1.dd2d62c4677b6p-7,-0x1.ab30fa92aab8ep-1
+toRadians,0x1.c090beda0a1eap-4,0x1.91939eabe933ep2
+toRadians,-0x1.fa64fbfece91fp-8,-0x1.c559104a2fc35p-2
 toRadians,0x1.03e06cf40987fp-6,0x1.d14eb0092067dp-1
 toRadians,-0x1.9e2d350067dbbp-8,-0x1.72ca4846014p-2
 toRadians,0x1.2b149a9831e4ep-2,0x1.0bc032a6985a2p4
 toRadians,-0x1.eb36b025b1424p-7,-0x1.b7c1deca5038ep-1
 toRadians,-0x1.581a480c8d362p-4,-0x1.340e855ef1af6p2
 toRadians,-0x1.0c3f652158269p-7,-0x1.e04ba8df602b9p-2
-toRadians,-0x1.309379cfc0976p-11,-0x1.10abb1f2f2834p-5
+toRadians,-0x1.309379cfc0977p-11,-0x1.10abb1f2f2834p-5
 toRadians,0x1.3f6a7aa234715p-7,0x1.1df4bd59b7a1fp-1
 toRadians,-0x1.65dd0dca04ae2p-7,-0x1.40604556bbc5ap-1
-toRadians,-0x1.69934495b8f4ap-6,-0x1.43b2f25b4c342p0
+toRadians,-0x1.69934495b8f4bp-6,-0x1.43b2f25b4c342p0
 toRadians,-0x1.f6766633423b6p-7,-0x1.c1d3ebf82f78ep-1
-toRadians,0x1.4c96adb0ee339p-6,0x1.29bfb0889a191p0
+toRadians,0x1.4c96adb0ee33ap-6,0x1.29bfb0889a191p0
 toRadians,0x1.51c4cc005ef3ep-7,0x1.2e62e47bbc5f8p-1
 toRadians,-0x1.37fcc828121c6p-8,-0x1.174e407648858p-2
 toRadians,0x1.3c85a053a8dbfp-6,0x1.1b5d7e6798ac9p0
 toRadians,0x1.2fa1707ca7533p-6,0x1.0fd303496037ep0
 toRadians,-0x1.fd30ff4ab5bb4p-8,-0x1.c7da125a7e8cp-2
-toRadians,-0x1.07053d4647f61p-3,-0x1.d6efb37cbda3cp2
+toRadians,-0x1.07053d4647f62p-3,-0x1.d6efb37cbda3cp2
 toRadians,0x1.2e6539dacf422p-6,0x1.0eb7ec831448p0
 toRadians,0x1.90768a6c41a28p-6,0x1.66835ed1b0038p0
-toRadians,-0x1.3b5f769af4c14p-9,-0x1.1a5625378947dp-3
+toRadians,-0x1.3b5f769af4c15p-9,-0x1.1a5625378947dp-3
 toRadians,0x1.5e2305a747b1bp-7,0x1.397571d90c1e8p-1
 toRadians,-0x1.9684bb151928dp-6,-0x1.6bef2c36e0214p0
 toRadians,0x1.80aab10e1f8a3p-10,0x1.585f20e007884p-4
-toRadians,-0x1.73454254905c1p-9,-0x1.4c60f0d6580cep-3
+toRadians,-0x1.73454254905cp-9,-0x1.4c60f0d6580cep-3
 toRadians,-0x1.64e173018ac6bp-6,-0x1.3f7f05ce9fc63p0
 toRadians,0x1.6c33df8f50558p-9,0x1.460d18271bc01p-3
 toRadians,-0x1.a66398e8cab57p-11,-0x1.7a2470a132a52p-5
-toRadians,-0x1.4044a3024d4c3p-6,-0x1.1eb80b6a865f3p0
+toRadians,-0x1.4044a3024d4c4p-6,-0x1.1eb80b6a865f3p0
 toRadians,0x1.a5edecbd257d2p-7,0x1.79bb1811e0512p-1
 toRadians,0x1.2f63061aafa03p-9,0x1.0f9b22b1cf7b8p-3
 toRadians,0x1.57a84a0a48335p-6,0x1.33a878472947cp0
 toRadians,-0x1.1fbadf0bde297p-5,-0x1.0196d9ca7dd6dp1
-toRadians,0x1.0579eb2f75c14p-5,0x1.d42be1d80dafap0
-toRadians,0x1.4bb08a6dddaffp-10,0x1.28f1a8d929a18p-4
+toRadians,0x1.0579eb2f75c15p-5,0x1.d42be1d80dafap0
+toRadians,0x1.4bb08a6dddafep-10,0x1.28f1a8d929a18p-4
 toRadians,-0x1.785e5c8f3248bp-6,-0x1.50f15449acabep0
 toRadians,0x1.7c2e98ed7c20ap-6,0x1.545b4d0e37923p0
 toRadians,0x1.8afa8d5f6beb4p-7,0x1.619a745cb9468p-1
 toRadians,0x1.9ab81ca6e2142p-7,0x1.6fb1e76a3d452p-1
 toRadians,0x1.5abbd97d5f2dfp-8,0x1.366987d08a848p-2
 toRadians,0x1.10b1ed52fa65ap-5,0x1.e8423180e2757p0
-toRadians,0x1.1977488637e48p-7,0x1.f7f67cff2be2p-2
+toRadians,0x1.1977488637e49p-7,0x1.f7f67cff2be2p-2
 toRadians,-0x1.ea464cd97d49ep-5,-0x1.b6eaa9f230e9ap1
-toRadians,0x1.b91c40b587a6dp-4,0x1.8ae70c5a81ab4p2
-toRadians,0x1.4437a94ee4aa7p-5,0x1.2241293012d19p1
+toRadians,0x1.b91c40b587a6ep-4,0x1.8ae70c5a81ab4p2
+toRadians,0x1.4437a94ee4aa6p-5,0x1.2241293012d19p1
 toRadians,0x1.f5efccce5b07bp-6,0x1.c15b6c1b274d9p0
-toRadians,-0x1.9f99237013c3ep-9,-0x1.741017345ad98p-3
+toRadians,-0x1.9f99237013c3dp-9,-0x1.741017345ad98p-3
 toRadians,-0x1.0973876df224ap-6,-0x1.db49e80f5e81ep-1
 toRadians,0x1.6fa164f8ba5d2p-6,0x1.491eb12f08f23p0
 toRadians,0x1.6c2759fa3c865p-9,0x1.4601e25dc1082p-3
 toRadians,-0x1.9e741ead7ac95p-9,-0x1.7309c44a173a5p-3
 toRadians,0x1.9030fa34f406dp-6,0x1.664518133618ep0
-toRadians,-0x1.efe26ef81c43dp-4,-0x1.bbf05b72f4d36p2
-toRadians,-0x1.f34430fc0f19fp-7,-0x1.bef76c89ad7e8p-1
+toRadians,-0x1.efe26ef81c43ep-4,-0x1.bbf05b72f4d36p2
+toRadians,-0x1.f34430fc0f19ep-7,-0x1.bef76c89ad7e8p-1
 toRadians,-0x1.2cbb12850bd1p-6,-0x1.0d3a694a092f3p0
-toRadians,-0x1.6ca79b649b4dap-6,-0x1.4674b45e4bef9p0
-toRadians,-0x1.5ed33ec70db7ap-6,-0x1.3a1335377f47p0
+toRadians,-0x1.6ca79b649b4dbp-6,-0x1.4674b45e4bef9p0
+toRadians,-0x1.5ed33ec70db7bp-6,-0x1.3a1335377f47p0
 toRadians,0x1.4bb2ac4bfd435p0,0x1.28f39188d12e9p6
 toRadians,-0x1.1e73f51abbca9p-5,-0x1.00722ea8a6779p1
 toRadians,0x1.50359082fe9fap-6,0x1.2cfd7b2947624p0
@@ -3880,41 +3880,41 @@
 toRadians,0x1.52c145c51ab79p0,0x1.2f44eba454717p6
 toRadians,-0x1.5082c8921deefp-5,-0x1.2d429c72b1d75p1
 toRadians,0x1.288a3adfc8e7ap-5,0x1.0979f3ee43321p1
-toRadians,-0x1.ef75b508090c5p-8,-0x1.bb8f05364e233p-2
+toRadians,-0x1.ef75b508090c6p-8,-0x1.bb8f05364e233p-2
 toRadians,0x1.365709f9e92dbp-5,0x1.15d4b01c6f66fp1
-toRadians,0x1.bd29cf8766e9fp-8,0x1.8e87eb1b1cb6ap-2
-toRadians,0x1.5705e9472736dp-10,0x1.331719fc9f227p-4
+toRadians,0x1.bd29cf8766eap-8,0x1.8e87eb1b1cb6ap-2
+toRadians,0x1.5705e9472736ep-10,0x1.331719fc9f227p-4
 toRadians,-0x1.c0f0760371a15p-5,-0x1.91e94f0aeb6fdp1
 toRadians,0x1.aa4b9d7189cd6p-11,0x1.7da3b3ce92d0bp-5
-toRadians,-0x1.e36f3239795c7p-7,-0x1.b0cafe786941p-1
+toRadians,-0x1.e36f3239795c8p-7,-0x1.b0cafe786941p-1
 toRadians,-0x1.5d453f9711567p-6,-0x1.38aee7103062ap0
-toRadians,0x1.4f5935250958dp-9,0x1.2c3835144a6c6p-3
-toRadians,-0x1.fc315cc3236d5p-5,-0x1.c6f5372783487p1
+toRadians,0x1.4f5935250958cp-9,0x1.2c3835144a6c6p-3
+toRadians,-0x1.fc315cc3236d6p-5,-0x1.c6f5372783487p1
 toRadians,-0x1.5f6f0db8815dcp-11,-0x1.3a9eb1dd80ae8p-5
 toRadians,0x1.044ced10f50cep-6,0x1.d210f4f97b4fap-1
 toRadians,-0x1.0820c249570a6p-12,-0x1.d8eb574a001cap-7
-toRadians,0x1.c0dce341827e4p-7,0x1.91d7c92de11e9p-1
-toRadians,-0x1.54c0758b47cf8p-5,-0x1.310e8efc1fc1dp1
+toRadians,0x1.c0dce341827e5p-7,0x1.91d7c92de11e9p-1
+toRadians,-0x1.54c0758b47cf9p-5,-0x1.310e8efc1fc1dp1
 toRadians,-0x1.0c22f069d37e6p-6,-0x1.e018b5a31fb2cp-1
 toRadians,-0x1.0d44d90e1098cp-6,-0x1.e21fca05c552fp-1
 toRadians,0x1.aa370725bfc19p-6,0x1.7d914597b0f93p0
-toRadians,0x1.5dae1ab6a26cap-8,0x1.390cc646e30c2p-2
+toRadians,0x1.5dae1ab6a26cbp-8,0x1.390cc646e30c2p-2
 toRadians,-0x1.93d8aca9afc4cp-6,-0x1.698ac60d72cfap0
-toRadians,0x1.dde50e06e847bp-8,0x1.abd568673b34cp-2
-toRadians,0x1.85367605681f8p-8,0x1.5c70fd2cabf94p-2
+toRadians,0x1.dde50e06e847cp-8,0x1.abd568673b34cp-2
+toRadians,0x1.85367605681f9p-8,0x1.5c70fd2cabf94p-2
 toRadians,0x1.0f398ad1f05d4p-6,0x1.e5a0476d86f65p-1
 toRadians,-0x1.d61f59195aa6cp-7,-0x1.a4e02134d1a6bp-1
 toRadians,-0x1.2ea0ffdaa0e6p-6,-0x1.0eed6f92fd525p0
-toRadians,-0x1.ed05911e835b4p-7,-0x1.b96042cbd3729p-1
+toRadians,-0x1.ed05911e835b5p-7,-0x1.b96042cbd3729p-1
 toRadians,0x1.2cd0b41a46717p-3,0x1.0d4dc6ca8eaa8p3
 toRadians,0x1.381d20fe74a4p-6,0x1.176b35da6d972p0
 toRadians,-0x1.135812197a196p-5,-0x1.ed0067a8591e4p0
-toRadians,0x1.9487e02c71b95p-4,0x1.6a279f36895cap2
-toRadians,0x1.2f1b98fbb5e38p-7,0x1.0f5b3100c4226p-1
+toRadians,0x1.9487e02c71b94p-4,0x1.6a279f36895cap2
+toRadians,0x1.2f1b98fbb5e37p-7,0x1.0f5b3100c4226p-1
 toRadians,-0x1.df126097b8ce9p-10,-0x1.ace32a703c8p-4
 toRadians,0x1.27602746d31p-5,0x1.086f19d122d5p1
 toRadians,-0x1.6f00c2e92cd4ep-7,-0x1.488ee2ccee45dp-1
-toRadians,-0x1.6d6cad1da49f1p-8,-0x1.4725214f128bcp-2
+toRadians,-0x1.6d6cad1da49f2p-8,-0x1.4725214f128bcp-2
 toRadians,0x1.53853b6e52504p-6,0x1.2ff45a46f0239p0
 toRadians,-0x1.35bedb84f10a2p-6,-0x1.154c72afce441p0
 toRadians,0x1.e5b425177b774p-8,0x1.b2d3161ad8a1fp-2
@@ -3922,14 +3922,14 @@
 toRadians,0x1.9e42202419179p-7,0x1.72dd02718e33ep-1
 toRadians,0x1.91ed5a574b502p-7,0x1.67d2eb7176ee9p-1
 toRadians,0x1.88624a4753cb9p-5,0x1.5f47c6b4bedb7p1
-toRadians,-0x1.88c9a0d956ca6p-10,-0x1.5fa44a11aabe3p-4
+toRadians,-0x1.88c9a0d956ca7p-10,-0x1.5fa44a11aabe3p-4
 toRadians,-0x1.a5a8e50293634p-8,-0x1.797d4b83f869p-2
 toRadians,-0x1.aee96588d5d7ap-6,-0x1.81c5b0333bb09p0
-toRadians,-0x1.a0bb132c02b9p-7,-0x1.7513a7bf2c3eep-1
+toRadians,-0x1.a0bb132c02b91p-7,-0x1.7513a7bf2c3eep-1
 toRadians,-0x1.159284ff767c1p-2,-0x1.f0fdca230f3f5p3
 toRadians,0x1.6ec5baab9dfccp-7,0x1.485a099e8a8a4p-1
 toRadians,-0x1.479fe44ef6b39p-4,-0x1.254e05afbfe62p2
-toRadians,0x1.0ce113f6e801dp-4,0x1.e16d26e044eb6p1
+toRadians,0x1.0ce113f6e801cp-4,0x1.e16d26e044eb6p1
 ulp,0x1.0p-52,-0x1.9369810dd84a3p0
 ulp,0x1.0p-54,-0x1.9f2928d31e01cp-2
 ulp,0x1.0p-51,-0x1.73ea1caeccadfp1
diff --git a/metrictests/memory/apps/Android.bp b/metrictests/memory/apps/Android.bp
index 480886e..4c13689 100644
--- a/metrictests/memory/apps/Android.bp
+++ b/metrictests/memory/apps/Android.bp
@@ -12,6 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_license"],
+}
+
 android_test_helper_app {
     name: "LibcoreHeapDumper",
     sdk_version: "current",
diff --git a/metrictests/memory/host/Android.bp b/metrictests/memory/host/Android.bp
index beed9e1..10ee832 100644
--- a/metrictests/memory/host/Android.bp
+++ b/metrictests/memory/host/Android.bp
@@ -12,6 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_license"],
+}
+
 java_test_host {
     name: "libcore-memory-metrics-tests",
     srcs: ["src/**/*.java"],
@@ -20,4 +28,7 @@
         "ahat",
     ],
     test_suites: ["general-tests"],
+    test_options: {
+        unit_test: false,
+    },
 }
diff --git a/mmodules/core_platform_api/Android.bp b/mmodules/core_platform_api/Android.bp
index f2a042b..d7988ea 100644
--- a/mmodules/core_platform_api/Android.bp
+++ b/mmodules/core_platform_api/Android.bp
@@ -19,71 +19,131 @@
 // The API specification .txt files managed by this only contain the additional
 // classes/members that are in the intra-core API but which are not in the public
 // API.
-droidstubs {
-    name: "art-module-platform-api-stubs-source",
+//
+// There are two versions of the API surface. The "stable" version contains the
+// APIs which are considered stable, and is indicated in source with the
+// annotation @CorePlatformApi(status = CorePlatformApi.Status.STABLE). The
+// "legacy" version also includes those which have not been audited for stability
+// or which are deprecated (which have the default status of LEGACY_ONLY).
+//
+// TODO(b/161973015): Remove the legacy/stable distinction once no longer useful.
+
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-GPL
+    //   SPDX-license-identifier-GPL-2.0
+    //   SPDX-license-identifier-LGPL
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-W3C
+    default_applicable_licenses: ["libcore_license"],
+}
+
+java_defaults {
+    name: "art-module-platform-api-defaults",
     srcs: [
         ":art_module_api_files",
     ],
-    sdk_version: "none",
-    system_modules: "none",
-    libs: [
-        // Needed to break the cycle in the platform api caused by
-        // b/141747409.
-        "i18n.module.intra.core.api.stubs",
+    api_only: true,
+    droiddoc_options: [
+        "--hide HiddenSuperclass",
+        "--hide-annotation libcore.api.Hide",
+        "--skip-annotation-instance-methods=false",
+        "--force-convert-to-warning-nullability-annotations +*:-android.*:+android.icu.*:-dalvik.* ",
     ],
-
-    installable: false,
-    args: "--hide HiddenSuperclass " +
-        "--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",
+    // Emit nullability annotations from the source to the stub files.
+    annotations_enabled: true,
 
-    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 special set of system modules that is needed to break the cycle in the
-// platform api caused by b/141747409.
-java_system_modules {
-    name: "break-cycle-in-core-platform-system-modules",
-    libs: [
-        "art.module.intra.core.api.stubs",
-        "i18n.module.intra.core.api.stubs",
+    merge_annotations_dirs: [
+        "metalava-manual",
+        "ojluni-annotated-sdk-stubs",
     ],
-}
-
-// A library containing the core platform API stubs of the ART module.
-//
-// Core platform APIs are only intended for use of other parts of the platform, not the
-// core library modules.
-java_library {
-    name: "art.module.platform.api.stubs",
-    srcs: [
-        ":art-module-platform-api-stubs-source",
-    ],
-    hostdex: true,
 
     sdk_version: "none",
-    system_modules: "break-cycle-in-core-platform-system-modules",
+    system_modules: "none",
     patch_module: "java.base",
+    dist_group: "android",
+    unsafe_ignore_missing_latest_api: true,
 }
 
-// Used when compiling higher-level code against core.platform.api.stubs.
+// Referenced implicitly from legacy.art.module.platform.api.
+filegroup {
+    name: "legacy.art.module.platform.api.api.public.latest",
+    srcs: [
+        "api/legacy_platform/last-api.txt",
+    ],
+}
+
+// Referenced implicitly from legacy.art.module.platform.api.
+filegroup {
+    name: "legacy.art.module.platform.api-removed.api.public.latest",
+    srcs: [
+        "api/legacy_platform/last-removed.txt",
+    ],
+}
+
+// Referenced implicitly from legacy.art.module.platform.api.
+filegroup {
+    name: "legacy.art.module.platform.api-incompatibilities.api.public.latest",
+    srcs: [
+        "api/legacy_platform/last-incompatibilities.txt",
+    ],
+}
+
+java_sdk_library {
+    name: "legacy.art.module.platform.api",
+    defaults: ["art-module-platform-api-defaults"],
+    api_dir: "api/legacy_platform",
+    droiddoc_options: [
+        "--show-single-annotation libcore.api.CorePlatformApi",
+    ],
+
+    // Make dex jars for the stubs available for use by hiddenapi processing.
+    compile_dex: true,
+    dist_stem: "art-coreplatform-legacy",
+}
+
+// Referenced implicitly from stable.art.module.platform.api.
+filegroup {
+    name: "stable.art.module.platform.api.api.public.latest",
+    srcs: [
+        "api/stable_platform/last-api.txt",
+    ],
+}
+
+// Referenced implicitly from stable.art.module.platform.api.
+filegroup {
+    name: "stable.art.module.platform.api-removed.api.public.latest",
+    srcs: [
+        "api/stable_platform/last-removed.txt",
+    ],
+}
+
+// Referenced implicitly from stable.art.module.platform.api.
+filegroup {
+    name: "stable.art.module.platform.api-incompatibilities.api.public.latest",
+    srcs: [
+        "api/stable_platform/last-incompatibilities.txt",
+    ],
+}
+
+java_sdk_library {
+    name: "stable.art.module.platform.api",
+    defaults: ["art-module-platform-api-defaults"],
+    api_dir: "api/stable_platform",
+    droiddoc_options: [
+        "--show-single-annotation libcore.api.CorePlatformApi\\(status=libcore.api.CorePlatformApi.Status.STABLE\\)",
+    ],
+    dist_stem: "art-coreplatform-stable",
+}
+
+// Used when compiling higher-level code against *.core.platform.api.stubs.
 java_system_modules {
-    name: "art-module-platform-api-stubs-system-modules",
+    name: "legacy-art-module-platform-api-stubs-system-modules",
     visibility: [
         "//art/build/sdk",
         "//external/conscrypt",
@@ -91,23 +151,36 @@
         "//external/wycheproof",
     ],
     libs: [
-        "art.module.platform.api.stubs",
+        "legacy.art.module.platform.api.stubs",
     ],
 }
 
-// Ideally this should be a restricted whitelist but there are hundreds of modules that depend on
+java_system_modules {
+    name: "stable-art-module-platform-api-stubs-system-modules",
+    visibility: [
+        "//art/build/sdk",
+        "//external/conscrypt",
+        "//external/icu/android_icu4j",
+        "//external/wycheproof",
+    ],
+    libs: [
+        "stable.art.module.platform.api.stubs",
+    ],
+}
+
+// Ideally this should be a restricted allowlist but there are hundreds of modules that depend on
 // this.
 // TODO(http://b/134561230) - limit the number of dependents on this.
 core_platform_visibility = ["//visibility:public"]
 
-// A library containing the core platform API stubs for the core libraries.
+// Libraries containing the core platform API stubs for the core libraries.
 //
 // 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",
+    name: "legacy.core.platform.api.stubs",
     visibility: core_platform_visibility,
     hostdex: true,
     compile_dex: true,
@@ -115,19 +188,52 @@
     sdk_version: "none",
     system_modules: "none",
     static_libs: [
-        "art.module.platform.api.stubs",
+        "legacy.art.module.platform.api.stubs",
         "conscrypt.module.platform.api.stubs",
-        "i18n.module.platform.api.stubs",
+        "legacy.i18n.module.platform.api.stubs",
     ],
     patch_module: "java.base",
 }
 
-// Used when compiling higher-level code against core.platform.api.stubs.
+java_library {
+    name: "stable.core.platform.api.stubs",
+    visibility: core_platform_visibility,
+    hostdex: true,
+    compile_dex: true,
+
+    sdk_version: "none",
+    system_modules: "none",
+    static_libs: [
+        "stable.art.module.platform.api.stubs",
+        // conscrypt only has a stable version, so it is okay to depend on it here:
+        "conscrypt.module.platform.api.stubs",
+        "stable.i18n.module.platform.api.stubs",
+    ],
+    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",
+    name: "legacy-core-platform-api-stubs-system-modules",
     visibility: core_platform_visibility,
     libs: [
-        "core.platform.api.stubs",
+        "legacy.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",
+        // This one is not on device but it's needed when javac compiles code
+        // containing @Generated annotations produced by some code generation
+        // tools.
+        // See http://b/123891440.
+        "core-generated-annotation-stubs",
+    ],
+}
+
+java_system_modules {
+    name: "stable-core-platform-api-stubs-system-modules",
+    visibility: core_platform_visibility,
+    libs: [
+        "stable.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/legacy_platform/current.txt b/mmodules/core_platform_api/api/legacy_platform/current.txt
new file mode 100644
index 0000000..28a8915
--- /dev/null
+++ b/mmodules/core_platform_api/api/legacy_platform/current.txt
@@ -0,0 +1,884 @@
+// Signature format: 2.0
+package android.compat {
+
+  public final class Compatibility {
+    method public static void clearBehaviorChangeDelegate();
+    method public static void clearOverrides();
+    method public static boolean isChangeEnabled(long);
+    method public static void reportUnconditionalChange(long);
+    method public static void setBehaviorChangeDelegate(android.compat.Compatibility.BehaviorChangeDelegate);
+    method public static void setOverrides(android.compat.Compatibility.ChangeConfig);
+  }
+
+  public static interface Compatibility.BehaviorChangeDelegate {
+    method public default boolean isChangeEnabled(long);
+    method public default void onChangeReported(long);
+  }
+
+  public static final class Compatibility.ChangeConfig {
+    ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+    method @NonNull public long[] getDisabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+    method @NonNull public long[] getEnabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
+    method public boolean isEmpty();
+    method public boolean isForceDisabled(long);
+    method public boolean isForceEnabled(long);
+  }
+
+}
+
+package android.system {
+
+  public final class NetlinkSocketAddress extends java.net.SocketAddress {
+    ctor public NetlinkSocketAddress(int, int);
+    method public int getGroupsMask();
+    method public int getPortId();
+  }
+
+  public final class Os {
+    method @Nullable public static android.system.StructCapUserData[] capget(@NonNull android.system.StructCapUserHeader) throws android.system.ErrnoException;
+    method public static void capset(@NonNull android.system.StructCapUserHeader, @NonNull android.system.StructCapUserData[]) throws android.system.ErrnoException;
+    method public static int getpgid(int) throws android.system.ErrnoException;
+    method @Nullable public static android.system.StructRlimit getrlimit(int) throws android.system.ErrnoException;
+    method public static int getsockoptInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method @Nullable public static android.system.StructLinger getsockoptLinger(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int ioctlInt(@NonNull java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method @Nullable public static java.io.FileDescriptor[] pipe2(int) throws android.system.ErrnoException;
+    method @Nullable public static String realpath(@Nullable 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 public static void setsockoptIfreq(@NonNull java.io.FileDescriptor, int, int, @Nullable String) throws android.system.ErrnoException;
+    method public static void setsockoptLinger(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructLinger) throws android.system.ErrnoException;
+    method public static long splice(@NonNull java.io.FileDescriptor, @Nullable android.system.Int64Ref, @NonNull java.io.FileDescriptor, @Nullable android.system.Int64Ref, long, int) throws android.system.ErrnoException;
+    method public static void unlink(@Nullable String) throws android.system.ErrnoException;
+  }
+
+  public final class OsConstants {
+    method public static int CAP_TO_INDEX(int);
+    method public static int CAP_TO_MASK(int);
+    field public static final int ARPHRD_LOOPBACK;
+    field public static final int EUSERS;
+    field public static final int MAP_POPULATE;
+    field public static final int O_DIRECT;
+    field public static final int PR_CAP_AMBIENT;
+    field public static final int PR_CAP_AMBIENT_RAISE;
+    field public static final int RLIMIT_NOFILE;
+    field public static final int RTMGRP_IPV4_IFADDR;
+    field public static final int SPLICE_F_MORE;
+    field public static final int SPLICE_F_MOVE;
+    field public static final int TIOCOUTQ;
+    field public static final int UDP_ENCAP;
+    field public static final int UDP_ENCAP_ESPINUDP;
+    field public static final int XATTR_CREATE;
+    field public static final int XATTR_REPLACE;
+    field public static final int _LINUX_CAPABILITY_VERSION_3;
+  }
+
+  public final class PacketSocketAddress extends java.net.SocketAddress {
+    ctor public PacketSocketAddress(int, 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);
+  }
+
+  public final class VmSocketAddress extends java.net.SocketAddress {
+    ctor public VmSocketAddress(int, int);
+    method public int getSvmCid();
+    method public int getSvmPort();
+  }
+
+}
+
+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 dalvik.annotation.codegen {
+
+  @java.lang.annotation.Repeatable(CovariantReturnType.CovariantReturnTypes.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface CovariantReturnType {
+    method public abstract int presentAfter();
+    method public abstract Class<?> returnType();
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public static @interface CovariantReturnType.CovariantReturnTypes {
+    method public abstract dalvik.annotation.codegen.CovariantReturnType[] 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 final class AnnotatedStackTraceElement {
+    method @Nullable public Object getBlockedOn();
+    method @Nullable public Object[] getHeldLocks();
+    method @NonNull public StackTraceElement getStackTraceElement();
+  }
+
+  public class AppSpecializationHooks {
+    method public static void handleCompatChangesBeforeBindingApplication();
+  }
+
+  public class BaseDexClassLoader extends java.lang.ClassLoader {
+    method public void addDexPath(@Nullable String);
+    method public void addNativePath(@NonNull java.util.Collection<java.lang.String>);
+    method @NonNull public String getLdLibraryPath();
+    method public void reportClassLoaderChain();
+    method public static void setReporter(@Nullable dalvik.system.BaseDexClassLoader.Reporter);
+  }
+
+  public static interface BaseDexClassLoader.Reporter {
+    method public void report(@NonNull java.util.Map<java.lang.String,java.lang.String>);
+  }
+
+  public final class BlockGuard {
+    method @NonNull public static dalvik.system.BlockGuard.Policy getThreadPolicy();
+    method @NonNull public static dalvik.system.BlockGuard.VmPolicy getVmPolicy();
+    method public static void setThreadPolicy(@NonNull dalvik.system.BlockGuard.Policy);
+    method public static void setVmPolicy(@NonNull dalvik.system.BlockGuard.VmPolicy);
+    field 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 public void onReadFromDisk();
+    method public void onUnbufferedIO();
+    method public void onWriteToDisk();
+  }
+
+  public static interface BlockGuard.VmPolicy {
+    method public void onPathAccess(@NonNull String);
+  }
+
+  public final class CloseGuard {
+    method public void close();
+    method public static dalvik.system.CloseGuard get();
+    method public static dalvik.system.CloseGuard.Reporter getReporter();
+    method public void open(String);
+    method public void openWithCallSite(String, String);
+    method public static void setEnabled(boolean);
+    method public static void setReporter(dalvik.system.CloseGuard.Reporter);
+    method public void warnIfOpen();
+  }
+
+  public static interface CloseGuard.Reporter {
+    method public void report(String, Throwable);
+    method public default void report(String);
+  }
+
+  public final class DelegateLastClassLoader extends dalvik.system.PathClassLoader {
+    ctor public DelegateLastClassLoader(String, String, ClassLoader, ClassLoader[]);
+  }
+
+  @Deprecated public final class DexFile {
+    method @Deprecated @NonNull public static dalvik.system.DexFile.OptimizationInfo getDexFileOptimizationInfo(@NonNull String, @NonNull String) throws java.io.FileNotFoundException;
+    method @Deprecated @Nullable public static String[] getDexFileOutputPaths(@NonNull String, @NonNull String) throws java.io.FileNotFoundException;
+    method @Deprecated public static int getDexOptNeeded(@NonNull String, @NonNull String, @NonNull String, @Nullable String, boolean, boolean) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated @NonNull public static String getSafeModeCompilerFilter(@NonNull String);
+    method @Deprecated public static boolean isProfileGuidedCompilerFilter(@NonNull String);
+    method @Deprecated public static boolean isValidCompilerFilter(@NonNull String);
+    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 @NonNull public String getReason();
+    method @Deprecated @NonNull public String getStatus();
+  }
+
+  public class PathClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public PathClassLoader(@NonNull String, @Nullable String, @Nullable ClassLoader, @Nullable ClassLoader[]);
+  }
+
+  public final class RuntimeHooks {
+    method public static void setTimeZoneIdSupplier(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public static void setUncaughtExceptionPreHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
+  }
+
+  public abstract class SocketTagger {
+    ctor public SocketTagger();
+    method 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 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 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 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 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.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 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 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.optimization.FastNative public long addressOf(Object);
+    method public static void bootCompleted();
+    method public void clampGrowthLimit();
+    method public void clearGrowthLimit();
+    method public static String getCurrentInstructionSet();
+    method public static String getInstructionSet(String);
+    method public static dalvik.system.VMRuntime getRuntime();
+    method public int getTargetSdkVersion();
+    method @dalvik.annotation.optimization.FastNative public boolean is64Bit();
+    method public static boolean is64BitAbi(String);
+    method public static boolean is64BitInstructionSet(String);
+    method @dalvik.annotation.optimization.FastNative public boolean isCheckJniEnabled();
+    method @dalvik.annotation.optimization.FastNative public boolean isNativeDebuggable();
+    method public static boolean isValidClassLoaderContext(String);
+    method @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, String, String[], int);
+    method public void registerNativeAllocation(long);
+    method @Deprecated public void registerNativeAllocation(int);
+    method public void registerNativeFree(long);
+    method @Deprecated public void registerNativeFree(int);
+    method public static void registerSensitiveThread();
+    method public void requestConcurrentGC();
+    method public static void resetJitCounters();
+    method public static void setDedupeHiddenApiWarnings(boolean);
+    method public void setDisabledCompatChanges(long[]);
+    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 public void setTargetSdkVersion(int);
+    method public void updateProcessState(int);
+    method public String vmInstructionSet();
+    method public String vmLibrary();
+    field public static final int CODE_PATH_TYPE_PRIMARY_APK = 1; // 0x1
+    field public static final int CODE_PATH_TYPE_SECONDARY_DEX = 4; // 0x4
+    field public static final int CODE_PATH_TYPE_SPLIT_APK = 2; // 0x2
+    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 final class ZygoteHooks {
+    method public static void gcAndFinalize();
+    method public static boolean isIndefiniteThreadSuspensionSafe();
+    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(int);
+    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 Math {
+    method public static long randomLongInternal();
+  }
+
+  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 {
+    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 @NonNull public static java.net.InetAddress[] getAllByNameOnNet(@Nullable String, int) throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getByNameOnNet(@Nullable 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 NIOAccess {
+    method public static Object getBaseArray(java.nio.Buffer);
+    method public static int getBaseArrayOffset(java.nio.Buffer);
+  }
+
+  public final class NioUtils {
+    method public static void freeDirectBuffer(java.nio.ByteBuffer);
+    method public static byte[] unsafeArray(java.nio.ByteBuffer);
+    method 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();
+  }
+
+}
+
+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 javax.net.ssl {
+
+  public abstract class HttpsURLConnection extends java.net.HttpURLConnection {
+    method public static javax.net.ssl.HostnameVerifier getStrictHostnameVerifier();
+  }
+
+}
+
+package libcore.content.type {
+
+  public final class MimeMap {
+    method @NonNull public libcore.content.type.MimeMap.Builder buildUpon();
+    method @NonNull public static libcore.content.type.MimeMap.Builder builder();
+    method @NonNull public java.util.Set<java.lang.String> extensions();
+    method @NonNull public static libcore.content.type.MimeMap getDefault();
+    method @Nullable public String guessExtensionFromMimeType(@Nullable String);
+    method @Nullable public String guessMimeTypeFromExtension(@Nullable String);
+    method public boolean hasExtension(@Nullable String);
+    method public boolean hasMimeType(@Nullable String);
+    method @NonNull public java.util.Set<java.lang.String> mimeTypes();
+    method public static void setDefaultSupplier(@NonNull java.util.function.Supplier<libcore.content.type.MimeMap>);
+  }
+
+  public static final class MimeMap.Builder {
+    method @NonNull public libcore.content.type.MimeMap.Builder addMimeMapping(@NonNull String, @NonNull java.util.List<java.lang.String>);
+    method @NonNull public libcore.content.type.MimeMap build();
+  }
+
+}
+
+package libcore.io {
+
+  public class ForwardingOs implements libcore.io.Os {
+    ctor protected ForwardingOs(@NonNull libcore.io.Os);
+    method public boolean access(@Nullable String, int) throws android.system.ErrnoException;
+    method public java.io.FileDescriptor open(@Nullable String, int, int) throws android.system.ErrnoException;
+    method public void remove(@Nullable String) throws android.system.ErrnoException;
+    method public void rename(@Nullable String, @Nullable String) throws android.system.ErrnoException;
+    method @Nullable public android.system.StructStat stat(@Nullable String) throws android.system.ErrnoException;
+    method public void unlink(@Nullable 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(@Nullable java.io.FileDescriptor) throws java.io.IOException;
+    method public static void closeQuietly(@Nullable AutoCloseable);
+    method public static void closeQuietly(@Nullable java.io.FileDescriptor);
+    method public static void closeQuietly(@Nullable java.net.Socket);
+    method @Deprecated public static void deleteContents(java.io.File) throws java.io.IOException;
+    method @NonNull public static byte[] readFileAsByteArray(@NonNull String) throws java.io.IOException;
+    method @NonNull public static String readFileAsString(@NonNull String) throws java.io.IOException;
+    method public static void setBlocking(@NonNull 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(@NonNull Object, int, @NonNull Object, int, long);
+    method public static int peekInt(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static short peekShort(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static void pokeInt(@NonNull byte[], int, int, @NonNull java.nio.ByteOrder);
+    method public static void pokeLong(@NonNull byte[], int, long, @NonNull java.nio.ByteOrder);
+    method public static void pokeShort(@NonNull byte[], int, short, @NonNull 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 public static int copy(@NonNull java.io.InputStream, @NonNull java.io.OutputStream) throws java.io.IOException;
+    method public static void readFully(@NonNull java.io.InputStream, @NonNull byte[]) throws java.io.IOException;
+    method @NonNull public static byte[] readFully(@NonNull java.io.InputStream) throws java.io.IOException;
+    method @NonNull public static String readFully(@NonNull java.io.Reader) throws java.io.IOException;
+    method @NonNull public static byte[] readFullyNoClose(@NonNull java.io.InputStream) throws java.io.IOException;
+    method public static int readSingleByte(@NonNull java.io.InputStream) throws java.io.IOException;
+    method public static long skipByReading(@NonNull java.io.InputStream, long) throws java.io.IOException;
+    method public static void writeSingleByte(@NonNull 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 abstract class NetworkSecurityPolicy {
+    ctor public NetworkSecurityPolicy();
+    method public static libcore.net.NetworkSecurityPolicy getInstance();
+    method public abstract boolean isCertificateTransparencyVerificationRequired(String);
+    method public abstract boolean isCleartextTrafficPermitted();
+    method public abstract boolean isCleartextTrafficPermitted(String);
+    method public static void setInstance(libcore.net.NetworkSecurityPolicy);
+  }
+
+}
+
+package libcore.net.event {
+
+  public final class NetworkEventDispatcher {
+    method public void dispatchNetworkConfigurationChange();
+    method public static libcore.net.event.NetworkEventDispatcher getInstance();
+  }
+
+}
+
+package libcore.net.http {
+
+  public interface Dns extends com.android.okhttp.internalandroidapi.Dns {
+  }
+
+  public class HttpURLConnectionFactory {
+    method @NonNull public static libcore.net.http.HttpURLConnectionFactory createInstance();
+    method public java.net.URLConnection openConnection(@NonNull java.net.URL, @NonNull javax.net.SocketFactory, @NonNull java.net.Proxy) throws java.io.IOException;
+    method public void setDns(@NonNull libcore.net.http.Dns);
+    method public void setNewConnectionPool(int, long, @NonNull java.util.concurrent.TimeUnit);
+  }
+
+}
+
+package libcore.util {
+
+  public final class EmptyArray {
+    field public static final boolean[] BOOLEAN;
+    field public static final byte[] BYTE;
+    field public static final float[] FLOAT;
+    field public static final int[] INT;
+    field public static final long[] LONG;
+    field public static final Object[] OBJECT;
+    field public static final String[] STRING;
+  }
+
+  public final class FP16 {
+    method public static short ceil(short);
+    method public static int compare(short, short);
+    method public static boolean equals(short, short);
+    method public static short floor(short);
+    method public static boolean greater(short, short);
+    method public static boolean greaterEquals(short, short);
+    method public static boolean isInfinite(short);
+    method public static boolean isNaN(short);
+    method public static boolean isNormalized(short);
+    method public static boolean less(short, short);
+    method public static boolean lessEquals(short, short);
+    method public static short max(short, short);
+    method public static short min(short, short);
+    method public static short rint(short);
+    method public static float toFloat(short);
+    method public static short toHalf(float);
+    method public static String toHexString(short);
+    method public static short trunc(short);
+    field public static final short EPSILON = 5120; // 0x1400
+    field public static final int EXPONENT_BIAS = 15; // 0xf
+    field public static final int EXPONENT_SHIFT = 10; // 0xa
+    field public static final int EXPONENT_SIGNIFICAND_MASK = 32767; // 0x7fff
+    field public static final short LOWEST_VALUE = -1025; // 0xfffffbff
+    field public static final int MAX_EXPONENT = 15; // 0xf
+    field public static final short MAX_VALUE = 31743; // 0x7bff
+    field public static final int MIN_EXPONENT = -14; // 0xfffffff2
+    field public static final short MIN_NORMAL = 1024; // 0x400
+    field public static final short MIN_VALUE = 1; // 0x1
+    field public static final short NEGATIVE_INFINITY = -1024; // 0xfffffc00
+    field public static final short NEGATIVE_ZERO = -32768; // 0xffff8000
+    field public static final short NaN = 32256; // 0x7e00
+    field public static final short POSITIVE_INFINITY = 31744; // 0x7c00
+    field public static final short POSITIVE_ZERO = 0; // 0x0
+    field public static final int SHIFTED_EXPONENT_MASK = 31; // 0x1f
+    field public static final int SIGNIFICAND_MASK = 1023; // 0x3ff
+    field public static final int SIGN_MASK = 32768; // 0x8000
+    field public static final int SIGN_SHIFT = 15; // 0xf
+    field public static final int SIZE = 16; // 0x10
+  }
+
+  public class HexEncoding {
+    method public static byte[] decode(String) throws java.lang.IllegalArgumentException;
+    method public static byte[] decode(String, boolean) 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[], boolean);
+    method public static char[] encode(byte[], int, int);
+    method public static String encodeToString(byte, boolean);
+    method public static String encodeToString(byte[]);
+    method public static String encodeToString(byte[], boolean);
+  }
+
+  public class NativeAllocationRegistry {
+    ctor public NativeAllocationRegistry(@NonNull ClassLoader, long, long);
+    method public static void applyFreeFunction(long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(@NonNull ClassLoader, long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(@NonNull ClassLoader, long);
+    method public static libcore.util.NativeAllocationRegistry createNonmalloced(@NonNull ClassLoader, long, long);
+    method @NonNull public Runnable registerNativeAllocation(@NonNull Object, long);
+  }
+
+  public class SneakyThrow {
+    method public static void sneakyThrow(@NonNull Throwable);
+  }
+
+  public class XmlObjectFactory {
+    method @NonNull public static org.xml.sax.XMLReader newXMLReader();
+    method @NonNull public static org.xmlpull.v1.XmlPullParser newXmlPullParser();
+    method @NonNull public static org.xmlpull.v1.XmlSerializer newXmlSerializer();
+  }
+
+}
+
+package org.apache.harmony.dalvik.ddmc {
+
+  public class Chunk {
+    ctor public Chunk(int, byte[], int, int);
+    ctor public Chunk(int, java.nio.ByteBuffer);
+    field public int type;
+  }
+
+  public abstract class ChunkHandler {
+    ctor public ChunkHandler();
+    method public static org.apache.harmony.dalvik.ddmc.Chunk createFailChunk(int, String);
+    method public abstract org.apache.harmony.dalvik.ddmc.Chunk handleChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    method public static String name(int);
+    method public abstract void onConnected();
+    method public abstract void onDisconnected();
+    method public static int type(String);
+    method public static java.nio.ByteBuffer wrapChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    field public static final java.nio.ByteOrder CHUNK_ORDER;
+  }
+
+  public final class DdmServer {
+    method public static void registerHandler(int, org.apache.harmony.dalvik.ddmc.ChunkHandler);
+    method public static void registrationComplete();
+    method public static void sendChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    method public static org.apache.harmony.dalvik.ddmc.ChunkHandler unregisterHandler(int);
+  }
+
+  public final class DdmVmInternal {
+    method public static void setRecentAllocationsTrackingEnabled(boolean);
+    method public static void setThreadNotifyEnabled(boolean);
+  }
+
+}
+
+package org.json {
+
+  public class JSONObject {
+    method @NonNull 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 public int arrayIndexScale(Class);
+    method @dalvik.annotation.optimization.FastNative public void copyMemory(long, long, long);
+    method @dalvik.annotation.optimization.FastNative public boolean getBoolean(Object, long);
+    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 double getDouble(Object, long);
+    method @dalvik.annotation.optimization.FastNative public double getDouble(long);
+    method @dalvik.annotation.optimization.FastNative public float getFloat(Object, long);
+    method @dalvik.annotation.optimization.FastNative public float getFloat(long);
+    method @dalvik.annotation.optimization.FastNative public int getInt(Object, long);
+    method @dalvik.annotation.optimization.FastNative public int getInt(long);
+    method @dalvik.annotation.optimization.FastNative public long getLong(Object, long);
+    method @dalvik.annotation.optimization.FastNative public long getLong(long);
+    method @dalvik.annotation.optimization.FastNative public Object getObject(Object, long);
+    method public static sun.misc.Unsafe getUnsafe();
+    method public long objectFieldOffset(java.lang.reflect.Field);
+    method @dalvik.annotation.optimization.FastNative public void putBoolean(Object, long, boolean);
+    method @dalvik.annotation.optimization.FastNative public void putByte(Object, long, byte);
+    method @dalvik.annotation.optimization.FastNative public void putByte(long, byte);
+    method @dalvik.annotation.optimization.FastNative public void putDouble(Object, long, double);
+    method @dalvik.annotation.optimization.FastNative public void putDouble(long, double);
+    method @dalvik.annotation.optimization.FastNative public void putFloat(Object, long, float);
+    method @dalvik.annotation.optimization.FastNative public void putFloat(long, float);
+    method @dalvik.annotation.optimization.FastNative public void putInt(Object, long, int);
+    method @dalvik.annotation.optimization.FastNative public void putInt(long, int);
+    method @dalvik.annotation.optimization.FastNative public void putLong(Object, long, long);
+    method @dalvik.annotation.optimization.FastNative public void putLong(long, long);
+    method @dalvik.annotation.optimization.FastNative public void putObject(Object, long, Object);
+  }
+
+}
+
+package sun.security.jca {
+
+  public class Providers {
+    method public static Object startJarVerification();
+    method public static void stopJarVerification(Object);
+  }
+
+}
+
+package sun.security.pkcs {
+
+  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.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();
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/legacy_platform/last-api.txt
similarity index 100%
rename from mmodules/core_platform_api/api/platform/last-api.txt
rename to mmodules/core_platform_api/api/legacy_platform/last-api.txt
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/legacy_platform/last-incompatibilities.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/last-api.txt
copy to mmodules/core_platform_api/api/legacy_platform/last-incompatibilities.txt
diff --git a/mmodules/core_platform_api/api/platform/last-removed.txt b/mmodules/core_platform_api/api/legacy_platform/last-removed.txt
similarity index 100%
rename from mmodules/core_platform_api/api/platform/last-removed.txt
rename to mmodules/core_platform_api/api/legacy_platform/last-removed.txt
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/mmodules/core_platform_api/api/legacy_platform/removed.txt
similarity index 100%
rename from mmodules/core_platform_api/api/platform/current-removed.txt
rename to mmodules/core_platform_api/api/legacy_platform/removed.txt
diff --git a/mmodules/core_platform_api/api/platform/current-api.txt b/mmodules/core_platform_api/api/platform/current-api.txt
deleted file mode 100644
index 15a0a48..0000000
--- a/mmodules/core_platform_api/api/platform/current-api.txt
+++ /dev/null
@@ -1,1510 +0,0 @@
-// Signature format: 2.0
-package android.compat {
-
-  public final class Compatibility {
-    method public static void clearOverrides();
-    method public static boolean isChangeEnabled(long);
-    method public static void reportChange(long);
-    method public static void setCallbacks(android.compat.Compatibility.Callbacks);
-    method public static void setOverrides(android.compat.Compatibility.ChangeConfig);
-  }
-
-  public static class Compatibility.Callbacks {
-    ctor protected Compatibility.Callbacks();
-    method protected boolean isChangeEnabled(long);
-    method protected void reportChange(long);
-  }
-
-  public static final class Compatibility.ChangeConfig {
-    ctor public Compatibility.ChangeConfig(java.util.Set<java.lang.Long>, java.util.Set<java.lang.Long>);
-    method public long[] forceDisabledChangesArray();
-    method public java.util.Set<java.lang.Long> forceDisabledSet();
-    method public long[] forceEnabledChangesArray();
-    method public java.util.Set<java.lang.Long> forceEnabledSet();
-    method public boolean isEmpty();
-    method public boolean isForceDisabled(long);
-    method public boolean isForceEnabled(long);
-  }
-
-}
-
-package android.system {
-
-  public class Int32Ref {
-    ctor public Int32Ref(int);
-    field public int value;
-  }
-
-  public final class NetlinkSocketAddress extends java.net.SocketAddress {
-    ctor 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 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 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 public static int CAP_TO_INDEX(int);
-    method public static int CAP_TO_MASK(int);
-    field public static final int ARPHRD_LOOPBACK;
-    field public static final int ENONET;
-    field public static final int EUSERS;
-    field public static final int MAP_POPULATE;
-    field public static final int O_DIRECT;
-    field public static final int PR_CAP_AMBIENT;
-    field public static final int PR_CAP_AMBIENT_RAISE;
-    field public static final int RLIMIT_NOFILE;
-    field public static final int RTMGRP_IPV4_IFADDR;
-    field public static final int SPLICE_F_MORE;
-    field public static final int SPLICE_F_MOVE;
-    field public static final int TIOCOUTQ;
-    field public static final int UDP_ENCAP;
-    field public static final int UDP_ENCAP_ESPINUDP;
-    field public static final int XATTR_CREATE;
-    field public static final int _LINUX_CAPABILITY_VERSION_3;
-  }
-
-  public final class PacketSocketAddress extends java.net.SocketAddress {
-    ctor public PacketSocketAddress(int, 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 public ASN1EncodableVector();
-    method public void add(com.android.org.bouncycastle.asn1.ASN1Encodable);
-  }
-
-  public class ASN1InputStream extends java.io.FilterInputStream {
-    ctor public ASN1InputStream(java.io.InputStream);
-    ctor public ASN1InputStream(byte[]);
-    method public com.android.org.bouncycastle.asn1.ASN1Primitive readObject() throws java.io.IOException;
-  }
-
-  public class ASN1Integer extends com.android.org.bouncycastle.asn1.ASN1Primitive {
-    ctor 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 public DERBitString(byte[]);
-  }
-
-  @Deprecated public class DERInteger extends com.android.org.bouncycastle.asn1.ASN1Integer {
-    ctor @Deprecated public DERInteger(long);
-  }
-
-  public class DERNull extends com.android.org.bouncycastle.asn1.ASN1Null {
-    field public static final com.android.org.bouncycastle.asn1.DERNull INSTANCE;
-  }
-
-  public class DEROctetString extends com.android.org.bouncycastle.asn1.ASN1OctetString {
-    ctor public DEROctetString(byte[]);
-  }
-
-  public class DERSequence extends com.android.org.bouncycastle.asn1.ASN1Sequence {
-    ctor public DERSequence();
-    ctor 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 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 public AlgorithmIdentifier(com.android.org.bouncycastle.asn1.ASN1ObjectIdentifier);
-    ctor 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 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 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 public Time(java.util.Date);
-  }
-
-  public class V3TBSCertificateGenerator {
-    ctor public V3TBSCertificateGenerator();
-    method public com.android.org.bouncycastle.asn1.x509.TBSCertificate generateTBSCertificate();
-    method public void setEndDate(com.android.org.bouncycastle.asn1.x509.Time);
-    method @Deprecated public void setIssuer(com.android.org.bouncycastle.asn1.x509.X509Name);
-    method public void setSerialNumber(com.android.org.bouncycastle.asn1.ASN1Integer);
-    method public void setSignature(com.android.org.bouncycastle.asn1.x509.AlgorithmIdentifier);
-    method public void setStartDate(com.android.org.bouncycastle.asn1.x509.Time);
-    method @Deprecated public void setSubject(com.android.org.bouncycastle.asn1.x509.X509Name);
-    method public void setSubjectPublicKeyInfo(com.android.org.bouncycastle.asn1.x509.SubjectPublicKeyInfo);
-  }
-
-  @Deprecated public class X509Name extends com.android.org.bouncycastle.asn1.ASN1Object {
-    ctor @Deprecated public X509Name(String);
-    method @Deprecated public static com.android.org.bouncycastle.asn1.x509.X509Name getInstance(Object);
-    method @Deprecated public java.util.Vector getOIDs();
-    method @Deprecated public java.util.Vector getValues();
-    method @Deprecated public String toString(boolean, java.util.Hashtable);
-    field @Deprecated 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 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.digests {
-
-  public abstract class GeneralDigest {
-    method public void finish();
-    method protected abstract void processBlock();
-    method public void update(byte[], int, int);
-  }
-
-  public class MD4Digest extends com.android.org.bouncycastle.crypto.digests.GeneralDigest {
-    ctor public MD4Digest();
-    method public int doFinal(byte[], int);
-    method protected void processBlock();
-  }
-
-  public class SHA1Digest extends com.android.org.bouncycastle.crypto.digests.GeneralDigest {
-    ctor public SHA1Digest();
-    method public int doFinal(byte[], int);
-    method protected void processBlock();
-  }
-
-}
-
-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 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 public BouncyCastleProvider();
-  }
-
-  @Deprecated public class X509CertificateObject extends java.security.cert.X509Certificate {
-    ctor @Deprecated 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 public X509V3CertificateGenerator();
-    method @Deprecated 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 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) throws java.lang.IllegalArgumentException;
-    method @Deprecated public void setSerialNumber(java.math.BigInteger);
-    method @Deprecated public void setSignatureAlgorithm(String);
-    method @Deprecated public void setSubjectDN(javax.security.auth.x500.X500Principal);
-  }
-
-}
-
-package dalvik.annotation.codegen {
-
-  @java.lang.annotation.Repeatable(CovariantReturnType.CovariantReturnTypes.class) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public @interface CovariantReturnType {
-    method public abstract int presentAfter();
-    method public abstract Class<?> returnType();
-  }
-
-  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) public static @interface CovariantReturnType.CovariantReturnTypes {
-    method public abstract dalvik.annotation.codegen.CovariantReturnType[] value();
-  }
-
-}
-
-package dalvik.annotation.compat {
-
-  public class VersionCodes {
-    field public static final int O = 26; // 0x1a
-    field public static final int P = 28; // 0x1c
-    field public static final int Q = 29; // 0x1d
-  }
-
-}
-
-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 public void addDexPath(String);
-    method public void addNativePath(java.util.Collection<java.lang.String>);
-    method public String getLdLibraryPath();
-    method public void reportClassLoaderChain();
-    method public static void setReporter(dalvik.system.BaseDexClassLoader.Reporter);
-  }
-
-  public static interface BaseDexClassLoader.Reporter {
-    method public void report(java.util.Map<java.lang.String,java.lang.String>);
-  }
-
-  public final class BlockGuard {
-    method @NonNull public static dalvik.system.BlockGuard.Policy getThreadPolicy();
-    method @NonNull public static dalvik.system.BlockGuard.VmPolicy getVmPolicy();
-    method public static void setThreadPolicy(@NonNull dalvik.system.BlockGuard.Policy);
-    method public static void setVmPolicy(@NonNull dalvik.system.BlockGuard.VmPolicy);
-    field 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 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 public void close();
-    method public static dalvik.system.CloseGuard get();
-    method public static dalvik.system.CloseGuard.Reporter getReporter();
-    method public void open(String);
-    method public void openWithCallSite(String, String);
-    method public static void setEnabled(boolean);
-    method public static void setReporter(dalvik.system.CloseGuard.Reporter);
-    method public void warnIfOpen();
-  }
-
-  public static interface CloseGuard.Reporter {
-    method public void report(String, Throwable);
-    method public default void report(String);
-  }
-
-  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 @Nullable public static dalvik.system.ThreadPrioritySetter getThreadPrioritySetter();
-    method public static void setThreadPrioritySetter(@NonNull dalvik.system.ThreadPrioritySetter);
-    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 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 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 public final void untag(java.net.Socket) throws java.net.SocketException;
-    method public final void untag(java.net.DatagramSocket) throws java.net.SocketException;
-  }
-
-  @java.lang.FunctionalInterface public interface ThreadPrioritySetter {
-    method public void setPriority(int, int);
-  }
-
-  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 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.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.optimization.FastNative public long addressOf(Object);
-    method public static void bootCompleted();
-    method public void clampGrowthLimit();
-    method public void clearGrowthLimit();
-    method public static boolean didPruneDalvikCache();
-    method public void disableJitCompilation();
-    method public static String getCurrentInstructionSet();
-    method public static String getInstructionSet(String);
-    method 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.optimization.FastNative public boolean is64Bit();
-    method 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 public static boolean isValidClassLoaderContext(String);
-    method @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 public void registerNativeAllocation(long);
-    method @Deprecated public void registerNativeAllocation(int);
-    method public void registerNativeFree(long);
-    method @Deprecated public void registerNativeFree(int);
-    method public static void registerSensitiveThread();
-    method public void requestConcurrentGC();
-    method public static void resetJitCounters();
-    method public static void setDedupeHiddenApiWarnings(boolean);
-    method public void setDisabledCompatChanges(long[]);
-    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 public float setTargetHeapUtilization(float);
-    method public void setTargetSdkVersion(int);
-    method public void startJitCompilation();
-    method public void updateProcessState(int);
-    method public String vmInstructionSet();
-    method 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 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(int);
-    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 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 NIOAccess {
-    method public static Object getBaseArray(java.nio.Buffer);
-    method public static int getBaseArrayOffset(java.nio.Buffer);
-  }
-
-  public final class NioUtils {
-    method public static void freeDirectBuffer(java.nio.ByteBuffer);
-    method public static byte[] unsafeArray(java.nio.ByteBuffer);
-    method 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 javax.net.ssl {
-
-  public abstract class HttpsURLConnection extends java.net.HttpURLConnection {
-    method public static javax.net.ssl.HostnameVerifier getStrictHostnameVerifier();
-  }
-
-}
-
-package libcore.content.type {
-
-  public final class MimeMap {
-    method public libcore.content.type.MimeMap.Builder buildUpon();
-    method public static libcore.content.type.MimeMap.Builder builder();
-    method @NonNull public java.util.Set<java.lang.String> extensions();
-    method @NonNull public static libcore.content.type.MimeMap getDefault();
-    method @Nullable public String guessExtensionFromMimeType(@Nullable String);
-    method @Nullable public String guessMimeTypeFromExtension(@Nullable String);
-    method public boolean hasExtension(@Nullable String);
-    method public boolean hasMimeType(@Nullable String);
-    method @NonNull public java.util.Set<java.lang.String> mimeTypes();
-    method public static void setDefaultSupplier(@NonNull java.util.function.Supplier<libcore.content.type.MimeMap>);
-  }
-
-  public static final class MimeMap.Builder {
-    method public libcore.content.type.MimeMap build();
-    method public libcore.content.type.MimeMap.Builder put(@NonNull String, @NonNull java.util.List<java.lang.String>);
-  }
-
-}
-
-package libcore.icu {
-
-  public final class DateIntervalFormat {
-    method public static String formatDateRange(long, long, int, String);
-  }
-
-  public final class ICU {
-    method public static String getBestDateTimePattern(String, java.util.Locale);
-    method public static char[] getDateFormatOrder(String);
-  }
-
-  public final class LocaleData {
-    method public static libcore.icu.LocaleData get(java.util.Locale);
-    method public String getDateFormat(int);
-    field public String[] amPm;
-    field public Integer firstDayOfWeek;
-    field public String[] longMonthNames;
-    field public String[] longStandAloneMonthNames;
-    field public String[] longStandAloneWeekdayNames;
-    field public String[] longWeekdayNames;
-    field public String narrowAm;
-    field public String narrowPm;
-    field public String[] shortMonthNames;
-    field public String[] shortStandAloneMonthNames;
-    field public String[] shortStandAloneWeekdayNames;
-    field public String[] shortWeekdayNames;
-    field public String timeFormat_Hm;
-    field public String timeFormat_Hms;
-    field 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 public String today;
-    field public String yesterday;
-    field 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 protected ForwardingOs(libcore.io.Os);
-    method public boolean access(String, int) throws android.system.ErrnoException;
-    method public java.io.FileDescriptor open(String, int, int) throws android.system.ErrnoException;
-    method public void remove(String) throws android.system.ErrnoException;
-    method public void rename(String, String) throws android.system.ErrnoException;
-    method public android.system.StructStat stat(String) throws android.system.ErrnoException;
-    method 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 public static void closeQuietly(AutoCloseable);
-    method public static void closeQuietly(java.io.FileDescriptor);
-    method public static void closeQuietly(java.net.Socket);
-    method @Deprecated public static void deleteContents(java.io.File) throws java.io.IOException;
-    method public static byte[] readFileAsByteArray(String) throws java.io.IOException;
-    method public static String readFileAsString(String) throws java.io.IOException;
-    method 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 public static int copy(java.io.InputStream, java.io.OutputStream) throws java.io.IOException;
-    method public static void readFully(java.io.InputStream, byte[]) throws java.io.IOException;
-    method 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 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 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 abstract class NetworkSecurityPolicy {
-    ctor public NetworkSecurityPolicy();
-    method public static libcore.net.NetworkSecurityPolicy getInstance();
-    method public abstract boolean isCertificateTransparencyVerificationRequired(String);
-    method 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 public static libcore.net.event.NetworkEventDispatcher getInstance();
-    method public void onNetworkConfigurationChanged();
-  }
-
-}
-
-package libcore.timezone {
-
-  public final class CountryTimeZones {
-    method public String getCountryIso();
-    method public android.icu.util.TimeZone getDefaultTimeZone();
-    method public String getDefaultTimeZoneId();
-    method public java.util.List<libcore.timezone.CountryTimeZones.TimeZoneMapping> getEffectiveTimeZoneMappingsAt(long);
-    method public java.util.List<libcore.timezone.CountryTimeZones.TimeZoneMapping> getTimeZoneMappings();
-    method public boolean hasUtcZone(long);
-    method public boolean isDefaultTimeZoneBoosted();
-    method public boolean isForCountryCode(String);
-    method public libcore.timezone.CountryTimeZones.OffsetResult lookupByOffsetWithBias(long, android.icu.util.TimeZone, int, boolean);
-    method public libcore.timezone.CountryTimeZones.OffsetResult lookupByOffsetWithBias(long, android.icu.util.TimeZone, int);
-  }
-
-  public static final class CountryTimeZones.OffsetResult {
-    method public android.icu.util.TimeZone getTimeZone();
-    method public boolean isOnlyMatch();
-  }
-
-  public static final class CountryTimeZones.TimeZoneMapping {
-    method public static libcore.timezone.CountryTimeZones.TimeZoneMapping createForTests(String, boolean, Long);
-    method public Long getNotUsedAfter();
-    method public android.icu.util.TimeZone getTimeZone();
-    method public String getTimeZoneId();
-    method public boolean isShownInPicker();
-  }
-
-  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 TelephonyLookup {
-    method public static libcore.timezone.TelephonyLookup createInstance(String) throws java.io.IOException;
-    method public static libcore.timezone.TelephonyLookup getInstance();
-    method public libcore.timezone.TelephonyNetworkFinder getTelephonyNetworkFinder();
-    method public void validate() throws java.io.IOException;
-  }
-
-  public final class TelephonyNetwork {
-    method public String getCountryIsoCode();
-    method public String getMcc();
-    method public String getMnc();
-  }
-
-  public final class TelephonyNetworkFinder {
-    method public libcore.timezone.TelephonyNetwork findNetworkByMccMnc(String, String);
-  }
-
-  public final class TimeZoneDataFiles {
-    method public static String getDataTimeZoneFile(String);
-    method public static String getDataTimeZoneRootDir();
-    method public static String getTimeZoneModuleTzVersionFile();
-  }
-
-  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 void validate() throws java.io.IOException;
-  }
-
-  public final 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 int getFormatMajorVersion();
-    method public int getFormatMinorVersion();
-    method public int getRevision();
-    method public String getRulesVersion();
-    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 static libcore.timezone.TzDataSetVersion readTimeZoneModuleVersion() throws java.io.IOException, libcore.timezone.TzDataSetVersion.TzDataSetException;
-    method public byte[] toBytes();
-    field public static final String DEFAULT_FILE_NAME = "tz_version";
-  }
-
-  public static class TzDataSetVersion.TzDataSetException extends java.lang.Exception {
-    ctor public TzDataSetVersion.TzDataSetException(String);
-    ctor public TzDataSetVersion.TzDataSetException(String, Throwable);
-  }
-
-  public final class ZoneInfoDb implements java.lang.AutoCloseable {
-    method public static libcore.timezone.ZoneInfoDb getInstance();
-    method public String getVersion();
-    method public boolean hasTimeZone(String) throws java.io.IOException;
-    method public static libcore.timezone.ZoneInfoDb 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 public static final byte[] BYTE;
-    field public static final float[] FLOAT;
-    field public static final int[] INT;
-    field public static final long[] LONG;
-    field public static final Object[] OBJECT;
-    field public static final String[] STRING;
-  }
-
-  public class FP16 {
-    method public static short ceil(short);
-    method public static int compare(short, short);
-    method public static boolean equals(short, short);
-    method public static short floor(short);
-    method public static boolean greater(short, short);
-    method public static boolean greaterEquals(short, short);
-    method public static boolean isInfinite(short);
-    method public static boolean isNaN(short);
-    method public static boolean isNormalized(short);
-    method public static boolean less(short, short);
-    method public static boolean lessEquals(short, short);
-    method public static short max(short, short);
-    method public static short min(short, short);
-    method public static short rint(short);
-    method public static float toFloat(short);
-    method public static short toHalf(float);
-    method public static String toHexString(short);
-    method public static short trunc(short);
-    field public static final short EPSILON = 5120; // 0x1400
-    field public static final int EXPONENT_BIAS = 15; // 0xf
-    field public static final int EXPONENT_SHIFT = 10; // 0xa
-    field public static final int EXPONENT_SIGNIFICAND_MASK = 32767; // 0x7fff
-    field public static final short LOWEST_VALUE = -1025; // 0xfffffbff
-    field public static final int MAX_EXPONENT = 15; // 0xf
-    field public static final short MAX_VALUE = 31743; // 0x7bff
-    field public static final int MIN_EXPONENT = -14; // 0xfffffff2
-    field public static final short MIN_NORMAL = 1024; // 0x400
-    field public static final short MIN_VALUE = 1; // 0x1
-    field public static final short NEGATIVE_INFINITY = -1024; // 0xfffffc00
-    field public static final short NEGATIVE_ZERO = -32768; // 0xffff8000
-    field public static final short NaN = 32256; // 0x7e00
-    field public static final short POSITIVE_INFINITY = 31744; // 0x7c00
-    field public static final short POSITIVE_ZERO = 0; // 0x0
-    field public static final int SHIFTED_EXPONENT_MASK = 31; // 0x1f
-    field public static final int SIGNIFICAND_MASK = 1023; // 0x3ff
-    field public static final int SIGN_MASK = 32768; // 0x8000
-    field public static final int SIGN_SHIFT = 15; // 0xf
-    field public static final int SIZE = 16; // 0x10
-  }
-
-  public class HexEncoding {
-    method public static byte[] decode(String) throws java.lang.IllegalArgumentException;
-    method public static byte[] decode(String, boolean) 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[], boolean);
-    method public static char[] encode(byte[], int, int);
-    method public static String encodeToString(byte, boolean);
-    method public static String encodeToString(byte[]);
-    method public static String encodeToString(byte[], boolean);
-  }
-
-  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 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 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 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 public static StackTraceElement[] getStackTraceById(int);
-    method 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 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 public int arrayIndexScale(Class);
-    method @dalvik.annotation.optimization.FastNative public void copyMemory(long, long, long);
-    method @dalvik.annotation.optimization.FastNative public boolean getBoolean(Object, long);
-    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 double getDouble(Object, long);
-    method @dalvik.annotation.optimization.FastNative public float getFloat(Object, long);
-    method @dalvik.annotation.optimization.FastNative public int getInt(Object, long);
-    method @dalvik.annotation.optimization.FastNative public int getInt(long);
-    method @dalvik.annotation.optimization.FastNative public long getLong(Object, long);
-    method @dalvik.annotation.optimization.FastNative public long getLong(long);
-    method @dalvik.annotation.optimization.FastNative public Object getObject(Object, long);
-    method public static sun.misc.Unsafe getUnsafe();
-    method public long objectFieldOffset(java.lang.reflect.Field);
-    method @dalvik.annotation.optimization.FastNative public void putBoolean(Object, long, boolean);
-    method @dalvik.annotation.optimization.FastNative public void putByte(Object, long, byte);
-    method @dalvik.annotation.optimization.FastNative public void putByte(long, byte);
-    method @dalvik.annotation.optimization.FastNative public void putDouble(Object, long, double);
-    method @dalvik.annotation.optimization.FastNative public void putFloat(Object, long, float);
-    method @dalvik.annotation.optimization.FastNative public void putInt(Object, long, int);
-    method @dalvik.annotation.optimization.FastNative public void putInt(long, int);
-    method @dalvik.annotation.optimization.FastNative public void putLong(Object, long, long);
-    method @dalvik.annotation.optimization.FastNative public void putLong(long, long);
-    method @dalvik.annotation.optimization.FastNative public void putObject(Object, long, Object);
-  }
-
-}
-
-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/stable_platform/current.txt b/mmodules/core_platform_api/api/stable_platform/current.txt
new file mode 100644
index 0000000..c7ee205
--- /dev/null
+++ b/mmodules/core_platform_api/api/stable_platform/current.txt
@@ -0,0 +1,769 @@
+// Signature format: 2.0
+package android.compat {
+
+  public final class Compatibility {
+    method public static void clearBehaviorChangeDelegate();
+    method public static void clearOverrides();
+    method public static boolean isChangeEnabled(long);
+    method public static void reportUnconditionalChange(long);
+    method public static void setBehaviorChangeDelegate(android.compat.Compatibility.BehaviorChangeDelegate);
+    method public static void setOverrides(android.compat.Compatibility.ChangeConfig);
+  }
+
+  public static interface Compatibility.BehaviorChangeDelegate {
+    method public default boolean isChangeEnabled(long);
+    method public default void onChangeReported(long);
+  }
+
+  public static final class Compatibility.ChangeConfig {
+    ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+    method @NonNull public long[] getDisabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+    method @NonNull public long[] getEnabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
+    method public boolean isEmpty();
+    method public boolean isForceDisabled(long);
+    method public boolean isForceEnabled(long);
+  }
+
+}
+
+package android.system {
+
+  public final class NetlinkSocketAddress extends java.net.SocketAddress {
+    ctor public NetlinkSocketAddress(int, int);
+    method public int getGroupsMask();
+    method public int getPortId();
+  }
+
+  public final class Os {
+    method @Nullable public static android.system.StructCapUserData[] capget(@NonNull android.system.StructCapUserHeader) throws android.system.ErrnoException;
+    method public static void capset(@NonNull android.system.StructCapUserHeader, @NonNull android.system.StructCapUserData[]) throws android.system.ErrnoException;
+    method public static int getpgid(int) throws android.system.ErrnoException;
+    method @Nullable public static android.system.StructRlimit getrlimit(int) throws android.system.ErrnoException;
+    method public static int getsockoptInt(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method @Nullable public static android.system.StructLinger getsockoptLinger(@NonNull java.io.FileDescriptor, int, int) throws android.system.ErrnoException;
+    method public static int ioctlInt(@NonNull java.io.FileDescriptor, int) throws android.system.ErrnoException;
+    method @Nullable public static java.io.FileDescriptor[] pipe2(int) throws android.system.ErrnoException;
+    method @Nullable public static String realpath(@Nullable 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 public static void setsockoptIfreq(@NonNull java.io.FileDescriptor, int, int, @Nullable String) throws android.system.ErrnoException;
+    method public static void setsockoptLinger(@NonNull java.io.FileDescriptor, int, int, @NonNull android.system.StructLinger) throws android.system.ErrnoException;
+    method public static long splice(@NonNull java.io.FileDescriptor, @Nullable android.system.Int64Ref, @NonNull java.io.FileDescriptor, @Nullable android.system.Int64Ref, long, int) throws android.system.ErrnoException;
+    method public static void unlink(@Nullable String) throws android.system.ErrnoException;
+  }
+
+  public final class OsConstants {
+    method public static int CAP_TO_INDEX(int);
+    method public static int CAP_TO_MASK(int);
+    field public static final int ARPHRD_LOOPBACK;
+    field public static final int EUSERS;
+    field public static final int MAP_POPULATE;
+    field public static final int O_DIRECT;
+    field public static final int PR_CAP_AMBIENT;
+    field public static final int PR_CAP_AMBIENT_RAISE;
+    field public static final int RLIMIT_NOFILE;
+    field public static final int RTMGRP_IPV4_IFADDR;
+    field public static final int SPLICE_F_MORE;
+    field public static final int SPLICE_F_MOVE;
+    field public static final int TIOCOUTQ;
+    field public static final int UDP_ENCAP;
+    field public static final int UDP_ENCAP_ESPINUDP;
+    field public static final int XATTR_CREATE;
+    field public static final int XATTR_REPLACE;
+    field public static final int _LINUX_CAPABILITY_VERSION_3;
+  }
+
+  public final class PacketSocketAddress extends java.net.SocketAddress {
+    ctor public PacketSocketAddress(int, 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);
+  }
+
+  public final class VmSocketAddress extends java.net.SocketAddress {
+    ctor public VmSocketAddress(int, int);
+    method public int getSvmCid();
+    method public int getSvmPort();
+  }
+
+}
+
+package dalvik.system {
+
+  public final class AnnotatedStackTraceElement {
+    method @Nullable public Object getBlockedOn();
+    method @Nullable public Object[] getHeldLocks();
+    method @NonNull public StackTraceElement getStackTraceElement();
+  }
+
+  public class AppSpecializationHooks {
+    method public static void handleCompatChangesBeforeBindingApplication();
+  }
+
+  public class BaseDexClassLoader extends java.lang.ClassLoader {
+    method public void addDexPath(@Nullable String);
+    method public void addNativePath(@NonNull java.util.Collection<java.lang.String>);
+    method @NonNull public String getLdLibraryPath();
+    method public void reportClassLoaderChain();
+    method public static void setReporter(@Nullable dalvik.system.BaseDexClassLoader.Reporter);
+  }
+
+  public static interface BaseDexClassLoader.Reporter {
+    method public void report(@NonNull java.util.Map<java.lang.String,java.lang.String>);
+  }
+
+  public final class BlockGuard {
+    method @NonNull public static dalvik.system.BlockGuard.Policy getThreadPolicy();
+    method @NonNull public static dalvik.system.BlockGuard.VmPolicy getVmPolicy();
+    method public static void setThreadPolicy(@NonNull dalvik.system.BlockGuard.Policy);
+    method public static void setVmPolicy(@NonNull dalvik.system.BlockGuard.VmPolicy);
+    field 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 public void onReadFromDisk();
+    method public void onUnbufferedIO();
+    method public void onWriteToDisk();
+  }
+
+  public static interface BlockGuard.VmPolicy {
+    method public void onPathAccess(@NonNull String);
+  }
+
+  public final class CloseGuard {
+    method public void close();
+    method public static dalvik.system.CloseGuard get();
+    method public static dalvik.system.CloseGuard.Reporter getReporter();
+    method public void open(String);
+    method public void openWithCallSite(String, String);
+    method public static void setEnabled(boolean);
+    method public static void setReporter(dalvik.system.CloseGuard.Reporter);
+    method public void warnIfOpen();
+  }
+
+  public static interface CloseGuard.Reporter {
+    method public void report(String, Throwable);
+    method public default void report(String);
+  }
+
+  @Deprecated public final class DexFile {
+    method @Deprecated @NonNull public static dalvik.system.DexFile.OptimizationInfo getDexFileOptimizationInfo(@NonNull String, @NonNull String) throws java.io.FileNotFoundException;
+    method @Deprecated @Nullable public static String[] getDexFileOutputPaths(@NonNull String, @NonNull String) throws java.io.FileNotFoundException;
+    method @Deprecated public static int getDexOptNeeded(@NonNull String, @NonNull String, @NonNull String, @Nullable String, boolean, boolean) throws java.io.FileNotFoundException, java.io.IOException;
+    method @Deprecated @NonNull public static String getSafeModeCompilerFilter(@NonNull String);
+    method @Deprecated public static boolean isProfileGuidedCompilerFilter(@NonNull String);
+    method @Deprecated public static boolean isValidCompilerFilter(@NonNull String);
+    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 @NonNull public String getReason();
+    method @Deprecated @NonNull public String getStatus();
+  }
+
+  public class PathClassLoader extends dalvik.system.BaseDexClassLoader {
+    ctor public PathClassLoader(@NonNull String, @Nullable String, @Nullable ClassLoader, @Nullable ClassLoader[]);
+  }
+
+  public final class RuntimeHooks {
+    method public static void setTimeZoneIdSupplier(@NonNull java.util.function.Supplier<java.lang.String>);
+    method public static void setUncaughtExceptionPreHandler(@Nullable java.lang.Thread.UncaughtExceptionHandler);
+  }
+
+  public abstract class SocketTagger {
+    ctor public SocketTagger();
+    method 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 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 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 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 public static void dumpReferenceTables();
+    method public static int getAllocCount(int);
+    method 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 public static boolean isDebuggerConnected();
+    method public static boolean isDebuggingEnabled();
+    method public static long lastDebuggerActivity();
+    method 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 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 stopMethodTracing();
+    method 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 public long addressOf(Object);
+    method public static void bootCompleted();
+    method public void clampGrowthLimit();
+    method public void clearGrowthLimit();
+    method public static String getCurrentInstructionSet();
+    method public static String getInstructionSet(String);
+    method public static dalvik.system.VMRuntime getRuntime();
+    method public int getTargetSdkVersion();
+    method public boolean is64Bit();
+    method public static boolean is64BitAbi(String);
+    method public static boolean is64BitInstructionSet(String);
+    method public boolean isCheckJniEnabled();
+    method public boolean isNativeDebuggable();
+    method public static boolean isValidClassLoaderContext(String);
+    method public Object newNonMovableArray(Class<?>, int);
+    method public Object newUnpaddedArray(Class<?>, int);
+    method public void notifyStartupCompleted();
+    method public void preloadDexCaches();
+    method public static void registerAppInfo(String, String, String, String[], int);
+    method public void registerNativeAllocation(long);
+    method @Deprecated public void registerNativeAllocation(int);
+    method public void registerNativeFree(long);
+    method @Deprecated public void registerNativeFree(int);
+    method public static void registerSensitiveThread();
+    method public void requestConcurrentGC();
+    method public static void resetJitCounters();
+    method public static void setDedupeHiddenApiWarnings(boolean);
+    method public void setDisabledCompatChanges(long[]);
+    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 public void setTargetSdkVersion(int);
+    method public void updateProcessState(int);
+    method public String vmInstructionSet();
+    method public String vmLibrary();
+    field public static final int CODE_PATH_TYPE_PRIMARY_APK = 1; // 0x1
+    field public static final int CODE_PATH_TYPE_SECONDARY_DEX = 4; // 0x4
+    field public static final int CODE_PATH_TYPE_SPLIT_APK = 2; // 0x2
+    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 ZygoteHooks {
+    method public static void gcAndFinalize();
+    method public static boolean isIndefiniteThreadSuspensionSafe();
+    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(int);
+    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 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 {
+    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 @NonNull public static java.net.InetAddress[] getAllByNameOnNet(@Nullable String, int) throws java.net.UnknownHostException;
+    method @NonNull public static java.net.InetAddress getByNameOnNet(@Nullable String, int) throws java.net.UnknownHostException;
+    method @Deprecated public static boolean isNumeric(String);
+    method @Deprecated public static java.net.InetAddress parseNumericAddress(String);
+  }
+
+  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 NIOAccess {
+    method public static Object getBaseArray(java.nio.Buffer);
+    method public static int getBaseArrayOffset(java.nio.Buffer);
+  }
+
+  public final class NioUtils {
+    method public static void freeDirectBuffer(java.nio.ByteBuffer);
+    method public static byte[] unsafeArray(java.nio.ByteBuffer);
+    method 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();
+  }
+
+}
+
+package java.util.zip {
+
+  public class ZipEntry implements java.lang.Cloneable {
+    method public long getDataOffset();
+  }
+
+}
+
+package javax.net.ssl {
+
+  public abstract class HttpsURLConnection extends java.net.HttpURLConnection {
+    method public static javax.net.ssl.HostnameVerifier getStrictHostnameVerifier();
+  }
+
+}
+
+package libcore.content.type {
+
+  public final class MimeMap {
+    method @NonNull public libcore.content.type.MimeMap.Builder buildUpon();
+    method @NonNull public static libcore.content.type.MimeMap.Builder builder();
+    method @NonNull public java.util.Set<java.lang.String> extensions();
+    method @NonNull public static libcore.content.type.MimeMap getDefault();
+    method @Nullable public String guessExtensionFromMimeType(@Nullable String);
+    method @Nullable public String guessMimeTypeFromExtension(@Nullable String);
+    method public boolean hasExtension(@Nullable String);
+    method public boolean hasMimeType(@Nullable String);
+    method @NonNull public java.util.Set<java.lang.String> mimeTypes();
+    method public static void setDefaultSupplier(@NonNull java.util.function.Supplier<libcore.content.type.MimeMap>);
+  }
+
+  public static final class MimeMap.Builder {
+    method @NonNull public libcore.content.type.MimeMap.Builder addMimeMapping(@NonNull String, @NonNull java.util.List<java.lang.String>);
+    method @NonNull public libcore.content.type.MimeMap build();
+  }
+
+}
+
+package libcore.io {
+
+  public class ForwardingOs implements libcore.io.Os {
+    ctor protected ForwardingOs(@NonNull libcore.io.Os);
+    method public boolean access(@Nullable String, int) throws android.system.ErrnoException;
+    method public java.io.FileDescriptor open(@Nullable String, int, int) throws android.system.ErrnoException;
+    method public void remove(@Nullable String) throws android.system.ErrnoException;
+    method public void rename(@Nullable String, @Nullable String) throws android.system.ErrnoException;
+    method @Nullable public android.system.StructStat stat(@Nullable String) throws android.system.ErrnoException;
+    method public void unlink(@Nullable String) throws android.system.ErrnoException;
+  }
+
+  public final class IoUtils {
+    method public static int acquireRawFd(@NonNull java.io.FileDescriptor);
+    method public static void close(@Nullable java.io.FileDescriptor) throws java.io.IOException;
+    method public static void closeQuietly(@Nullable AutoCloseable);
+    method public static void closeQuietly(@Nullable java.io.FileDescriptor);
+    method public static void closeQuietly(@Nullable java.net.Socket);
+    method @NonNull public static byte[] readFileAsByteArray(@NonNull String) throws java.io.IOException;
+    method @NonNull public static String readFileAsString(@NonNull String) throws java.io.IOException;
+    method public static void setBlocking(@NonNull 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(@NonNull Object, int, @NonNull Object, int, long);
+    method public static int peekInt(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static short peekShort(@NonNull byte[], int, @NonNull java.nio.ByteOrder);
+    method public static void pokeInt(@NonNull byte[], int, int, @NonNull java.nio.ByteOrder);
+    method public static void pokeLong(@NonNull byte[], int, long, @NonNull java.nio.ByteOrder);
+    method public static void pokeShort(@NonNull byte[], int, short, @NonNull 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 public static int copy(@NonNull java.io.InputStream, @NonNull java.io.OutputStream) throws java.io.IOException;
+    method public static void readFully(@NonNull java.io.InputStream, @NonNull byte[]) throws java.io.IOException;
+    method @NonNull public static byte[] readFully(@NonNull java.io.InputStream) throws java.io.IOException;
+    method @NonNull public static String readFully(@NonNull java.io.Reader) throws java.io.IOException;
+    method @NonNull public static byte[] readFullyNoClose(@NonNull java.io.InputStream) throws java.io.IOException;
+    method public static int readSingleByte(@NonNull java.io.InputStream) throws java.io.IOException;
+    method public static long skipByReading(@NonNull java.io.InputStream, long) throws java.io.IOException;
+    method public static void writeSingleByte(@NonNull 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 abstract class NetworkSecurityPolicy {
+    ctor public NetworkSecurityPolicy();
+    method public static libcore.net.NetworkSecurityPolicy getInstance();
+    method public abstract boolean isCertificateTransparencyVerificationRequired(String);
+    method public abstract boolean isCleartextTrafficPermitted();
+    method public abstract boolean isCleartextTrafficPermitted(String);
+    method public static void setInstance(libcore.net.NetworkSecurityPolicy);
+  }
+
+}
+
+package libcore.net.event {
+
+  public final class NetworkEventDispatcher {
+    method public void dispatchNetworkConfigurationChange();
+    method public static libcore.net.event.NetworkEventDispatcher getInstance();
+  }
+
+}
+
+package libcore.net.http {
+
+  public interface Dns {
+    method @NonNull public java.util.List<java.net.InetAddress> lookup(@Nullable String) throws java.net.UnknownHostException;
+  }
+
+  public class HttpURLConnectionFactory {
+    method @NonNull public static libcore.net.http.HttpURLConnectionFactory createInstance();
+    method public java.net.URLConnection openConnection(@NonNull java.net.URL, @NonNull javax.net.SocketFactory, @NonNull java.net.Proxy) throws java.io.IOException;
+    method public void setDns(@NonNull libcore.net.http.Dns);
+    method public void setNewConnectionPool(int, long, @NonNull java.util.concurrent.TimeUnit);
+  }
+
+}
+
+package libcore.util {
+
+  public final class FP16 {
+    method public static short ceil(short);
+    method public static int compare(short, short);
+    method public static boolean equals(short, short);
+    method public static short floor(short);
+    method public static boolean greater(short, short);
+    method public static boolean greaterEquals(short, short);
+    method public static boolean isInfinite(short);
+    method public static boolean isNaN(short);
+    method public static boolean isNormalized(short);
+    method public static boolean less(short, short);
+    method public static boolean lessEquals(short, short);
+    method public static short max(short, short);
+    method public static short min(short, short);
+    method public static short rint(short);
+    method public static float toFloat(short);
+    method public static short toHalf(float);
+    method public static String toHexString(short);
+    method public static short trunc(short);
+    field public static final short EPSILON = 5120; // 0x1400
+    field public static final int EXPONENT_BIAS = 15; // 0xf
+    field public static final int EXPONENT_SHIFT = 10; // 0xa
+    field public static final int EXPONENT_SIGNIFICAND_MASK = 32767; // 0x7fff
+    field public static final short LOWEST_VALUE = -1025; // 0xfffffbff
+    field public static final int MAX_EXPONENT = 15; // 0xf
+    field public static final short MAX_VALUE = 31743; // 0x7bff
+    field public static final int MIN_EXPONENT = -14; // 0xfffffff2
+    field public static final short MIN_NORMAL = 1024; // 0x400
+    field public static final short MIN_VALUE = 1; // 0x1
+    field public static final short NEGATIVE_INFINITY = -1024; // 0xfffffc00
+    field public static final short NEGATIVE_ZERO = -32768; // 0xffff8000
+    field public static final short NaN = 32256; // 0x7e00
+    field public static final short POSITIVE_INFINITY = 31744; // 0x7c00
+    field public static final short POSITIVE_ZERO = 0; // 0x0
+    field public static final int SHIFTED_EXPONENT_MASK = 31; // 0x1f
+    field public static final int SIGNIFICAND_MASK = 1023; // 0x3ff
+    field public static final int SIGN_MASK = 32768; // 0x8000
+    field public static final int SIGN_SHIFT = 15; // 0xf
+    field public static final int SIZE = 16; // 0x10
+  }
+
+  public class HexEncoding {
+    method public static byte[] decode(String) throws java.lang.IllegalArgumentException;
+    method public static byte[] decode(String, boolean) 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[], boolean);
+    method public static char[] encode(byte[], int, int);
+    method public static String encodeToString(byte, boolean);
+    method public static String encodeToString(byte[]);
+    method public static String encodeToString(byte[], boolean);
+  }
+
+  public class NativeAllocationRegistry {
+    ctor public NativeAllocationRegistry(@NonNull ClassLoader, long, long);
+    method public static void applyFreeFunction(long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(@NonNull ClassLoader, long, long);
+    method public static libcore.util.NativeAllocationRegistry createMalloced(@NonNull ClassLoader, long);
+    method public static libcore.util.NativeAllocationRegistry createNonmalloced(@NonNull ClassLoader, long, long);
+    method @NonNull public Runnable registerNativeAllocation(@NonNull Object, long);
+  }
+
+  public class SneakyThrow {
+    method public static void sneakyThrow(@NonNull Throwable);
+  }
+
+  public class XmlObjectFactory {
+    method @NonNull public static org.xml.sax.XMLReader newXMLReader();
+    method @NonNull public static org.xmlpull.v1.XmlPullParser newXmlPullParser();
+    method @NonNull public static org.xmlpull.v1.XmlSerializer newXmlSerializer();
+  }
+
+}
+
+package org.apache.harmony.dalvik.ddmc {
+
+  public class Chunk {
+    ctor public Chunk(int, byte[], int, int);
+    ctor public Chunk(int, java.nio.ByteBuffer);
+    field public int type;
+  }
+
+  public abstract class ChunkHandler {
+    ctor public ChunkHandler();
+    method public static org.apache.harmony.dalvik.ddmc.Chunk createFailChunk(int, String);
+    method public abstract org.apache.harmony.dalvik.ddmc.Chunk handleChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    method public static String name(int);
+    method public abstract void onConnected();
+    method public abstract void onDisconnected();
+    method public static int type(String);
+    method public static java.nio.ByteBuffer wrapChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    field public static final java.nio.ByteOrder CHUNK_ORDER;
+  }
+
+  public final class DdmServer {
+    method public static void registerHandler(int, org.apache.harmony.dalvik.ddmc.ChunkHandler);
+    method public static void registrationComplete();
+    method public static void sendChunk(org.apache.harmony.dalvik.ddmc.Chunk);
+    method public static org.apache.harmony.dalvik.ddmc.ChunkHandler unregisterHandler(int);
+  }
+
+  public final class DdmVmInternal {
+    method public static void setRecentAllocationsTrackingEnabled(boolean);
+    method public static void setThreadNotifyEnabled(boolean);
+  }
+
+}
+
+package org.json {
+
+  public class JSONObject {
+    method @NonNull 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 public int arrayIndexScale(Class);
+    method public void copyMemory(long, long, long);
+    method public boolean getBoolean(Object, long);
+    method public byte getByte(Object, long);
+    method public byte getByte(long);
+    method public double getDouble(Object, long);
+    method public double getDouble(long);
+    method public float getFloat(Object, long);
+    method public float getFloat(long);
+    method public int getInt(Object, long);
+    method public int getInt(long);
+    method public long getLong(Object, long);
+    method public long getLong(long);
+    method public Object getObject(Object, long);
+    method public static sun.misc.Unsafe getUnsafe();
+    method public long objectFieldOffset(java.lang.reflect.Field);
+    method public void putBoolean(Object, long, boolean);
+    method public void putByte(Object, long, byte);
+    method public void putByte(long, byte);
+    method public void putDouble(Object, long, double);
+    method public void putDouble(long, double);
+    method public void putFloat(Object, long, float);
+    method public void putFloat(long, float);
+    method public void putInt(Object, long, int);
+    method public void putInt(long, int);
+    method public void putLong(Object, long, long);
+    method public void putLong(long, long);
+    method public void putObject(Object, long, Object);
+  }
+
+}
+
+package sun.security.jca {
+
+  public class Providers {
+    method public static Object startJarVerification();
+    method public static void stopJarVerification(Object);
+  }
+
+}
+
+package sun.security.pkcs {
+
+  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.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();
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/stable_platform/last-api.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/last-api.txt
copy to mmodules/core_platform_api/api/stable_platform/last-api.txt
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/core_platform_api/api/stable_platform/last-incompatibilities.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/last-api.txt
copy to mmodules/core_platform_api/api/stable_platform/last-incompatibilities.txt
diff --git a/mmodules/core_platform_api/api/platform/last-removed.txt b/mmodules/core_platform_api/api/stable_platform/last-removed.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/last-removed.txt
copy to mmodules/core_platform_api/api/stable_platform/last-removed.txt
diff --git a/mmodules/core_platform_api/api/platform/current-removed.txt b/mmodules/core_platform_api/api/stable_platform/removed.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/current-removed.txt
copy to mmodules/core_platform_api/api/stable_platform/removed.txt
diff --git a/mmodules/intracoreapi/Android.bp b/mmodules/intracoreapi/Android.bp
index c2a3de3..513b044 100644
--- a/mmodules/intracoreapi/Android.bp
+++ b/mmodules/intracoreapi/Android.bp
@@ -12,59 +12,99 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-// Generates stub source files for the intra-core API of the ART module.
-// i.e. every class/member that is either in the public API or annotated with
-// @IntraCoreApi.
-//
-// The API specification .txt files managed by this only contain the additional
-// classes/members that are in the intra-core API but which are not in the public
-// API.
-droidstubs {
-    name: "art-module-intra-core-api-stubs-source",
+// Referenced implicitly from art.module.intra.core.api.
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-GPL
+    //   SPDX-license-identifier-GPL-2.0
+    //   SPDX-license-identifier-LGPL
+    //   SPDX-license-identifier-MIT
+    //   SPDX-license-identifier-W3C
+    default_applicable_licenses: ["libcore_license"],
+}
+
+filegroup {
+    name: "art.module.intra.core.api.api.public.latest",
     srcs: [
-        ":art_module_api_files",
+        "api/intra/last-api.txt",
     ],
-    sdk_version: "none",
-    system_modules: "none",
+}
 
-    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"],
+// Referenced implicitly from art.module.intra.core.api.
+filegroup {
+    name: "art.module.intra.core.api-removed.api.public.latest",
+    srcs: [
+        "api/intra/last-removed.txt",
+    ],
+}
 
-    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",
-        },
-    },
+// Referenced implicitly from art.module.intra.core.api.
+filegroup {
+    name: "art.module.intra.core.api-incompatibilities.api.public.latest",
+    srcs: [
+        "api/intra/last-incompatibilities.txt",
+    ],
 }
 
 // A library containing the intra-core API stubs of the ART module.
 //
 // Intra-core APIs are only intended for the use of other core library modules.
-java_library {
-    name: "art.module.intra.core.api.stubs",
+//
+// The API specification .txt files managed by this only contain the additional
+// classes/members that are in the intra-core API but which are not the public API.
+java_sdk_library {
+    name: "art.module.intra.core.api",
     visibility: [
         "//libcore/mmodules/core_platform_api",
     ],
     srcs: [
-        ":art-module-intra-core-api-stubs-source",
-        ":openjdk_lambda_stub_files",
-        ":openjdk_generated_annotation_stub_files",
+        ":art_module_api_files",
     ],
+    api_dir: "api/intra",
+    api_only: true,
+    droiddoc_options: [
+        "--hide-annotation libcore.api.Hide",
+        "--show-single-annotation libcore.api.IntraCoreApi",
+        "--skip-annotation-instance-methods=false",
+    ],
+    merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
 
     sdk_version: "none",
     system_modules: "none",
     patch_module: "java.base",
+
+    // Don't copy any output files to the dist.
+    no_dist: true,
+}
+
+// Bootstrap the art-module-intra-core-api-stubs-system-modules.
+//
+// This is needed to build art-module-intra-core-api-stubs-system-modules-lib
+// which is in turn needed to build art-module-intra-core-api-stubs-system-modules
+java_system_modules {
+    name: "art-module-intra-core-api-stubs-bootstrap-system-modules",
+    libs: [
+        // The intra core API stubs library.
+        "art.module.intra.core.api.stubs",
+    ],
+}
+
+// A library containing additional classes that are needed in the system modules.
+java_library {
+    name: "art-module-intra-core-api-stubs-system-modules-lib",
+    srcs: [
+        ":openjdk_lambda_stub_files",
+        ":openjdk_generated_annotation_stub_files",
+    ],
+    libs: [
+        "art.module.intra.core.api",
+    ],
+    system_modules: "art-module-intra-core-api-stubs-bootstrap-system-modules",
+    sdk_version: "none",
+    patch_module: "java.base",
 }
 
 // Used when compiling against art.module.intra.core.api.stubs.
@@ -76,5 +116,11 @@
         "//external/conscrypt",
         "//external/icu/android_icu4j",
     ],
-    libs: ["art.module.intra.core.api.stubs"],
+    libs: [
+        // The intra core API stubs library.
+        "art.module.intra.core.api.stubs",
+
+        // Additional classes needed by javac but which are not present in the stubs.
+        "art-module-intra-core-api-stubs-system-modules-lib",
+    ],
 }
diff --git a/mmodules/intracoreapi/api/intra/current-api.txt b/mmodules/intracoreapi/api/intra/current-api.txt
deleted file mode 100644
index f98906f..0000000
--- a/mmodules/intracoreapi/api/intra/current-api.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-// Signature format: 2.0
-package android.compat {
-
-  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class Compatibility {
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static boolean isChangeEnabled(long);
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static void reportChange(long);
-  }
-
-  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static final class Compatibility.ChangeConfig {
-    ctor public Compatibility.ChangeConfig(java.util.Set<java.lang.Long>, java.util.Set<java.lang.Long>);
-    method public long[] forceDisabledChangesArray();
-    method public java.util.Set<java.lang.Long> forceDisabledSet();
-    method public long[] forceEnabledChangesArray();
-    method public java.util.Set<java.lang.Long> forceEnabledSet();
-    method public boolean isEmpty();
-    method public boolean isForceDisabled(long);
-    method public boolean isForceEnabled(long);
-  }
-
-}
-
-package dalvik.annotation.compat {
-
-  @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
-    field @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static final int Q = 29; // 0x1d
-  }
-
-}
-
-package dalvik.annotation.optimization {
-
-  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @libcore.api.IntraCoreApi public @interface ReachabilitySensitive {
-  }
-
-}
-
-package dalvik.system {
-
-  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class BlockGuard {
-    method @NonNull @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 @libcore.api.IntraCoreApi public void onNetwork();
-  }
-
-  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public final class CloseGuard {
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void close();
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static dalvik.system.CloseGuard get();
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void open(String);
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public void warnIfOpen();
-  }
-
-}
-
-package java.net {
-
-  public class Socket implements java.io.Closeable {
-    method @libcore.api.IntraCoreApi public java.io.FileDescriptor getFileDescriptor$();
-  }
-
-}
-
-package java.nio.charset {
-
-  public abstract class Charset implements java.lang.Comparable<java.nio.charset.Charset> {
-    ctor @libcore.api.IntraCoreApi protected Charset(String, String[]);
-  }
-
-  public abstract class CharsetDecoder {
-    ctor @libcore.api.IntraCoreApi protected CharsetDecoder(java.nio.charset.Charset, float, float);
-  }
-
-  public abstract class CharsetEncoder {
-    ctor @libcore.api.IntraCoreApi protected CharsetEncoder(java.nio.charset.Charset, float, float, byte[], boolean);
-  }
-
-}
-
-package java.security.spec {
-
-  public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
-    method @libcore.api.IntraCoreApi public String getCurveName();
-    method @libcore.api.IntraCoreApi 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.io {
-
-  @libcore.api.IntraCoreApi public final class AsynchronousCloseMonitor {
-    method @libcore.api.IntraCoreApi public static void signalBlockedThreads(java.io.FileDescriptor);
-  }
-
-}
-
-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 {
-
-  @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public class NativeAllocationRegistry {
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public static libcore.util.NativeAllocationRegistry createMalloced(ClassLoader, long);
-    method @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public Runnable registerNativeAllocation(Object, long);
-  }
-
-  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, 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.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE_USE}) @libcore.api.IntraCoreApi public @interface Nullable {
-  }
-
-}
-
-package sun.security.util {
-
-  @libcore.api.IntraCoreApi public interface DerEncoder {
-    method @libcore.api.IntraCoreApi public void derEncode(java.io.OutputStream) throws java.io.IOException;
-  }
-
-}
-
-package sun.security.x509 {
-
-  @libcore.api.IntraCoreApi public class AlgorithmId implements sun.security.util.DerEncoder java.io.Serializable {
-    method @libcore.api.IntraCoreApi public void derEncode(java.io.OutputStream) throws java.io.IOException;
-    method @libcore.api.IntraCoreApi public static sun.security.x509.AlgorithmId get(String) throws java.security.NoSuchAlgorithmException;
-    method @libcore.api.IntraCoreApi public String getName();
-  }
-
-}
-
diff --git a/mmodules/intracoreapi/api/intra/current.txt b/mmodules/intracoreapi/api/intra/current.txt
new file mode 100644
index 0000000..3b9b746
--- /dev/null
+++ b/mmodules/intracoreapi/api/intra/current.txt
@@ -0,0 +1,169 @@
+// Signature format: 2.0
+package android.compat {
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public final class Compatibility {
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static boolean isChangeEnabled(long);
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static void reportUnconditionalChange(long);
+  }
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static final class Compatibility.ChangeConfig {
+    ctor public Compatibility.ChangeConfig(@NonNull java.util.Set<java.lang.Long>, @NonNull java.util.Set<java.lang.Long>);
+    method @NonNull public long[] getDisabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getDisabledSet();
+    method @NonNull public long[] getEnabledChangesArray();
+    method @NonNull public java.util.Set<java.lang.Long> getEnabledSet();
+    method public boolean isEmpty();
+    method public boolean isForceDisabled(long);
+    method public boolean isForceEnabled(long);
+  }
+
+}
+
+package android.system {
+
+  public final class Os {
+    method @Nullable @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static String realpath(@Nullable String) throws android.system.ErrnoException;
+  }
+
+}
+
+package dalvik.annotation.compat {
+
+  @libcore.api.IntraCoreApi public class VersionCodes {
+    field @libcore.api.IntraCoreApi public static final int CUR_DEVELOPMENT = 10000; // 0x2710
+    field @libcore.api.IntraCoreApi public static final int O = 26; // 0x1a
+    field @libcore.api.IntraCoreApi public static final int P = 28; // 0x1c
+    field @libcore.api.IntraCoreApi public static final int Q = 29; // 0x1d
+    field @libcore.api.IntraCoreApi public static final int R = 30; // 0x1e
+    field @libcore.api.IntraCoreApi public static final int S = 10000; // 0x2710
+  }
+
+}
+
+package dalvik.annotation.optimization {
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @libcore.api.CorePlatformApi @libcore.api.IntraCoreApi public @interface FastNative {
+  }
+
+  @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD}) @libcore.api.IntraCoreApi public @interface ReachabilitySensitive {
+  }
+
+}
+
+package dalvik.system {
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public final class BlockGuard {
+    method @NonNull @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static dalvik.system.BlockGuard.Policy getThreadPolicy();
+  }
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static interface BlockGuard.Policy {
+    method @libcore.api.IntraCoreApi public void onNetwork();
+  }
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public final class CloseGuard {
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public void close();
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static dalvik.system.CloseGuard get();
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public void open(String);
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public void warnIfOpen();
+  }
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public final class VMRuntime {
+    method @dalvik.annotation.optimization.FastNative @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public long addressOf(Object);
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static dalvik.system.VMRuntime getRuntime();
+    method @dalvik.annotation.optimization.FastNative @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public Object newNonMovableArray(Class<?>, int);
+  }
+
+}
+
+package java.net {
+
+  public class Socket implements java.io.Closeable {
+    method @libcore.api.IntraCoreApi public java.io.FileDescriptor getFileDescriptor$();
+  }
+
+}
+
+package java.nio.charset {
+
+  public abstract class CharsetEncoder {
+    ctor @libcore.api.IntraCoreApi protected CharsetEncoder(java.nio.charset.Charset, float, float, byte[], boolean);
+  }
+
+}
+
+package java.security.spec {
+
+  public class ECParameterSpec implements java.security.spec.AlgorithmParameterSpec {
+    method @libcore.api.IntraCoreApi public String getCurveName();
+    method @libcore.api.IntraCoreApi 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 {
+    method @libcore.api.IntraCoreApi public abstract libcore.api.CorePlatformApi.Status status() default libcore.api.CorePlatformApi.Status.LEGACY_ONLY;
+  }
+
+  @libcore.api.IntraCoreApi public enum CorePlatformApi.Status {
+    enum_constant @libcore.api.IntraCoreApi public static final libcore.api.CorePlatformApi.Status LEGACY_ONLY;
+    enum_constant @libcore.api.IntraCoreApi public static final libcore.api.CorePlatformApi.Status STABLE;
+  }
+
+  @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.io {
+
+  @libcore.api.IntraCoreApi public final class AsynchronousCloseMonitor {
+    method @libcore.api.IntraCoreApi public static void signalBlockedThreads(java.io.FileDescriptor);
+  }
+
+}
+
+package libcore.net {
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public abstract class NetworkSecurityPolicy {
+    ctor @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public NetworkSecurityPolicy();
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static libcore.net.NetworkSecurityPolicy getInstance();
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public abstract boolean isCertificateTransparencyVerificationRequired(String);
+  }
+
+}
+
+package libcore.util {
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public class NativeAllocationRegistry {
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public static libcore.util.NativeAllocationRegistry createMalloced(@NonNull ClassLoader, long);
+    method @NonNull @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public Runnable registerNativeAllocation(@NonNull Object, long);
+  }
+
+  @java.lang.annotation.Documented @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, 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.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.TYPE_USE}) @libcore.api.IntraCoreApi public @interface Nullable {
+  }
+
+}
+
+package sun.security.util {
+
+  @libcore.api.IntraCoreApi public interface DerEncoder {
+    method @libcore.api.IntraCoreApi public void derEncode(java.io.OutputStream) throws java.io.IOException;
+  }
+
+}
+
+package sun.security.x509 {
+
+  @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public class AlgorithmId implements sun.security.util.DerEncoder java.io.Serializable {
+    method @libcore.api.IntraCoreApi public void derEncode(java.io.OutputStream) throws java.io.IOException;
+    method @libcore.api.IntraCoreApi public static sun.security.x509.AlgorithmId get(String) throws java.security.NoSuchAlgorithmException;
+    method @libcore.api.CorePlatformApi(status=libcore.api.CorePlatformApi.Status.STABLE) @libcore.api.IntraCoreApi public String getName();
+  }
+
+}
+
diff --git a/mmodules/core_platform_api/api/platform/last-api.txt b/mmodules/intracoreapi/api/intra/last-incompatibilities.txt
similarity index 100%
copy from mmodules/core_platform_api/api/platform/last-api.txt
copy to mmodules/intracoreapi/api/intra/last-incompatibilities.txt
diff --git a/mmodules/intracoreapi/api/intra/current-removed.txt b/mmodules/intracoreapi/api/intra/removed.txt
similarity index 100%
rename from mmodules/intracoreapi/api/intra/current-removed.txt
rename to mmodules/intracoreapi/api/intra/removed.txt
diff --git a/non_openjdk_java_files.bp b/non_openjdk_java_files.bp
old mode 100644
new mode 100755
index e3c8c16..59a78e3
--- a/non_openjdk_java_files.bp
+++ b/non_openjdk_java_files.bp
@@ -32,11 +32,10 @@
         "dalvik/src/main/java/dalvik/bytecode/OpcodeInfo.java",
         "dalvik/src/main/java/dalvik/bytecode/Opcodes.java",
         "dalvik/src/main/java/dalvik/system/AllocationLimitError.java",
+        "dalvik/src/main/java/dalvik/system/AppSpecializationHooks.java",
         "dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java",
         "dalvik/src/main/java/dalvik/system/BlockGuard.java",
         "dalvik/src/main/java/dalvik/system/CloseGuard.java",
-        "dalvik/src/main/java/dalvik/system/DalvikLogHandler.java",
-        "dalvik/src/main/java/dalvik/system/DalvikLogging.java",
         "dalvik/src/main/java/dalvik/system/DelegateLastClassLoader.java",
         "dalvik/src/main/java/dalvik/system/DexClassLoader.java",
         "dalvik/src/main/java/dalvik/system/DexFile.java",
@@ -49,10 +48,8 @@
         "dalvik/src/main/java/dalvik/system/RuntimeHooks.java",
         "dalvik/src/main/java/dalvik/system/SocketTagger.java",
         "dalvik/src/main/java/dalvik/system/TemporaryDirectory.java",
-        "dalvik/src/main/java/dalvik/system/ThreadPrioritySetter.java",
         "dalvik/src/main/java/dalvik/system/VMDebug.java",
         "dalvik/src/main/java/dalvik/system/ZygoteHooks.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",
@@ -143,9 +140,11 @@
         "luni/src/main/java/android/system/StructAddrinfo.java",
         "luni/src/main/java/android/system/StructCapUserData.java",
         "luni/src/main/java/android/system/StructCapUserHeader.java",
+        "luni/src/main/java/android/system/StructCmsghdr.java",
         "luni/src/main/java/android/system/StructGroupReq.java",
         "luni/src/main/java/android/system/StructIfaddrs.java",
         "luni/src/main/java/android/system/StructLinger.java",
+        "luni/src/main/java/android/system/StructMsghdr.java",
         "luni/src/main/java/android/system/StructPasswd.java",
         "luni/src/main/java/android/system/StructPollfd.java",
         "luni/src/main/java/android/system/StructRlimit.java",
@@ -156,20 +155,9 @@
         "luni/src/main/java/android/system/StructUcred.java",
         "luni/src/main/java/android/system/StructUtsname.java",
         "luni/src/main/java/android/system/UnixSocketAddress.java",
+        "luni/src/main/java/android/system/VmSocketAddress.java",
         "luni/src/main/java/java/lang/FindBugsSuppressWarnings.java",
         "luni/src/main/java/java/lang/ref/FinalizerReference.java",
-        "luni/src/main/java/java/math/BigDecimal.java",
-        "luni/src/main/java/java/math/BigInt.java",
-        "luni/src/main/java/java/math/BigInteger.java",
-        "luni/src/main/java/java/math/BitLevel.java",
-        "luni/src/main/java/java/math/Conversion.java",
-        "luni/src/main/java/java/math/Division.java",
-        "luni/src/main/java/java/math/Logical.java",
-        "luni/src/main/java/java/math/MathContext.java",
-        "luni/src/main/java/java/math/Multiplication.java",
-        "luni/src/main/java/java/math/NativeBN.java",
-        "luni/src/main/java/java/math/Primality.java",
-        "luni/src/main/java/java/math/RoundingMode.java",
         "luni/src/main/java/java/net/DefaultFileNameMap.java",
         "luni/src/main/java/java/nio/NIOAccess.java",
         "luni/src/main/java/java/nio/NioUtils.java",
@@ -235,9 +223,7 @@
         "luni/src/main/java/libcore/icu/DateIntervalFormat.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/AsynchronousCloseMonitor.java",
         "luni/src/main/java/libcore/io/ForwardingOs.java",
         "luni/src/main/java/libcore/io/IoBridge.java",
@@ -249,20 +235,10 @@
         "luni/src/main/java/libcore/net/InetAddressUtils.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/TelephonyLookup.java",
-        "luni/src/main/java/libcore/timezone/TelephonyNetwork.java",
-        "luni/src/main/java/libcore/timezone/TelephonyNetworkFinder.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/XmlUtils.java",
-        "luni/src/main/java/libcore/timezone/ZoneInfoDb.java",
+        "luni/src/main/java/libcore/net/http/Dns.java",
+        "luni/src/main/java/libcore/net/http/HttpURLConnectionFactory.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/FP16.java",
         "luni/src/main/java/libcore/util/HexEncoding.java",
@@ -374,9 +350,9 @@
     srcs: [
         "luni/src/main/java/java/net/AddressCache.java",
         "luni/src/main/java/libcore/icu/CollationKeyICU.java",
-        "luni/src/main/java/libcore/icu/DateTimeFormat.java",
         "luni/src/main/java/libcore/icu/DateUtilsBridge.java",
         "luni/src/main/java/libcore/internal/Java9LanguageFeatures.java",
+        "luni/src/main/java/libcore/internal/StringPool.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",
@@ -385,6 +361,7 @@
         "luni/src/main/java/libcore/io/MemoryMappedFile.java",
         "luni/src/main/java/libcore/io/NioBufferIterator.java",
         "luni/src/main/java/libcore/math/MathUtils.java",
+        "luni/src/main/java/libcore/math/NativeBN.java",
         "luni/src/main/java/libcore/net/event/NetworkEventListener.java",
         "luni/src/main/java/libcore/net/http/HttpDate.java",
         "luni/src/main/java/libcore/reflect/AnnotatedElements.java",
@@ -438,15 +415,3 @@
         ":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/TimeZoneDataFiles.java",
-        "luni/src/main/java/libcore/timezone/TzDataSetVersion.java",
-    ],
-}
diff --git a/ojluni/Android.bp b/ojluni/Android.bp
index 20a5a5a..4c9e703 100644
--- a/ojluni/Android.bp
+++ b/ojluni/Android.bp
@@ -12,6 +12,38 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    default_applicable_licenses: ["libcore_ojluni_license"],
+}
+
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'filegroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// http://go/android-license-faq
+license {
+    name: "libcore_ojluni_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
+        "SPDX-license-identifier-GPL-2.0",
+        "SPDX-license-identifier-GPL-with-classpath-exception",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 // Phony target that causes the build to check the license file in this
 // directory, detect that it is a GPL license and then copy all the files
 // from this directory and its subdirectories in to the
@@ -21,6 +53,6 @@
 
     // A phony module must have at least one dependency.
     required: [
-        "core-oj",
+        "core-all",
     ],
 }
diff --git a/ojluni/annotations/hiddenapi/java/io/Console.java b/ojluni/annotations/hiddenapi/java/io/Console.java
index 24039a1..2f74f97 100644
--- a/ojluni/annotations/hiddenapi/java/io/Console.java
+++ b/ojluni/annotations/hiddenapi/java/io/Console.java
@@ -75,7 +75,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static native java.lang.String encoding();
 
     private static native boolean echo(boolean on) throws java.io.IOException;
diff --git a/ojluni/annotations/hiddenapi/java/io/File.java b/ojluni/annotations/hiddenapi/java/io/File.java
index bdcce88..3a6a78d 100644
--- a/ojluni/annotations/hiddenapi/java/io/File.java
+++ b/ojluni/annotations/hiddenapi/java/io/File.java
@@ -298,7 +298,7 @@
         UNSAFE = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private transient volatile java.nio.file.Path filePath;
 
     @UnsupportedAppUsage
@@ -308,7 +308,7 @@
         fs = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.lang.String path;
 
     {
@@ -327,7 +327,7 @@
         pathSeparatorChar = 0;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final transient int prefixLength;
 
     {
@@ -348,7 +348,7 @@
 
     private static final long serialVersionUID = 301077366599181567L; // 0x42da4450e0de4ffL
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private transient java.io.File.PathStatus status;
 
     @SuppressWarnings({"unchecked", "deprecation", "all"})
diff --git a/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java b/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java
index 6e9e74d..00c0915 100644
--- a/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java
+++ b/ojluni/annotations/hiddenapi/java/io/FileDescriptor.java
@@ -66,7 +66,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public boolean isSocket$() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/io/FileInputStream.java b/ojluni/annotations/hiddenapi/java/io/FileInputStream.java
index 1999d13..5f2bdd4 100644
--- a/ojluni/annotations/hiddenapi/java/io/FileInputStream.java
+++ b/ojluni/annotations/hiddenapi/java/io/FileInputStream.java
@@ -104,7 +104,7 @@
 
     private volatile boolean closed = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.io.FileDescriptor fd;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java b/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java
index 5e35fc0..69b0dc9 100644
--- a/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java
+++ b/ojluni/annotations/hiddenapi/java/io/FileOutputStream.java
@@ -109,7 +109,7 @@
 
     private volatile boolean closed = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.io.FileDescriptor fd;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java b/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java
index 1e429a4..25b28337 100644
--- a/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java
+++ b/ojluni/annotations/hiddenapi/java/io/ObjectOutputStream.java
@@ -300,7 +300,7 @@
 
     private byte[] primVals;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int protocol = 2; // 0x2
 
     private final java.io.ObjectOutputStream.ReplaceTable subs;
diff --git a/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java b/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java
index 5bc7d69..a4b6a96 100644
--- a/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java
+++ b/ojluni/annotations/hiddenapi/java/io/RandomAccessFile.java
@@ -225,7 +225,7 @@
 
     private volatile boolean closed = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.io.FileDescriptor fd;
 
     private int flushAfterWrite = 0; // 0x0
diff --git a/ojluni/annotations/hiddenapi/java/lang/Class.java b/ojluni/annotations/hiddenapi/java/lang/Class.java
index a9c1515..30b28ed 100644
--- a/ojluni/annotations/hiddenapi/java/lang/Class.java
+++ b/ojluni/annotations/hiddenapi/java/lang/Class.java
@@ -421,7 +421,7 @@
 
     private transient int classSize;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private transient int clinitThreadId;
 
     private transient java.lang.Class<?> componentType;
@@ -465,7 +465,7 @@
 
     private static final long serialVersionUID = 3206093459760846163L; // 0x2c7e5503d9bf9553L
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private transient int status;
 
     private transient java.lang.Class<? super T> superClass;
diff --git a/ojluni/annotations/hiddenapi/java/lang/Enum.java b/ojluni/annotations/hiddenapi/java/lang/Enum.java
index 8cd1b6d..06b3864 100644
--- a/ojluni/annotations/hiddenapi/java/lang/Enum.java
+++ b/ojluni/annotations/hiddenapi/java/lang/Enum.java
@@ -77,7 +77,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static <T extends java.lang.Enum<T>> T[] getSharedConstants(
             java.lang.Class<T> enumType) {
         throw new RuntimeException("Stub!");
@@ -96,14 +96,14 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.lang.String name;
 
     {
         name = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final int ordinal;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/lang/Runtime.java b/ojluni/annotations/hiddenapi/java/lang/Runtime.java
index 798967f..dab7708 100644
--- a/ojluni/annotations/hiddenapi/java/lang/Runtime.java
+++ b/ojluni/annotations/hiddenapi/java/lang/Runtime.java
@@ -31,7 +31,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class Runtime {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private Runtime() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/lang/String.java b/ojluni/annotations/hiddenapi/java/lang/String.java
index a7b137a..e3a264b 100644
--- a/ojluni/annotations/hiddenapi/java/lang/String.java
+++ b/ojluni/annotations/hiddenapi/java/lang/String.java
@@ -138,7 +138,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     native void getCharsNoCheck(int start, int end, char[] buffer, int index);
 
     @Deprecated
@@ -255,7 +255,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static int indexOf(
             char[] source,
             int sourceOffset,
@@ -289,7 +289,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static int lastIndexOf(
             char[] source,
             int sourceOffset,
@@ -457,7 +457,7 @@
         count = 0;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int hash;
 
     private static final java.io.ObjectStreamField[] serialPersistentFields;
diff --git a/ojluni/annotations/hiddenapi/java/lang/System.java b/ojluni/annotations/hiddenapi/java/lang/System.java
index 407473b..95a2ed2 100644
--- a/ojluni/annotations/hiddenapi/java/lang/System.java
+++ b/ojluni/annotations/hiddenapi/java/lang/System.java
@@ -31,7 +31,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class System {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private System() {
         throw new RuntimeException("Stub!");
     }
@@ -271,7 +271,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     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
diff --git a/ojluni/annotations/hiddenapi/java/lang/Thread.java b/ojluni/annotations/hiddenapi/java/lang/Thread.java
index 36ca327..235743c 100644
--- a/ojluni/annotations/hiddenapi/java/lang/Thread.java
+++ b/ojluni/annotations/hiddenapi/java/lang/Thread.java
@@ -55,7 +55,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     Thread(java.lang.ThreadGroup group, java.lang.String name, int priority, boolean daemon) {
         throw new RuntimeException("Stub!");
     }
@@ -306,7 +306,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public final void dispatchUncaughtException(java.lang.Throwable e) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java b/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java
index bc69033..da33ff9 100644
--- a/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java
+++ b/ojluni/annotations/hiddenapi/java/lang/ThreadGroup.java
@@ -159,7 +159,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     void add(java.lang.Thread t) {
         throw new RuntimeException("Stub!");
     }
@@ -168,7 +168,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     void threadTerminated(java.lang.Thread t) {
         throw new RuntimeException("Stub!");
     }
@@ -205,7 +205,7 @@
     @UnsupportedAppUsage
     java.lang.ThreadGroup[] groups;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static final java.lang.ThreadGroup mainThreadGroup;
 
     static {
@@ -216,7 +216,7 @@
 
     int nUnstartedThreads = 0; // 0x0
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     java.lang.String name;
 
     @UnsupportedAppUsage
diff --git a/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java b/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java
index ca5927b..8d8791a 100644
--- a/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java
+++ b/ojluni/annotations/hiddenapi/java/lang/ThreadLocal.java
@@ -63,7 +63,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     java.lang.ThreadLocal.ThreadLocalMap getMap(java.lang.Thread t) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/lang/Throwable.java b/ojluni/annotations/hiddenapi/java/lang/Throwable.java
index 00a3b2c..6dfb2ed 100644
--- a/ojluni/annotations/hiddenapi/java/lang/Throwable.java
+++ b/ojluni/annotations/hiddenapi/java/lang/Throwable.java
@@ -105,7 +105,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static native java.lang.Object nativeFillInStackTrace();
 
     public java.lang.StackTraceElement[] getStackTrace() {
@@ -166,7 +166,7 @@
     @UnsupportedAppUsage
     private java.lang.StackTraceElement[] stackTrace;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.util.List<java.lang.Throwable> suppressedExceptions;
 
     @SuppressWarnings({"unchecked", "deprecation", "all"})
diff --git a/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java b/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java
index fd92ce4..81cf355 100644
--- a/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java
+++ b/ojluni/annotations/hiddenapi/java/lang/invoke/SerializedLambda.java
@@ -29,7 +29,7 @@
 
 public final class SerializedLambda implements Serializable {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public SerializedLambda(Class<?> capturingClass,
                             String functionalInterfaceClass,
                             String functionalInterfaceMethodName,
@@ -41,7 +41,7 @@
                             String instantiatedMethodType,
                             Object[] capturedArgs) { }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public String getCapturingClass() {
         throw new RuntimeException("Stub!");
     }
@@ -81,12 +81,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public final String getInstantiatedMethodType() {
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public int getCapturedArgCount() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java b/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java
index 74359c1..41d6897 100644
--- a/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java
+++ b/ojluni/annotations/hiddenapi/java/lang/ref/Reference.java
@@ -43,7 +43,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final native T getReferent();
 
     public void clear() {
diff --git a/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java b/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java
index e123068..52d82d8 100644
--- a/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java
+++ b/ojluni/annotations/hiddenapi/java/lang/ref/ReferenceQueue.java
@@ -68,7 +68,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static void add(java.lang.ref.Reference<?> list) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java
index 5accc6a..ad0cf99 100644
--- a/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Constructor.java
@@ -40,7 +40,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.lang.reflect.Constructor<T> serializationCopy(
             java.lang.Class<?> ctor, java.lang.Class<?> cl) {
         throw new RuntimeException("Stub!");
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java
index 9982658..5795b8a 100644
--- a/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Parameter.java
@@ -30,7 +30,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Parameter implements java.lang.reflect.AnnotatedElement {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     Parameter(
             java.lang.String name,
             int modifiers,
diff --git a/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java b/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java
index 593de12..dc835bf 100644
--- a/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java
+++ b/ojluni/annotations/hiddenapi/java/lang/reflect/Proxy.java
@@ -98,7 +98,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.lang.Object invoke(
             java.lang.reflect.Proxy proxy, java.lang.reflect.Method method, java.lang.Object[] args)
             throws java.lang.Throwable {
diff --git a/ojluni/annotations/hiddenapi/java/net/HttpCookie.java b/ojluni/annotations/hiddenapi/java/net/HttpCookie.java
index 97189e4..bc80525 100644
--- a/ojluni/annotations/hiddenapi/java/net/HttpCookie.java
+++ b/ojluni/annotations/hiddenapi/java/net/HttpCookie.java
@@ -232,7 +232,7 @@
 
     private static final java.lang.String SET_COOKIE2 = "set-cookie2:";
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static final java.util.Map<java.lang.String, java.net.HttpCookie.CookieAttributeAssignor>
             assignors;
 
@@ -240,16 +240,16 @@
         assignors = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String comment;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String commentURL;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String domain;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.lang.String header;
 
     {
@@ -260,35 +260,35 @@
         publicAlternatives = "Use {@link #setHttpOnly()}/{@link #isHttpOnly()} instead.")
     private boolean httpOnly;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private long maxAge = -1L; // 0xffffffffffffffffL
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.lang.String name;
 
     {
         name = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String path;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String portlist;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean secure;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean toDiscard;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static final java.lang.String tspecials = ",;= \t";
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String value;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int version = 1; // 0x1
 
     @UnsupportedAppUsage
diff --git a/ojluni/annotations/hiddenapi/java/net/Inet4Address.java b/ojluni/annotations/hiddenapi/java/net/Inet4Address.java
index b8f60cb..6f04e54 100644
--- a/ojluni/annotations/hiddenapi/java/net/Inet4Address.java
+++ b/ojluni/annotations/hiddenapi/java/net/Inet4Address.java
@@ -31,7 +31,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Inet4Address extends java.net.InetAddress {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     Inet4Address() {
         throw new RuntimeException("Stub!");
     }
@@ -108,14 +108,14 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final java.net.InetAddress ALL;
 
     static {
         ALL = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final java.net.InetAddress ANY;
 
     static {
diff --git a/ojluni/annotations/hiddenapi/java/net/Inet6Address.java b/ojluni/annotations/hiddenapi/java/net/Inet6Address.java
index fc48ebc..a0fe9d8 100644
--- a/ojluni/annotations/hiddenapi/java/net/Inet6Address.java
+++ b/ojluni/annotations/hiddenapi/java/net/Inet6Address.java
@@ -31,7 +31,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Inet6Address extends java.net.InetAddress {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     Inet6Address() {
         throw new RuntimeException("Stub!");
     }
@@ -177,7 +177,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final java.net.InetAddress ANY;
 
     static {
@@ -206,7 +206,7 @@
         UNSAFE = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final transient java.net.Inet6Address.Inet6AddressHolder holder6;
 
     {
@@ -301,16 +301,16 @@
             throw new RuntimeException("Stub!");
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         byte[] ipaddress;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         int scope_id;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         boolean scope_id_set;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         java.net.NetworkInterface scope_ifname;
 
         boolean scope_ifname_set;
diff --git a/ojluni/annotations/hiddenapi/java/net/InetAddress.java b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
index 2be05b7..4951374 100644
--- a/ojluni/annotations/hiddenapi/java/net/InetAddress.java
+++ b/ojluni/annotations/hiddenapi/java/net/InetAddress.java
@@ -182,7 +182,7 @@
     }
 
     @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891,
-        publicAlternatives = "Use {@link android.net.InetAddresses#isNumericAddress} "
+        publicAlternatives = "Use {@code android.net.InetAddresses#isNumericAddress} "
         + "instead. There is a behavioural difference between the original method and its "
         + "replacement.")
     public static boolean isNumeric(java.lang.String address) {
@@ -202,7 +202,7 @@
      * @deprecated Use {@code android.net.InetAddresses.parseNumericAddress(String)} instead.
      */
     @UnsupportedAppUsage(maxTargetSdk = VersionCodes.P, trackingBug = 78686891,
-        publicAlternatives = "Use {@link android.net.InetAddresses#parseNumericAddress} "
+        publicAlternatives = "Use {@code android.net.InetAddresses#parseNumericAddress} "
         + "instead. There is a behavioural difference between the original method and its "
         + "replacement.")
     public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) {
@@ -289,16 +289,16 @@
             throw new RuntimeException("Stub!");
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         int address;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         int family;
 
         @UnsupportedAppUsage
         java.lang.String hostName;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         java.lang.String originalHostName;
     }
 }
diff --git a/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java b/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java
index 84d3537..fbd408e 100644
--- a/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java
+++ b/ojluni/annotations/hiddenapi/java/net/InterfaceAddress.java
@@ -30,7 +30,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class InterfaceAddress {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     InterfaceAddress() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/net/Proxy.java b/ojluni/annotations/hiddenapi/java/net/Proxy.java
index ff91f35..4ce14a3 100644
--- a/ojluni/annotations/hiddenapi/java/net/Proxy.java
+++ b/ojluni/annotations/hiddenapi/java/net/Proxy.java
@@ -30,7 +30,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class Proxy {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private Proxy() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/net/ServerSocket.java b/ojluni/annotations/hiddenapi/java/net/ServerSocket.java
index ad0788a..71b137e 100644
--- a/ojluni/annotations/hiddenapi/java/net/ServerSocket.java
+++ b/ojluni/annotations/hiddenapi/java/net/ServerSocket.java
@@ -168,7 +168,7 @@
 
     private boolean created = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.net.SocketImplFactory factory;
 
     private java.net.SocketImpl impl;
diff --git a/ojluni/annotations/hiddenapi/java/net/Socket.java b/ojluni/annotations/hiddenapi/java/net/Socket.java
index 495d134..822dd65 100644
--- a/ojluni/annotations/hiddenapi/java/net/Socket.java
+++ b/ojluni/annotations/hiddenapi/java/net/Socket.java
@@ -306,7 +306,7 @@
 
     private boolean created = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.net.SocketImplFactory factory;
 
     @UnsupportedAppUsage
diff --git a/ojluni/annotations/hiddenapi/java/net/URI.java b/ojluni/annotations/hiddenapi/java/net/URI.java
index ec7e242..99ab372 100644
--- a/ojluni/annotations/hiddenapi/java/net/URI.java
+++ b/ojluni/annotations/hiddenapi/java/net/URI.java
@@ -666,7 +666,7 @@
     @UnsupportedAppUsage
     private transient int port = -1; // 0xffffffff
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private transient java.lang.String query;
 
     private transient java.lang.String scheme;
diff --git a/ojluni/annotations/hiddenapi/java/net/URL.java b/ojluni/annotations/hiddenapi/java/net/URL.java
index 9ba6358..7f3857f 100644
--- a/ojluni/annotations/hiddenapi/java/net/URL.java
+++ b/ojluni/annotations/hiddenapi/java/net/URL.java
@@ -257,7 +257,7 @@
 
     private int port = -1; // 0xffffffff
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.lang.String protocol;
 
     private static final java.lang.String protocolPathProp = "java.protocol.handler.pkgs";
diff --git a/ojluni/annotations/hiddenapi/java/nio/Buffer.java b/ojluni/annotations/hiddenapi/java/nio/Buffer.java
index fa8b31b..e135277 100644
--- a/ojluni/annotations/hiddenapi/java/nio/Buffer.java
+++ b/ojluni/annotations/hiddenapi/java/nio/Buffer.java
@@ -149,7 +149,7 @@
     @UnsupportedAppUsage
     long address;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int capacity;
 
     @UnsupportedAppUsage
diff --git a/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java b/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java
index 32f53a4..bd5718d 100644
--- a/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java
+++ b/ojluni/annotations/hiddenapi/java/nio/ByteBuffer.java
@@ -264,19 +264,19 @@
 
     boolean bigEndian = true;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     final byte[] hb;
 
     {
         hb = new byte[0];
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     boolean isReadOnly;
 
     boolean nativeByteOrder;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     final int offset;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java b/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java
index b447bb6..f6c3342 100644
--- a/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java
+++ b/ojluni/annotations/hiddenapi/java/nio/CharBuffer.java
@@ -155,7 +155,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     abstract java.lang.String toString(int start, int end);
 
     public final int length() {
diff --git a/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java b/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java
index b6ca5fb..deef630 100644
--- a/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java
+++ b/ojluni/annotations/hiddenapi/java/nio/DirectByteBuffer.java
@@ -36,7 +36,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private DirectByteBuffer(long addr, int cap) {
         super(0, 0, 0, 0);
         throw new RuntimeException("Stub!");
diff --git a/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java b/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java
index fb86662..d81556d 100644
--- a/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java
+++ b/ojluni/annotations/hiddenapi/java/nio/charset/Charset.java
@@ -167,7 +167,7 @@
         cache2 = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.nio.charset.Charset defaultCharset;
 
     private static java.lang.ThreadLocal<java.lang.ThreadLocal<?>> gate;
diff --git a/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java b/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java
index 0e0fd2d..0c986ff 100644
--- a/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java
+++ b/ojluni/annotations/hiddenapi/java/nio/charset/CharsetEncoder.java
@@ -138,7 +138,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean canEncode(java.nio.CharBuffer cb) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java b/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java
index 0f9ae1e..13a06a7 100644
--- a/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java
+++ b/ojluni/annotations/hiddenapi/java/nio/file/FileTreeWalker.java
@@ -72,20 +72,20 @@
 
     private boolean closed;
 
-    @android.compat.annotation.UnsupportedAppUsage private final boolean followLinks;
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) private final boolean followLinks;
 
     {
         followLinks = false;
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.nio.file.LinkOption[] linkOptions;
 
     {
         linkOptions = new java.nio.file.LinkOption[0];
     }
 
-    @android.compat.annotation.UnsupportedAppUsage private final int maxDepth;
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) private final int maxDepth;
 
     {
         maxDepth = 0;
diff --git a/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java b/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java
index e5ceb2a..268a5a2 100644
--- a/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java
+++ b/ojluni/annotations/hiddenapi/java/security/KeyPairGenerator.java
@@ -38,7 +38,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.security.KeyPairGenerator getInstance(
             sun.security.jca.GetInstance.Instance instance, java.lang.String algorithm) {
         throw new RuntimeException("Stub!");
diff --git a/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java b/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java
index 1b0a68c..e6945a3 100644
--- a/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java
+++ b/ojluni/annotations/hiddenapi/java/text/DecimalFormatSymbols.java
@@ -100,7 +100,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.lang.String getPercentString() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/text/NumberFormat.java b/ojluni/annotations/hiddenapi/java/text/NumberFormat.java
index 232c94f..7aaf4c1 100644
--- a/ojluni/annotations/hiddenapi/java/text/NumberFormat.java
+++ b/ojluni/annotations/hiddenapi/java/text/NumberFormat.java
@@ -201,7 +201,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static java.text.NumberFormat getInstance(java.util.Locale desiredLocale, int choice) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/time/Duration.java b/ojluni/annotations/hiddenapi/java/time/Duration.java
index ca99832..6f4332b 100644
--- a/ojluni/annotations/hiddenapi/java/time/Duration.java
+++ b/ojluni/annotations/hiddenapi/java/time/Duration.java
@@ -254,7 +254,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 172313849)
     private java.math.BigDecimal toSeconds() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java b/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java
index d4822c4..adb1f64 100644
--- a/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java
+++ b/ojluni/annotations/hiddenapi/java/time/OffsetDateTime.java
@@ -71,7 +71,7 @@
                 java.lang.Comparable<java.time.OffsetDateTime>,
                 java.io.Serializable {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private OffsetDateTime(java.time.LocalDateTime dateTime, java.time.ZoneOffset offset) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/time/ZoneId.java b/ojluni/annotations/hiddenapi/java/time/ZoneId.java
index ef4a7aa..8854125 100644
--- a/ojluni/annotations/hiddenapi/java/time/ZoneId.java
+++ b/ojluni/annotations/hiddenapi/java/time/ZoneId.java
@@ -92,7 +92,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     static java.time.ZoneId of(java.lang.String zoneId, boolean checkAvailable) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/util/ArrayList.java b/ojluni/annotations/hiddenapi/java/util/ArrayList.java
index 3d90fa5..1d7691f 100644
--- a/ojluni/annotations/hiddenapi/java/util/ArrayList.java
+++ b/ojluni/annotations/hiddenapi/java/util/ArrayList.java
@@ -404,7 +404,7 @@
             throw new RuntimeException("Stub!");
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         private final int offset;
 
         {
diff --git a/ojluni/annotations/hiddenapi/java/util/HashMap.java b/ojluni/annotations/hiddenapi/java/util/HashMap.java
index b13c25c..e72432b 100644
--- a/ojluni/annotations/hiddenapi/java/util/HashMap.java
+++ b/ojluni/annotations/hiddenapi/java/util/HashMap.java
@@ -531,17 +531,17 @@
             hash = 0;
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         final K key;
 
         {
             key = null;
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         java.util.HashMap.Node<K, V> next;
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         V value;
     }
 
diff --git a/ojluni/annotations/hiddenapi/java/util/HashSet.java b/ojluni/annotations/hiddenapi/java/util/HashSet.java
index 896c1aa..3fd999d 100644
--- a/ojluni/annotations/hiddenapi/java/util/HashSet.java
+++ b/ojluni/annotations/hiddenapi/java/util/HashSet.java
@@ -47,7 +47,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
+    HashSet(int initialCapacity, float loadFactor, boolean fake) {
         throw new RuntimeException("Stub!");
     }
 
diff --git a/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java b/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java
index 99d649b..3fec006 100644
--- a/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java
+++ b/ojluni/annotations/hiddenapi/java/util/LinkedHashMap.java
@@ -145,7 +145,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     final boolean accessOrder;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/util/Random.java b/ojluni/annotations/hiddenapi/java/util/Random.java
index 930688a..cc1b70f 100644
--- a/ojluni/annotations/hiddenapi/java/util/Random.java
+++ b/ojluni/annotations/hiddenapi/java/util/Random.java
@@ -38,7 +38,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(trackingBug = 172313849)
     private static long seedUniquifier() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/util/UUID.java b/ojluni/annotations/hiddenapi/java/util/UUID.java
index 353f2b6..06bd0db 100644
--- a/ojluni/annotations/hiddenapi/java/util/UUID.java
+++ b/ojluni/annotations/hiddenapi/java/util/UUID.java
@@ -98,14 +98,14 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final long leastSigBits;
 
     {
         leastSigBits = 0;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final long mostSigBits;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/util/Vector.java b/ojluni/annotations/hiddenapi/java/util/Vector.java
index 91a6aa7..bf0f326 100644
--- a/ojluni/annotations/hiddenapi/java/util/Vector.java
+++ b/ojluni/annotations/hiddenapi/java/util/Vector.java
@@ -162,7 +162,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     E elementData(int index) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java b/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java
index 0d27711..50003b4 100644
--- a/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java
+++ b/ojluni/annotations/hiddenapi/java/util/concurrent/ThreadPoolExecutor.java
@@ -334,7 +334,7 @@
 
     private static final int TIDYING = 1073741824; // 0x40000000
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private volatile boolean allowCoreThreadTimeOut;
 
     private long completedTaskCount;
@@ -348,7 +348,7 @@
         ctl = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private static final java.util.concurrent.RejectedExecutionHandler defaultHandler;
 
     static {
@@ -361,7 +361,7 @@
 
     private int largestPoolSize;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private final java.util.concurrent.locks.ReentrantLock mainLock;
 
     {
diff --git a/ojluni/annotations/hiddenapi/java/util/logging/Handler.java b/ojluni/annotations/hiddenapi/java/util/logging/Handler.java
index 7243f48..fd1344c 100644
--- a/ojluni/annotations/hiddenapi/java/util/logging/Handler.java
+++ b/ojluni/annotations/hiddenapi/java/util/logging/Handler.java
@@ -118,6 +118,6 @@
         offValue = 0;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     boolean sealed = true;
 }
diff --git a/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java b/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java
index 8900a5a..ae16209 100644
--- a/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java
+++ b/ojluni/annotations/hiddenapi/java/util/logging/LogManager.java
@@ -173,7 +173,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     java.util.logging.Formatter getFormatterProperty(
             java.lang.String name, java.util.logging.Formatter defaultValue) {
         throw new RuntimeException("Stub!");
diff --git a/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java b/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java
index 686f1bd..4600ff0 100644
--- a/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java
+++ b/ojluni/annotations/hiddenapi/java/util/regex/Matcher.java
@@ -232,7 +232,7 @@
 
     boolean anchoringBounds = true;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     int appendPos = 0; // 0x0
 
     int from;
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java b/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java
index 0dbe2a5..aa27720 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/Deflater.java
@@ -160,17 +160,17 @@
 
     public static final int SYNC_FLUSH = 2; // 0x2
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private byte[] buf;
 
     private long bytesRead;
 
     private long bytesWritten;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean finish;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean finished;
 
     private final dalvik.system.CloseGuard guard;
@@ -179,19 +179,19 @@
         guard = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int len;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int level;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int off;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean setParams;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int strategy;
 
     private final java.util.zip.ZStreamRef zsRef;
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java b/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java
index e5a5dcc..5b770b8 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/Inflater.java
@@ -132,7 +132,7 @@
 
     private static native void end(long addr);
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private byte[] buf;
 
     private long bytesRead;
@@ -145,7 +145,7 @@
         defaultBuf = new byte[0];
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean finished;
 
     private final dalvik.system.CloseGuard guard;
@@ -154,13 +154,13 @@
         guard = null;
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int len;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean needDict;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int off;
 
     private final java.util.zip.ZStreamRef zsRef;
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java
index 91440c2..2b9936d 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipEntry.java
@@ -31,7 +31,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class ZipEntry implements java.util.zip.ZipConstants, java.lang.Cloneable {
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public ZipEntry(
             java.lang.String name,
             java.lang.String comment,
@@ -189,7 +189,7 @@
 
     int flag = 0; // 0x0
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     int method = -1; // 0xffffffff
 
     java.nio.file.attribute.FileTime mtime;
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java
index b2c72a7..02fd000 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipFile.java
@@ -192,7 +192,7 @@
 
     private java.util.Deque<java.util.zip.Inflater> inflaterCache;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private long jzfile;
 
     private final boolean locsig;
@@ -244,7 +244,7 @@
             throw new RuntimeException("Stub!");
         }
 
-        @UnsupportedAppUsage
+        @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public java.util.zip.ZipEntry nextElement() {
             throw new RuntimeException("Stub!");
         }
diff --git a/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java b/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java
index 18c1b2e..14a0a66 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipInputStream.java
@@ -100,12 +100,12 @@
 
     private boolean entryEOF = false;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int flag;
 
     private long remaining;
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     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
index fd4276a..a733cda 100644
--- a/ojluni/annotations/hiddenapi/java/util/zip/ZipOutputStream.java
+++ b/ojluni/annotations/hiddenapi/java/util/zip/ZipOutputStream.java
@@ -144,10 +144,10 @@
 
     private long locoff = 0; // 0x0
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private int method = 8; // 0x8
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private java.util.HashSet<java.lang.String> names;
 
     @UnsupportedAppUsage
diff --git a/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java b/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java
index cdbc658..be9bc498 100644
--- a/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java
+++ b/ojluni/annotations/hiddenapi/sun/misc/Cleaner.java
@@ -53,10 +53,10 @@
         throw new RuntimeException("Stub!");
     }
 
-    private static final java.lang.ref.ReferenceQueue<java.lang.Object> dummyQueue;
+    private static final java.lang.ref.ReferenceQueue<java.lang.Object> fakeQueue;
 
     static {
-        dummyQueue = null;
+        fakeQueue = null;
     }
 
     private static sun.misc.Cleaner first;
diff --git a/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java b/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java
index c6dad00..63d7a33 100644
--- a/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java
+++ b/ojluni/annotations/hiddenapi/sun/misc/Unsafe.java
@@ -230,33 +230,33 @@
     @UnsupportedAppUsage
     public native void putDouble(long address, double x);
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public native void copyMemoryToPrimitiveArray(
             long srcAddr, java.lang.Object dst, long dstOffset, long bytes);
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     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
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public int getAndAddInt(java.lang.Object o, long offset, int delta) {
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public long getAndAddLong(java.lang.Object o, long offset, long delta) {
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public int getAndSetInt(java.lang.Object o, long offset, int newValue) {
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public long getAndSetLong(java.lang.Object o, long offset, long newValue) {
         throw new RuntimeException("Stub!");
     }
@@ -276,7 +276,7 @@
     @UnsupportedAppUsage
     public native void fullFence();
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final int INVALID_FIELD_OFFSET = -1; // 0xffffffff
 
     @UnsupportedAppUsage private static final sun.misc.Unsafe THE_ONE;
diff --git a/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java b/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java
index 0134b09..4ff149a 100644
--- a/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java
+++ b/ojluni/annotations/hiddenapi/sun/net/util/IPAddressUtil.java
@@ -40,12 +40,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static boolean isIPv4LiteralAddress(java.lang.String src) {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static boolean isIPv6LiteralAddress(java.lang.String src) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java b/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java
index 12b1d72..eeb25f4 100644
--- a/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java
+++ b/ojluni/annotations/hiddenapi/sun/net/www/URLConnection.java
@@ -28,7 +28,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public abstract class URLConnection extends java.net.URLConnection {
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public URLConnection(java.net.URL u) {
         super(null);
         throw new RuntimeException("Stub!");
@@ -38,7 +38,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public void setProperties(sun.net.www.MessageHeader properties) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java b/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java
index 3d6c0e8..ef8b1a4 100644
--- a/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java
+++ b/ojluni/annotations/hiddenapi/sun/nio/fs/BasicFileAttributesHolder.java
@@ -28,7 +28,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public interface BasicFileAttributesHolder {
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.nio.file.attribute.BasicFileAttributes get();
 
     public void invalidate();
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java b/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java
index 92756f9..ef3d1a6 100644
--- a/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/GetInstance.java
@@ -75,7 +75,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static sun.security.jca.GetInstance.Instance getInstance(
             java.lang.String type,
             java.lang.Class<?> clazz,
@@ -94,7 +94,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static sun.security.jca.GetInstance.Instance getInstance(
             java.lang.String type,
             java.lang.Class<?> clazz,
@@ -114,7 +114,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static sun.security.jca.GetInstance.Instance getInstance(
             java.lang.String type,
             java.lang.Class<?> clazz,
@@ -156,13 +156,13 @@
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage public final java.lang.Object impl;
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) public final java.lang.Object impl;
 
         {
             impl = null;
         }
 
-        @android.compat.annotation.UnsupportedAppUsage public final java.security.Provider provider;
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) 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
index ca703f2..ab1acb6 100644
--- a/ojluni/annotations/hiddenapi/sun/security/jca/JCAUtil.java
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/JCAUtil.java
@@ -39,7 +39,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static java.security.SecureRandom getSecureRandom() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java
index f6abd8b..f6a49a1 100644
--- a/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/ProviderConfig.java
@@ -47,7 +47,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private boolean hasArgument() {
         throw new RuntimeException("Stub!");
     }
@@ -56,7 +56,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private void disableLoad() {
         throw new RuntimeException("Stub!");
     }
@@ -94,7 +94,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage private static final java.lang.Class[] CL_STRING;
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) private static final java.lang.Class[] CL_STRING;
 
     static {
         CL_STRING = new java.lang.Class[0];
@@ -107,7 +107,7 @@
 
     private static final java.lang.String P11_SOL_NAME = "sun.security.pkcs11.SunPKCS11";
 
-    @android.compat.annotation.UnsupportedAppUsage private final java.lang.String argument;
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) private final java.lang.String argument;
 
     {
         argument = null;
diff --git a/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java b/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java
index 4e116fc..440afbf 100644
--- a/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java
+++ b/ojluni/annotations/hiddenapi/sun/security/jca/Providers.java
@@ -38,12 +38,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static java.lang.Object startJarVerification() {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static void stopJarVerification(java.lang.Object obj) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java
index a5e9019..c4dd15b 100644
--- a/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/PKCS9Attributes.java
@@ -75,7 +75,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.security.pkcs.PKCS9Attribute getAttribute(java.lang.String name) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java b/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java
index 162b420..cecae94 100644
--- a/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/annotations/hiddenapi/sun/security/pkcs/SignerInfo.java
@@ -129,7 +129,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public byte[] getEncryptedDigest() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java b/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java
index 1c2d115..19ebc55 100644
--- a/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java
+++ b/ojluni/annotations/hiddenapi/sun/security/timestamp/TimestampToken.java
@@ -33,7 +33,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.util.Date getDate() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/Cache.java b/ojluni/annotations/hiddenapi/sun/security/util/Cache.java
index 1520e12..9df085e 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/Cache.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/Cache.java
@@ -63,7 +63,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static <K, V> sun.security.util.Cache<K, V> newHardMemoryCache(int size) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java b/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java
index fefcd08..f021927 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerInputStream.java
@@ -148,7 +148,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.lang.String getUTF8String() throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java b/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java
index 772018d..507625d 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerOutputStream.java
@@ -30,7 +30,7 @@
 public class DerOutputStream extends java.io.ByteArrayOutputStream
         implements sun.security.util.DerEncoder {
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public DerOutputStream(int size) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java b/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java
index 42825d3..77d37c4 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/DerValue.java
@@ -146,7 +146,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.math.BigInteger getPositiveBigInteger() throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java b/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java
index b8d89f8..d62d9b3 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/ManifestDigester.java
@@ -76,7 +76,7 @@
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public byte[] digestWorkaround(java.security.MessageDigest md) {
             throw new RuntimeException("Stub!");
         }
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java b/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java
index 9a86630..91faf10 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/PropertyExpander.java
@@ -33,7 +33,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static java.lang.String expand(java.lang.String value)
             throws sun.security.util.PropertyExpander.ExpandException {
         throw new RuntimeException("Stub!");
diff --git a/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java b/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java
index 0a66cae..9e63fdd 100644
--- a/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java
+++ b/ojluni/annotations/hiddenapi/sun/security/util/ResourcesMgr.java
@@ -32,7 +32,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static java.lang.String getString(java.lang.String s) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java b/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java
index 7948de8..215bc7a 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/AlgorithmId.java
@@ -67,7 +67,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @UnsupportedAppUsage
+    @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public final byte[] encode() throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java
index 40eb1b8..249c353 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CRLNumberExtension.java
@@ -74,7 +74,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.math.BigInteger get(java.lang.String name) throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java
index da41fbd..6b7eedb 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/CertificateExtensions.java
@@ -66,7 +66,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.security.x509.Extension get(java.lang.String name) throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java
index cd2ff3e..3c15a4c 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/KeyUsageExtension.java
@@ -69,7 +69,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.lang.Boolean get(java.lang.String name) throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java
index 2db2b55..0460d8b 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/NetscapeCertTypeExtension.java
@@ -70,7 +70,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public java.lang.Boolean get(java.lang.String name) throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java
index 9b1ed0b..dea94a4 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/SubjectAlternativeNameExtension.java
@@ -67,7 +67,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.security.x509.GeneralNames get(java.lang.String name) throws java.io.IOException {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java b/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java
index fd8e9b6..bdc7ce7 100644
--- a/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java
+++ b/ojluni/annotations/hiddenapi/sun/security/x509/X500Name.java
@@ -45,7 +45,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public X500Name(
             java.lang.String commonName,
             java.lang.String organizationUnit,
@@ -55,7 +55,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public X500Name(
             java.lang.String commonName,
             java.lang.String organizationUnit,
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java
index 3e1be5e..8bea9b5 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/AbstractCalendar.java
@@ -37,7 +37,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.Era[] getEras() {
         throw new RuntimeException("Stub!");
     }
@@ -75,7 +75,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public long getTimeOfDayValue(sun.util.calendar.CalendarDate date) {
         throw new RuntimeException("Stub!");
     }
@@ -104,7 +104,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static long getDayOfWeekDateOnOrBefore(long fixedDate, int dayOfWeek) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java
index 660ba87..dc410b6 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/BaseCalendar.java
@@ -185,10 +185,10 @@
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public abstract int getNormalizedYear();
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public abstract void setNormalizedYear(int normalizedYear);
 
         protected final boolean hit(int year) {
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java
index 165920c..fdeeb5b 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarDate.java
@@ -84,7 +84,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setDayOfMonth(int date) {
         throw new RuntimeException("Stub!");
     }
@@ -101,7 +101,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setHours(int hours) {
         throw new RuntimeException("Stub!");
     }
@@ -114,7 +114,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setMinutes(int minutes) {
         throw new RuntimeException("Stub!");
     }
@@ -127,7 +127,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setSeconds(int seconds) {
         throw new RuntimeException("Stub!");
     }
@@ -140,7 +140,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setMillis(int millis) {
         throw new RuntimeException("Stub!");
     }
@@ -149,12 +149,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public long getTimeOfDay() {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.CalendarDate setDate(int year, int month, int dayOfMonth) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java
index c847641..e658a34 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarSystem.java
@@ -34,7 +34,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static sun.util.calendar.Gregorian getGregorianCalendar() {
         throw new RuntimeException("Stub!");
     }
@@ -62,10 +62,10 @@
 
     public abstract sun.util.calendar.CalendarDate newCalendarDate();
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public abstract sun.util.calendar.CalendarDate newCalendarDate(java.util.TimeZone zone);
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public abstract long getTime(sun.util.calendar.CalendarDate date);
 
     public abstract int getYearLength(sun.util.calendar.CalendarDate date);
@@ -88,7 +88,7 @@
     public abstract sun.util.calendar.CalendarDate setTimeOfDay(
             sun.util.calendar.CalendarDate date, int timeOfDay);
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public abstract boolean validate(sun.util.calendar.CalendarDate date);
 
     public abstract boolean normalize(sun.util.calendar.CalendarDate date);
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java
index 2a05603..f2908a5 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/CalendarUtils.java
@@ -40,12 +40,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final long floorDivide(long n, long d) {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final int floorDivide(int n, int d) {
         throw new RuntimeException("Stub!");
     }
@@ -58,12 +58,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final long mod(long x, long y) {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public static final int mod(int x, int y) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java b/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java
index 49aa034..f865e59 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/Era.java
@@ -28,7 +28,7 @@
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Era {
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public Era(java.lang.String name, java.lang.String abbr, long since, boolean localTime) {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java b/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java
index aa92656..4aff983 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/ImmutableGregorianDate.java
@@ -242,7 +242,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     private void unsupported() {
         throw new RuntimeException("Stub!");
     }
diff --git a/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java b/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java
index b1320c5..edbcf2a 100644
--- a/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java
+++ b/ojluni/annotations/hiddenapi/sun/util/calendar/LocalGregorianCalendar.java
@@ -68,12 +68,12 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public sun.util.calendar.LocalGregorianCalendar.Date newCalendarDate(java.util.TimeZone zone) {
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public boolean validate(sun.util.calendar.CalendarDate date) {
         throw new RuntimeException("Stub!");
     }
@@ -82,7 +82,7 @@
         throw new RuntimeException("Stub!");
     }
 
-    @android.compat.annotation.UnsupportedAppUsage
+    @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
     public boolean normalize(sun.util.calendar.CalendarDate date) {
         throw new RuntimeException("Stub!");
     }
@@ -122,7 +122,7 @@
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public sun.util.calendar.LocalGregorianCalendar.Date setEra(sun.util.calendar.Era era) {
             throw new RuntimeException("Stub!");
         }
@@ -131,17 +131,17 @@
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public sun.util.calendar.LocalGregorianCalendar.Date setYear(int localYear) {
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public int getNormalizedYear() {
             throw new RuntimeException("Stub!");
         }
 
-        @android.compat.annotation.UnsupportedAppUsage
+        @android.compat.annotation.UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
         public void setNormalizedYear(int normalizedYear) {
             throw new RuntimeException("Stub!");
         }
diff --git a/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java b/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java
index 89006c1..915d410 100644
--- a/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java
+++ b/ojluni/annotations/mmodule/java/io/FileDescriptor.annotated.java
@@ -36,10 +36,10 @@
 
 public native void sync() throws java.io.SyncFailedException;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public int getInt$() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public void setInt$(int fd) { throw new RuntimeException("Stub!"); }
 
 public long getOwnerId$() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java b/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java
index 11013ac..8978137 100644
--- a/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java
+++ b/ojluni/annotations/mmodule/java/io/FileInputStream.annotated.java
@@ -38,7 +38,7 @@
 
 public FileInputStream(java.io.FileDescriptor fdObj) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public FileInputStream(java.io.FileDescriptor fdObj, boolean isFdOwner) { throw new RuntimeException("Stub!"); }
 
 public int read() throws java.io.IOException { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/java/lang/Class.annotated.java b/ojluni/annotations/mmodule/java/lang/Class.annotated.java
index fd80abb..41411bf 100644
--- a/ojluni/annotations/mmodule/java/lang/Class.annotated.java
+++ b/ojluni/annotations/mmodule/java/lang/Class.annotated.java
@@ -83,7 +83,6 @@
 
 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!"); }
@@ -134,12 +133,10 @@
 
 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!"); }
diff --git a/ojluni/annotations/mmodule/java/lang/System.annotated.java b/ojluni/annotations/mmodule/java/lang/System.annotated.java
index 918b3da..43286e5 100644
--- a/ojluni/annotations/mmodule/java/lang/System.annotated.java
+++ b/ojluni/annotations/mmodule/java/lang/System.annotated.java
@@ -102,8 +102,5 @@
 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
index 2499518..7682796 100644
--- a/ojluni/annotations/mmodule/java/lang/Thread.annotated.java
+++ b/ojluni/annotations/mmodule/java/lang/Thread.annotated.java
@@ -141,10 +141,10 @@
 
 public static java.lang.Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static void setUncaughtExceptionPreHandler(UncaughtExceptionHandler eh) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() { throw new RuntimeException("Stub!"); }
 
 public java.lang.Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java b/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java
index b462769..8f7ddf7 100644
--- a/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/DatagramSocket.annotated.java
@@ -103,7 +103,7 @@
 
 public static synchronized void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
index e10debf..b3f6c4c 100644
--- a/ojluni/annotations/mmodule/java/net/Inet4Address.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/Inet4Address.annotated.java
@@ -62,15 +62,15 @@
 
 public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static final java.net.InetAddress ALL;
 static { ALL = null; }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static final java.net.InetAddress ANY;
 static { ANY = null; }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
index 7888710..2a465e5 100644
--- a/ojluni/annotations/mmodule/java/net/Inet6Address.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/Inet6Address.annotated.java
@@ -28,7 +28,6 @@
 package java.net;
 
 
-@libcore.api.CorePlatformApi
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Inet6Address extends java.net.InetAddress {
 
@@ -60,7 +59,6 @@
 
 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!"); }
@@ -73,11 +71,11 @@
 
 public boolean isIPv4CompatibleAddress() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static final java.net.InetAddress ANY;
 static { ANY = null; }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
index 6f4492d..3ec88f4 100644
--- a/ojluni/annotations/mmodule/java/net/InetAddress.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/InetAddress.annotated.java
@@ -87,19 +87,19 @@
 
 public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static boolean isNumeric(java.lang.String address) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static void clearDnsCache() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static java.net.InetAddress getByNameOnNet(java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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/Socket.annotated.java b/ojluni/annotations/mmodule/java/net/Socket.annotated.java
index e021788..2123660 100644
--- a/ojluni/annotations/mmodule/java/net/Socket.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/Socket.annotated.java
@@ -139,7 +139,7 @@
 
 public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @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
index 2146d2f..46c201f 100644
--- a/ojluni/annotations/mmodule/java/net/SocketImpl.annotated.java
+++ b/ojluni/annotations/mmodule/java/net/SocketImpl.annotated.java
@@ -62,7 +62,7 @@
 
 protected java.io.FileDescriptor getFileDescriptor() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public java.io.FileDescriptor getFD$() { throw new RuntimeException("Stub!"); }
 
 protected java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java b/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java
index d0caba2..c2d01c5 100644
--- a/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java
+++ b/ojluni/annotations/mmodule/java/nio/ByteBuffer.annotated.java
@@ -151,7 +151,7 @@
 
 public boolean isAccessible() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
index 51e0e9c..6612539 100644
--- a/ojluni/annotations/mmodule/java/nio/DirectByteBuffer.annotated.java
+++ b/ojluni/annotations/mmodule/java/nio/DirectByteBuffer.annotated.java
@@ -28,11 +28,11 @@
 package java.nio;
 
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class DirectByteBuffer extends java.nio.MappedByteBuffer implements sun.nio.ch.DirectBuffer {
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
@@ -45,7 +45,7 @@
 
 public final java.nio.ByteBuffer asReadOnlyBuffer() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final long address() { throw new RuntimeException("Stub!"); }
 
 public final byte get() { throw new RuntimeException("Stub!"); }
@@ -130,6 +130,7 @@
 
 public final boolean isAccessible() { throw new RuntimeException("Stub!"); }
 
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public final void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
 }
 
diff --git a/ojluni/annotations/mmodule/java/nio/charset/CharsetDecoder.annotated.java b/ojluni/annotations/mmodule/java/nio/charset/CharsetDecoder.annotated.java
deleted file mode 100644
index ed0f378..0000000
--- a/ojluni/annotations/mmodule/java/nio/charset/CharsetDecoder.annotated.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 java.nio.CharBuffer;
-import java.nio.ByteBuffer;
-import java.nio.Buffer;
-import java.nio.charset.CoderMalfunctionError;
-
-@SuppressWarnings({"unchecked", "deprecation", "all"})
-public abstract class CharsetDecoder {
-
-@libcore.api.IntraCoreApi
-protected CharsetDecoder(java.nio.charset.Charset cs, float averageCharsPerByte, float maxCharsPerByte) { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); }
-
-public final java.lang.String replacement() { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.CharsetDecoder replaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
-
-protected void implReplaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
-
-public java.nio.charset.CodingErrorAction malformedInputAction() { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.CharsetDecoder 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.CharsetDecoder 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 averageCharsPerByte() { throw new RuntimeException("Stub!"); }
-
-public final float maxCharsPerByte() { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.CoderResult decode(java.nio.ByteBuffer in, java.nio.CharBuffer out, boolean endOfInput) { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.CoderResult flush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
-
-protected java.nio.charset.CoderResult implFlush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
-
-public final java.nio.charset.CharsetDecoder reset() { throw new RuntimeException("Stub!"); }
-
-protected void implReset() { throw new RuntimeException("Stub!"); }
-
-protected abstract java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer in, java.nio.CharBuffer out);
-
-public final java.nio.CharBuffer decode(java.nio.ByteBuffer in) throws java.nio.charset.CharacterCodingException { throw new RuntimeException("Stub!"); }
-
-public boolean isAutoDetecting() { throw new RuntimeException("Stub!"); }
-
-public boolean isCharsetDetected() { throw new RuntimeException("Stub!"); }
-
-public java.nio.charset.Charset detectedCharset() { throw new RuntimeException("Stub!"); }
-}
-
diff --git a/ojluni/annotations/mmodule/java/security/Provider.annotated.java b/ojluni/annotations/mmodule/java/security/Provider.annotated.java
index 2fce78b..1d6652a 100644
--- a/ojluni/annotations/mmodule/java/security/Provider.annotated.java
+++ b/ojluni/annotations/mmodule/java/security/Provider.annotated.java
@@ -106,7 +106,7 @@
 
 public boolean isRegistered() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public synchronized void warmUpServiceProvision() { throw new RuntimeException("Stub!"); }
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public static class Service {
diff --git a/ojluni/annotations/mmodule/java/security/Signature.annotated.java b/ojluni/annotations/mmodule/java/security/Signature.annotated.java
index 87323e2..4ac3abd 100644
--- a/ojluni/annotations/mmodule/java/security/Signature.annotated.java
+++ b/ojluni/annotations/mmodule/java/security/Signature.annotated.java
@@ -86,7 +86,7 @@
 
 public java.lang.Object clone() throws java.lang.CloneNotSupportedException { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public java.security.SignatureSpi getCurrentSpi() { throw new RuntimeException("Stub!"); }
 
 protected static final int SIGN = 2; // 0x2
diff --git a/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java b/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java
index 5a28d02..6456c83 100644
--- a/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java
+++ b/ojluni/annotations/mmodule/java/text/DateFormat.annotated.java
@@ -83,7 +83,7 @@
 
 public static final java.text.DateFormat getInstance() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static final void set24HourTimePref(java.lang.Boolean is24Hour) { throw new RuntimeException("Stub!"); }
 
 public static java.util.Locale[] getAvailableLocales() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java b/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java
index 9f494b6..0354493 100644
--- a/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java
+++ b/ojluni/annotations/mmodule/java/util/LinkedHashMap.annotated.java
@@ -48,7 +48,7 @@
 
 public void clear() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
diff --git a/ojluni/annotations/mmodule/java/util/Locale.annotated.java b/ojluni/annotations/mmodule/java/util/Locale.annotated.java
deleted file mode 100644
index d8aad03..0000000
--- a/ojluni/annotations/mmodule/java/util/Locale.annotated.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * 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
index 5ac5a83..0015ff1 100644
--- a/ojluni/annotations/mmodule/java/util/concurrent/CompletableFuture.annotated.java
+++ b/ojluni/annotations/mmodule/java/util/concurrent/CompletableFuture.annotated.java
@@ -175,7 +175,6 @@
 
 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!"); }
@@ -184,7 +183,6 @@
 
 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!"); }
diff --git a/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java b/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java
index 66b3616..519cb13 100644
--- a/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java
+++ b/ojluni/annotations/mmodule/java/util/zip/ZipEntry.annotated.java
@@ -38,7 +38,7 @@
 
 public ZipEntry(java.util.zip.ZipEntry e) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public long getDataOffset() { throw new RuntimeException("Stub!"); }
 
 public java.lang.String getName() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/javax/net/ssl/HttpsURLConnection.annotated.java b/ojluni/annotations/mmodule/javax/net/ssl/HttpsURLConnection.annotated.java
new file mode 100644
index 0000000..8379981
--- /dev/null
+++ b/ojluni/annotations/mmodule/javax/net/ssl/HttpsURLConnection.annotated.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1999, 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;
+
+abstract public class HttpsURLConnection extends HttpURLConnection {
+    public abstract java.lang.String getCipherSuite();
+
+    public abstract java.security.cert.Certificate [] getLocalCertificates();
+
+    public abstract java.security.cert.Certificate [] getServerCertificates() throws javax.net.ssl.SSLPeerUnverifiedException;
+
+    public java.security.Principal getPeerPrincipal() throws javax.net.ssl.SSLPeerUnverifiedException { throw new RuntimeException("Stub!"); }
+
+    public java.security.Principal getLocalPrincipal() { throw new RuntimeException("Stub!"); }
+
+    public static void setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier v) { throw new RuntimeException("Stub!"); }
+
+    public static javax.net.ssl.HostnameVerifier getDefaultHostnameVerifier() { throw new RuntimeException("Stub!"); }
+
+    public void setHostnameVerifier(javax.net.ssl.HostnameVerifier v) { throw new RuntimeException("Stub!"); }
+
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public static javax.net.ssl.HostnameVerifier getStrictHostnameVerifier() { throw new RuntimeException("Stub!"); }
+
+    public javax.net.ssl.HostnameVerifier getHostnameVerifier() { throw new RuntimeException("Stub!"); }
+
+    public static void setDefaultSSLSocketFactory(javax.net.ssl.SSLSocketFactory sf) { throw new RuntimeException("Stub!"); }
+
+    public static javax.net.ssl.SSLSocketFactory getDefaultSSLSocketFactory() { throw new RuntimeException("Stub!"); }
+
+    public void setSSLSocketFactory(javax.net.ssl.SSLSocketFactory sf) { throw new RuntimeException("Stub!"); }
+
+    public javax.net.ssl.SSLSocketFactory getSSLSocketFactory() { throw new RuntimeException("Stub!"); }
+}
diff --git a/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java b/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java
index b09384a..3c2531c 100644
--- a/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java
+++ b/ojluni/annotations/mmodule/sun/misc/Cleaner.annotated.java
@@ -28,16 +28,16 @@
 
 import java.lang.ref.*;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @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
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static sun.misc.Cleaner create(java.lang.Object ob, java.lang.Runnable thunk) { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
index a6711e0..9407d1a 100644
--- a/ojluni/annotations/mmodule/sun/misc/Unsafe.annotated.java
+++ b/ojluni/annotations/mmodule/sun/misc/Unsafe.annotated.java
@@ -27,95 +27,103 @@
 
 // sun.misc.Unsafe is part of the Core Platform API as platform uses protobuf and protobuf uses
 // this API for fast structure updates from native code (b/144502743).
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.Hide
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public final class Unsafe {
 
-    private Unsafe() {
-        throw new RuntimeException("Stub!");
-    }
-
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public static sun.misc.Unsafe getUnsafe() {
         throw new RuntimeException("Stub!");
     }
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public int arrayBaseOffset(Class clazz) {
         throw new RuntimeException("Stub!");
     }
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public int arrayIndexScale(Class clazz) {
         throw new RuntimeException("Stub!");
     }
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void copyMemory(long srcAddr, long destAddr, long bytes);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native boolean getBoolean(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native byte getByte(long address);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native byte getByte(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native double getDouble(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native double getDouble(long address);
+
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native float getFloat(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native float getFloat(long address);
+
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native int getInt(long address);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native int getInt(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native long getLong(long address);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native long getLong(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native Object getObject(Object obj, long offset);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public long objectFieldOffset(java.lang.reflect.Field field) {
         throw new RuntimeException("Stub!");
     }
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putBoolean(Object obj, long offset, boolean newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putByte(long address, byte newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putByte(Object obj, long offset, byte newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putDouble(Object obj, long offset, double newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native void putDouble(long address, double newValue);
+
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putFloat(Object obj, long offset, float newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
+    public native void putFloat(long address, float newValue);
+
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putInt(long address, int newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putInt(Object obj, long offset, int newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putLong(long address, long newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putLong(Object obj, long offset, long newValue);
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public native void putObject(Object obj, long offset, Object newValue);
 }
diff --git a/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java b/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java
index ca8716b..03bbc4e 100644
--- a/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/jca/Providers.annotated.java
@@ -31,7 +31,7 @@
 import java.util.Set;
 import java.security.NoSuchAlgorithmException;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.Hide
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class Providers {
@@ -40,11 +40,11 @@
 
 public static java.security.Provider getSunProvider() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static java.lang.Object startJarVerification() { throw new RuntimeException("Stub!"); }
 
 
-  @libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public static void stopJarVerification(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
 
 public static sun.security.jca.ProviderList getProviderList() { throw new RuntimeException("Stub!"); }
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java
index c4a0a21..cc946ba 100644
--- a/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/ContentInfo.annotated.java
@@ -36,7 +36,6 @@
  */
 
 @SuppressWarnings({"unchecked", "deprecation", "all"})
-@libcore.api.CorePlatformApi
 @libcore.api.Hide
 public class ContentInfo {
 
@@ -80,7 +79,6 @@
  * 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!"); }
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java
index 2d5cb84..c6bc489 100644
--- a/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/PKCS7.annotated.java
@@ -34,17 +34,17 @@
 import sun.security.x509.AlgorithmId;
 import sun.security.x509.X500Name;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.Hide
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class PKCS7 {
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
@@ -57,10 +57,10 @@
 
 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
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
@@ -69,15 +69,14 @@
 
 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
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public java.security.cert.X509Certificate[] getCertificates() { throw new RuntimeException("Stub!"); }
 
 public java.security.cert.X509CRL[] getCRLs() { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java
index ab44b06..854f394 100644
--- a/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/ParsingException.annotated.java
@@ -33,7 +33,7 @@
 package sun.security.pkcs;
 
 @libcore.api.Hide
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class ParsingException extends java.io.IOException {
 
diff --git a/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java b/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java
index b929e2e..787b295 100644
--- a/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/pkcs/SignerInfo.annotated.java
@@ -30,12 +30,12 @@
 import sun.security.util.DerEncoder;
 import java.io.IOException;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.Hide
 @SuppressWarnings({"unchecked", "deprecation", "all"})
 public class SignerInfo implements sun.security.util.DerEncoder {
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
@@ -52,7 +52,7 @@
 
 public java.security.cert.X509Certificate getCertificate(sun.security.pkcs.PKCS7 block) throws java.io.IOException { throw new RuntimeException("Stub!"); }
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 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!"); }
diff --git a/ojluni/annotations/mmodule/java/sun/security/util/DerEncoder.annotated.java b/ojluni/annotations/mmodule/sun/security/util/DerEncoder.annotated.java
similarity index 100%
rename from ojluni/annotations/mmodule/java/sun/security/util/DerEncoder.annotated.java
rename to ojluni/annotations/mmodule/sun/security/util/DerEncoder.annotated.java
diff --git a/ojluni/annotations/mmodule/java/sun/security/util/ObjectIdentifier.annotated.java b/ojluni/annotations/mmodule/sun/security/util/ObjectIdentifier.annotated.java
similarity index 100%
rename from ojluni/annotations/mmodule/java/sun/security/util/ObjectIdentifier.annotated.java
rename to ojluni/annotations/mmodule/sun/security/util/ObjectIdentifier.annotated.java
diff --git a/ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java b/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
similarity index 88%
rename from ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java
rename to ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
index dc2baf6..1fc8d82 100644
--- a/ojluni/annotations/mmodule/java/sun/security/x509/AlgorithmId.annotated.java
+++ b/ojluni/annotations/mmodule/sun/security/x509/AlgorithmId.annotated.java
@@ -31,17 +31,17 @@
 import sun.security.util.DerEncoder;
 import sun.security.util.ObjectIdentifier;
 
-@libcore.api.CorePlatformApi
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 @libcore.api.IntraCoreApi
 @libcore.api.Hide
 public class AlgorithmId implements Serializable, DerEncoder {
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public AlgorithmId(ObjectIdentifier oid) {
         throw new RuntimeException("Stub!");
     }
 
-    @libcore.api.CorePlatformApi
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     @libcore.api.IntraCoreApi
     public String getName() {
         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
deleted file mode 100644
index eaec071..0000000
--- a/ojluni/annotations/mmodule/sun/util/locale/LanguageTag.annotated.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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/lang/Class.annotated.java b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
index cb99f54..ab0cc39 100644
--- a/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
+++ b/ojluni/annotations/sdk/nullability/java/lang/Class.annotated.java
@@ -81,6 +81,8 @@
 
 @libcore.util.Nullable public java.lang.Package getPackage() { throw new RuntimeException("Stub!"); }
 
+@libcore.util.NonNull public java.lang.String getPackageName() { 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!"); }
diff --git a/ojluni/annotations/sdk/nullability/java/net/InetAddress.annotated.java b/ojluni/annotations/sdk/nullability/java/net/InetAddress.annotated.java
new file mode 100644
index 0000000..967ea83
--- /dev/null
+++ b/ojluni/annotations/sdk/nullability/java/net/InetAddress.annotated.java
@@ -0,0 +1,89 @@
+/*
+ * 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;
+
+@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(@libcore.util.Nullable java.net.NetworkInterface netif, int ttl, int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getHostName() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public java.lang.String getCanonicalHostName() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.Nullable public java.lang.String getHostAddress() { 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.String toString() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getByAddress(@libcore.util.Nullable java.lang.String host, byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getByName(@libcore.util.Nullable java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress[] getAllByName(@libcore.util.Nullable java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getByAddress(byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress getByNameOnNet(@libcore.util.Nullable java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static java.net.InetAddress[] getAllByNameOnNet(@libcore.util.Nullable java.lang.String host, int netId) throws java.net.UnknownHostException { 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
index 2ef4a6f..9583d18 100644
--- a/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
+++ b/ojluni/annotations/sdk/nullability/java/util/List.annotated.java
@@ -111,4 +111,6 @@
 
 @java.lang.SafeVarargs
 @libcore.util.NonNull public static <E> java.util.List<@libcore.util.NonNull E> of(E @libcore.util.NonNull ... elements) { throw new RuntimeException("Stub!"); }
-}
+
+@libcore.util.NonNull public static <E> java.util.List<@libcore.util.NonNull E> copyOf(@libcore.util.NonNull java.util.Collection<? extends E> coll) { throw new RuntimeException("Stub!"); }
+}
\ No newline at end of file
diff --git a/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
index c19add2..dafddd9 100644
--- a/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
+++ b/ojluni/annotations/sdk/nullability/java/util/Map.annotated.java
@@ -129,4 +129,6 @@
 @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!"); }
 }
 
+@libcore.util.NonNull public static <K, V> java.util.Map<K, V> copyOf(@libcore.util.NonNull java.util.Map<? extends K, ? extends V> map);
+
 }
diff --git a/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
index bae8bdd..6f88740 100644
--- a/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
+++ b/ojluni/annotations/sdk/nullability/java/util/Set.annotated.java
@@ -87,4 +87,6 @@
 
 @java.lang.SafeVarargs
 @libcore.util.NonNull public static <E> java.util.Set<@libcore.util.NonNull E> of(E @libcore.util.NonNull ... elements) { throw new RuntimeException("Stub!"); }
+
+@libcore.util.NonNull public static <E> java.util.Set<E> copyOf(@libcore.util.NonNull java.util.Collection<? extends E> coll)  { throw new RuntimeException("Stub!"); }
 }
diff --git a/ojluni/src/main/java/java/awt/font/TEST_MAPPING b/ojluni/src/main/java/java/awt/font/TEST_MAPPING
index a23d298..8bc46cc 100644
--- a/ojluni/src/main/java/java/awt/font/TEST_MAPPING
+++ b/ojluni/src/main/java/java/awt/font/TEST_MAPPING
@@ -7,6 +7,14 @@
           "include-filter": "libcore.java.awt.font"
         }
       ]
+    },
+    {
+      "name": "CtsLibcoreOjTestCases",
+      "options": [
+        {
+          "include-filter": "test.java.awt.font"
+        }
+      ]
     }
   ]
 }
\ No newline at end of file
diff --git a/ojluni/src/main/java/java/io/File.java b/ojluni/src/main/java/java/io/File.java
index 98956ca..0037534 100644
--- a/ojluni/src/main/java/java/io/File.java
+++ b/ojluni/src/main/java/java/io/File.java
@@ -518,7 +518,7 @@
 
     /* -- Path operations -- */
 
-    // Android-changed: Android-specific path information
+    // Android-changed: Android-specific path information.
     /**
      * Tests whether this abstract pathname is absolute.  The definition of
      * absolute pathname is system dependent.  On Android, absolute paths start with
@@ -531,7 +531,7 @@
         return fs.isAbsolute(this);
     }
 
-    // Android-changed: Android-specific path information
+    // Android-changed: Android-specific path information.
     /**
      * Returns the absolute path of this file. An absolute path is a path that starts at a root
      * of the file system. On Android, there is only one root: {@code /}.
@@ -737,8 +737,7 @@
 
     /* -- Attribute accessors -- */
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on android
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Tests whether the application can read the file denoted by this
      * abstract pathname.
@@ -763,8 +762,7 @@
         return fs.checkAccess(this, FileSystem.ACCESS_READ);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on android
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Tests whether the application can modify the file denoted by this
      * abstract pathname.
@@ -1450,8 +1448,7 @@
         return fs.setLastModifiedTime(this, time);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Marks the file or directory named by this abstract pathname so that
      * only read operations are allowed. After invoking this method the file
@@ -1480,8 +1477,7 @@
         return fs.setReadOnly(this);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Sets the owner's or everybody's write permission for this abstract
      * pathname.
@@ -1523,8 +1519,7 @@
         return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * A convenience method to set the owner's write permission for this abstract
      * pathname.
@@ -1554,8 +1549,7 @@
         return setWritable(writable, true);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Sets the owner's or everybody's read permission for this abstract
      * pathname.
@@ -1600,8 +1594,7 @@
         return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * A convenience method to set the owner's read permission for this abstract
      * pathname.
@@ -1634,8 +1627,7 @@
         return setReadable(readable, true);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Sets the owner's or everybody's execute permission for this abstract
      * pathname.
@@ -1680,8 +1672,7 @@
         return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * A convenience method to set the owner's execute permission for this
      * abstract pathname.
@@ -1714,8 +1705,7 @@
         return setExecutable(executable, true);
     }
 
-    // Android-changed. Removed javadoc comment about special privileges
-    // that doesn't make sense on Android.
+    // Android-changed: Removed inapplicable javadoc comment about special privileges.
     /**
      * Tests whether the application can execute the file denoted by this
      * abstract pathname.
@@ -1873,8 +1863,7 @@
     private static class TempDirectory {
         private TempDirectory() { }
 
-        // Android-changed: Don't cache java.io.tmpdir value
-        // temporary directory location.
+        // Android-changed: Don't cache java.io.tmpdir value temporary directory location.
         /*
         private static final File tmpdir = new File(AccessController
            .doPrivileged(new GetPropertyAction("java.io.tmpdir")));
@@ -1888,8 +1877,8 @@
         static File generateFile(String prefix, String suffix, File dir)
             throws IOException
         {
-            // Android-changed: Use Math.randomIntInternal. This (pseudo) random number
-            // is initialized post-fork
+            // Android-changed: Use Math.randomIntInternal.
+            // This (pseudo) random number is initialized post-fork.
 
             long n = Math.randomLongInternal();
             if (n == Long.MIN_VALUE) {
@@ -1898,7 +1887,7 @@
                 n = Math.abs(n);
             }
 
-            // Android-changed: Reject invalid file prefixes
+            // Android-changed: Reject invalid file prefixes.
             // Use only the file name from the supplied prefix
             // prefix = (new File(prefix)).getName();
 
diff --git a/ojluni/src/main/java/java/io/FileDescriptor.java b/ojluni/src/main/java/java/io/FileDescriptor.java
index 98db443..90b97b5 100644
--- a/ojluni/src/main/java/java/io/FileDescriptor.java
+++ b/ojluni/src/main/java/java/io/FileDescriptor.java
@@ -47,11 +47,11 @@
  * @since   JDK1.0
  */
 public final class FileDescriptor {
-    // Android-changed: Removed parent reference counting. Creator is responsible for closing
-    // the file descriptor.
+    // Android-changed: Removed parent reference counting.
+    // The creator is responsible for closing the file descriptor.
 
-    // Android-changed: Renamed fd to descriptor to avoid issues with JNI/reflection
-    // fetching the descriptor value.
+    // Android-changed: Renamed fd to descriptor.
+    // Renaming is to avoid issues with JNI/reflection fetching the descriptor value.
     private int descriptor;
 
     // Android-added: Track fd owner to guard against accidental closure. http://b/110100358
@@ -63,6 +63,9 @@
     /** @hide */
     public static final long NO_OWNER = 0L;
 
+    // Android-added: lock for release$.
+    private final Object releaseLock = new Object();
+
     /**
      * Constructs an (invalid) FileDescriptor
      * object.
@@ -142,11 +145,11 @@
      */
     public native void sync() throws SyncFailedException;
 
-    // Android-removed: initIDs not used to allow compile-time intialization
+    // Android-removed: initIDs not used to allow compile-time initialization.
     /* This routine initializes JNI field offsets for the class */
     //private static native void initIDs();
 
-    // Android-added: Needed for framework to access descriptor value
+    // 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.
@@ -156,7 +159,7 @@
         return descriptor;
     }
 
-    // Android-added: Needed for framework to access descriptor value
+    // 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.
@@ -211,19 +214,26 @@
 
     /**
      * Returns a copy of this FileDescriptor, and sets this to an invalid state.
+     *
+     * The returned instance is not necessarily {@code valid()}, if the original FileDescriptor
+     * was invalid, or if another thread concurrently calls {@code release$()}.
+     *
      * @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;
+      synchronized (releaseLock) {
+          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.
 
-    // Android-added: Needed for framework to test if it's a socket
+    // Android-added: Needed for framework to test if it's a socket.
     /**
      * @hide internal use only
      */
@@ -254,5 +264,5 @@
             }
         );
     }
-// Android-removed: Removed method required for parents reference counting
+// Android-removed: Removed method required for parents reference counting.
 }
diff --git a/ojluni/src/main/java/java/io/FileInputStream.java b/ojluni/src/main/java/java/io/FileInputStream.java
index 38230bb..9ce75ff 100755
--- a/ojluni/src/main/java/java/io/FileInputStream.java
+++ b/ojluni/src/main/java/java/io/FileInputStream.java
@@ -222,6 +222,9 @@
         fd.attach(this);
         */
         this.isFdOwner = isFdOwner;
+        if (isFdOwner) {
+            IoUtils.setFdOwner(this.fd, this);
+        }
     }
 
     // BEGIN Android-changed: Open files using IoBridge to share BlockGuard & StrictMode logic.
diff --git a/ojluni/src/main/java/java/io/FileOutputStream.java b/ojluni/src/main/java/java/io/FileOutputStream.java
index d0d0d40..66f4c05 100755
--- a/ojluni/src/main/java/java/io/FileOutputStream.java
+++ b/ojluni/src/main/java/java/io/FileOutputStream.java
@@ -299,6 +299,9 @@
         // Android-changed: FileDescriptor ownership tracking mechanism.
         // fd.attach(this);
         this.isFdOwner = isFdOwner;
+        if (isFdOwner) {
+            IoUtils.setFdOwner(this.fd, this);
+        }
     }
 
     // BEGIN Android-changed: Open files using IoBridge to share BlockGuard & StrictMode logic.
diff --git a/ojluni/src/main/java/java/io/ObjectOutputStream.java b/ojluni/src/main/java/java/io/ObjectOutputStream.java
index ccec944..1f7f901 100644
--- a/ojluni/src/main/java/java/io/ObjectOutputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectOutputStream.java
@@ -1223,7 +1223,7 @@
                 writeClass((Class) obj, unshared);
             } else if (obj instanceof ObjectStreamClass) {
                 writeClassDesc((ObjectStreamClass) obj, unshared);
-            // END Android-changed:  Make Class and ObjectStreamClass replaceable.
+            // END Android-changed: Make Class and ObjectStreamClass replaceable.
             } else if (obj instanceof String) {
                 writeString((String) obj, unshared);
             } else if (cl.isArray()) {
@@ -1865,7 +1865,7 @@
             return blkmode;
         }
 
-        // BEGIN Android-added: Warning about writing to closed ObjectOutputStream
+        // BEGIN Android-added: Warning about writing to closed ObjectOutputStream.
         /**
          * Warns if the stream has been closed.
          *
@@ -1884,7 +1884,7 @@
                 warnOnceWhenWriting = false;
             }
         }
-        // END Android-added: Warning about writing to closed ObjectOutputStream
+        // END Android-added: Warning about writing to closed ObjectOutputStream.
 
         /* ----------------- generic output stream methods ----------------- */
         /*
@@ -1916,7 +1916,7 @@
         public void close() throws IOException {
             flush();
             out.close();
-            // Android-added: Warning about writing to closed ObjectOutputStream
+            // Android-added: Warning about writing to closed ObjectOutputStream.
             warnOnceWhenWriting = true;
         }
 
@@ -1932,7 +1932,7 @@
             if (!(copy || blkmode)) {           // write directly
                 drain();
                 out.write(b, off, len);
-                // Android-added: Warning about writing to closed ObjectOutputStream
+                // Android-added: Warning about writing to closed ObjectOutputStream.
                 warnIfClosed();
                 return;
             }
@@ -1955,7 +1955,7 @@
                     len -= wlen;
                 }
             }
-            // Android-added: Warning about writing to closed ObjectOutputStream
+            // Android-added: Warning about writing to closed ObjectOutputStream.
             warnIfClosed();
         }
 
@@ -1972,7 +1972,7 @@
             }
             out.write(buf, 0, pos);
             pos = 0;
-            // Android-added: Warning about writing to closed ObjectOutputStream
+            // Android-added: Warning about writing to closed ObjectOutputStream.
             warnIfClosed();
         }
 
@@ -1991,7 +1991,7 @@
                 Bits.putInt(hbuf, 1, len);
                 out.write(hbuf, 0, 5);
             }
-            // Android-added: Warning about writing to closed ObjectOutputStream
+            // Android-added: Warning about writing to closed ObjectOutputStream.
             warnIfClosed();
         }
 
diff --git a/ojluni/src/main/java/java/io/ObjectStreamClass.java b/ojluni/src/main/java/java/io/ObjectStreamClass.java
index a88ad63..9a1a48f 100644
--- a/ojluni/src/main/java/java/io/ObjectStreamClass.java
+++ b/ojluni/src/main/java/java/io/ObjectStreamClass.java
@@ -1425,12 +1425,12 @@
             {
                 return null;
             }
-            // BEGIN Android-changed: Serialization constructor obtained differently
+            // BEGIN Android-changed: Serialization constructor obtained differently.
             // cons = reflFactory.newConstructorForSerialization(cl, cons);
             if (cons.getDeclaringClass() != cl) {
                 cons = cons.serializationCopy(cons.getDeclaringClass(), cl);
             }
-            // END Android-changed: Serialization constructor obtained differently
+            // END Android-changed: Serialization constructor obtained differently.
             cons.setAccessible(true);
             return cons;
         } catch (NoSuchMethodException ex) {
@@ -1797,7 +1797,7 @@
                 }
             }
 
-            // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
+            // 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
@@ -1817,7 +1817,7 @@
                     // instructions to the developer on how to fix the problems.
                     warnIncompatibleSUIDChange = true;
                 }
-                // END Android-changed: Fix/log clinit serialization workaround b/29064453
+            // END Android-changed: Fix/log clinit serialization workaround. b/29064453
                 dout.writeUTF("<clinit>");
                 dout.writeInt(Modifier.STATIC);
                 dout.writeUTF("()V");
@@ -1882,14 +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
+            // 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
+            // END Android-added: Fix/log clinit serialization workaround. b/29064453
             return hash;
         } catch (IOException ex) {
             throw new InternalError(ex);
@@ -1898,7 +1898,7 @@
         }
     }
 
-    // BEGIN Android-changed: Fix/log clinit serialization workaround b/29064453
+    // 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.
      *
@@ -1943,7 +1943,7 @@
      */
     private native static boolean hasStaticInitializer(
         Class<?> cl, boolean inheritStaticInitializer);
-    // END Android-changed: Fix/log clinit serialization workaround b/29064453
+    // 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/lang/Byte.java b/ojluni/src/main/java/java/lang/Byte.java
index deb4ecb..bc397f9 100644
--- a/ojluni/src/main/java/java/lang/Byte.java
+++ b/ojluni/src/main/java/java/lang/Byte.java
@@ -25,6 +25,8 @@
 
 package java.lang;
 
+// Android-removed: Unsupported @HotSpotIntrinsicCandidate annotation.
+// import jdk.internal.HotSpotIntrinsicCandidate;
 import libcore.util.HexEncoding;
 
 /**
@@ -41,7 +43,7 @@
  * @author  Nakul Saraiya
  * @author  Joseph D. Darcy
  * @see     java.lang.Number
- * @since   JDK1.1
+ * @since   1.1
  */
 public final class Byte extends Number implements Comparable<Byte> {
 
@@ -100,6 +102,8 @@
      * @return a {@code Byte} instance representing {@code b}.
      * @since  1.5
      */
+    // Android-removed: Unsupported @HotSpotIntrinsicCandidate annotation.
+    // @HotSpotIntrinsicCandidate
     public static Byte valueOf(byte b) {
         final int offset = 128;
         return ByteCache.cache[(int)b + offset];
@@ -296,7 +300,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Byte}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(byte)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Byte(byte value) {
         this.value = value;
     }
@@ -310,10 +320,16 @@
      *
      * @param s         the {@code String} to be converted to a
      *                  {@code Byte}
-     * @throws           NumberFormatException If the {@code String}
+     * @throws          NumberFormatException if the {@code String}
      *                  does not contain a parsable {@code byte}.
-     * @see        java.lang.Byte#parseByte(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseByte(String)} to convert a string to a
+     * {@code byte} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Byte} object.
      */
+    @Deprecated(since="9")
     public Byte(String s) throws NumberFormatException {
         this.value = parseByte(s, 10);
     }
@@ -322,6 +338,8 @@
      * Returns the value of this {@code Byte} as a
      * {@code byte}.
      */
+    // Android-removed: Unsupported @HotSpotIntrinsicCandidate annotation.
+    // @HotSpotIntrinsicCandidate
     public byte byteValue() {
         return value;
     }
@@ -461,6 +479,22 @@
     }
 
     /**
+     * Compares two {@code byte} values numerically treating the values
+     * as unsigned.
+     *
+     * @param  x the first {@code byte} to compare
+     * @param  y the second {@code byte} to compare
+     * @return the value {@code 0} if {@code x == y}; a value less
+     *         than {@code 0} if {@code x < y} as unsigned values; and
+     *         a value greater than {@code 0} if {@code x > y} as
+     *         unsigned values
+     * @since 9
+     */
+    public static int compareUnsigned(byte x, byte y) {
+        return Byte.toUnsignedInt(x) - Byte.toUnsignedInt(y);
+    }
+
+    /**
      * Converts the argument to an {@code int} by an unsigned
      * conversion.  In an unsigned conversion to an {@code int}, the
      * high-order 24 bits of the {@code int} are zero and the
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index f792248..7925408 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -896,22 +896,53 @@
     public Package getPackage() {
         ClassLoader loader = getClassLoader();
         if (loader != null) {
-            String packageName = getPackageName$();
+            String packageName = getPackageName();
             return packageName != null ? loader.getPackage(packageName) : null;
         }
         return null;
     }
 
     /**
-     * Returns the package name of this class. This returns null for classes in
-     * the default package.
+     * Returns the fully qualified package name.
      *
-     * @hide
+     * <p> If this class is a top level class, then this method returns the fully
+     * qualified name of the package that the class is a member of, or the
+     * empty string if the class is in an unnamed package.
+     *
+     * <p> If this class is a member class, then this method is equivalent to
+     * invoking {@code getPackageName()} on the {@linkplain #getEnclosingClass
+     * enclosing class}.
+     *
+     * <p> If this class is a {@linkplain #isLocalClass local class} or an {@linkplain
+     * #isAnonymousClass() anonymous class}, then this method is equivalent to
+     * invoking {@code getPackageName()} on the {@linkplain #getDeclaringClass
+     * declaring class} of the {@linkplain #getEnclosingMethod enclosing method} or
+     * {@linkplain #getEnclosingConstructor enclosing constructor}.
+     *
+     * <p> If this class represents an array type then this method returns the
+     * package name of the element type. If this class represents a primitive
+     * type or void then the package name "{@code java.lang}" is returned.
+     *
+     * @return the fully qualified package name
+     *
+     * @since 9
+     * @spec JPMS
+     * @jls 6.7  Fully Qualified Names
      */
-    public String getPackageName$() {
-        String name = getName();
-        int last = name.lastIndexOf('.');
-        return last == -1 ? null : name.substring(0, last);
+    public String getPackageName() {
+            // BEGIN Android-changed: Don't use a private field as a cache.
+            Class<?> c = this;
+            while (c.isArray()) {
+                c = c.getComponentType();
+            }
+            if (c.isPrimitive()) {
+                return "java.lang";
+            } else {
+                String cn = c.getName();
+                int dot = cn.lastIndexOf('.');
+                return (dot != -1) ? cn.substring(0, dot).intern() : "";
+            }
+            // END Android-changed: Don't use a private field as a cache.
     }
 
 
@@ -1135,7 +1166,7 @@
      *     that class is a local or anonymous class; otherwise {@code null}.
      * @since 1.5
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     public Method getEnclosingMethod() {
         if (classNameImpliesTopLevel()) {
             return null;
@@ -1157,7 +1188,7 @@
      *     that class is a local or anonymous class; otherwise {@code null}.
      * @since 1.5
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     public Constructor<?> getEnclosingConstructor() {
         if (classNameImpliesTopLevel()) {
             return null;
@@ -1184,7 +1215,7 @@
      * @return the declaring class for this class
      * @since JDK1.1
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     @FastNative
     public native Class<?> getDeclaringClass();
 
@@ -1195,7 +1226,7 @@
      * @return the immediately enclosing class of the underlying class
      * @since 1.5
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     @FastNative
     public native Class<?> getEnclosingClass();
 
@@ -1593,7 +1624,7 @@
      * @jls 8.2 Class Members
      * @jls 8.3 Field Declarations
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     public Field getField(String name)
         throws NoSuchFieldException {
         if (name == null) {
@@ -1764,7 +1795,7 @@
      *
      * @since JDK1.1
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     @FastNative
     public native Class<?>[] getDeclaredClasses();
 
@@ -1810,7 +1841,7 @@
      * @jls 8.2 Class Members
      * @jls 8.3 Field Declarations
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     @FastNative
     public native Field[] getDeclaredFields();
 
@@ -1986,7 +2017,7 @@
      * @jls 8.2 Class Members
      * @jls 8.3 Field Declarations
      */
-    // Android-changed: Removed SecurityException
+    // Android-changed: Removed SecurityException.
     @FastNative
     public native Field getDeclaredField(String name) throws NoSuchFieldException;
 
diff --git a/ojluni/src/main/java/java/lang/Deprecated.java b/ojluni/src/main/java/java/lang/Deprecated.java
index 58a0691..3735f59 100644
--- a/ojluni/src/main/java/java/lang/Deprecated.java
+++ b/ojluni/src/main/java/java/lang/Deprecated.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -29,17 +29,75 @@
 import static java.lang.annotation.ElementType.*;
 
 /**
- * A program element annotated &#64;Deprecated is one that programmers
- * are discouraged from using, typically because it is dangerous,
- * or because a better alternative exists.  Compilers warn when a
- * deprecated program element is used or overridden in non-deprecated code.
+ * A program element annotated {@code @Deprecated} is one that programmers
+ * are discouraged from using. An element may be deprecated for any of several
+ * reasons, for example, its usage is likely to lead to errors; it may
+ * be changed incompatibly or removed in a future version; it has been
+ * superseded by a newer, usually preferable alternative; or it is obsolete.
+ *
+ * <p>Compilers issue warnings when a deprecated program element is used or
+ * overridden in non-deprecated code. Use of the {@code @Deprecated}
+ * annotation on a local variable declaration or on a parameter declaration
+ * or a package declaration has no effect on the warnings issued by a compiler.
+ *
+ * <p>When a module is deprecated, the use of that module in {@code
+ * requires}, but not in {@code exports} or {@code opens} clauses causes
+ * a warning to be issued. A module being deprecated does <em>not</em> cause
+ * warnings to be issued for uses of types within the module.
+ *
+ * <p>This annotation type has a string-valued element {@code since}. The value
+ * of this element indicates the version in which the annotated program element
+ * was first deprecated.
+ *
+ * <p>This annotation type has a boolean-valued element {@code forRemoval}.
+ * A value of {@code true} indicates intent to remove the annotated program
+ * element in a future version. A value of {@code false} indicates that use of
+ * the annotated program element is discouraged, but at the time the program
+ * element was annotated, there was no specific intent to remove it.
+ *
+ * @apiNote
+ * It is strongly recommended that the reason for deprecating a program element
+ * be explained in the documentation, using the {@code &#64;deprecated}
+ * javadoc tag. The documentation should also suggest and link to a
+ * recommended replacement API, if applicable. A replacement API often
+ * has subtly different semantics, so such issues should be discussed as
+ * well.
+ *
+ * <p>It is recommended that a {@code since} value be provided with all newly
+ * annotated program elements. Note that {@code since} cannot be mandatory,
+ * as there are many existing annotations that lack this element value.
+ *
+ * <p>There is no defined order among annotation elements. As a matter of
+ * style, the {@code since} element should be placed first.
+ *
+ * <p>The {@code @Deprecated} annotation should always be present if
+ * the {@code &#64;deprecated} javadoc tag is present, and vice-versa.
  *
  * @author  Neal Gafter
  * @since 1.5
- * @jls 9.6.3.6 @Deprecated
+ * @jls 9.6.4.6 @Deprecated
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
-@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
+@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
 public @interface Deprecated {
+    /**
+     * Returns the version in which the annotated element became deprecated.
+     * The version string is in the same format and namespace as the value of
+     * the {@code @since} javadoc tag. The default value is the empty
+     * string.
+     *
+     * @return the version string
+     * @since 9
+     */
+    String since() default "";
+
+    /**
+     * Indicates whether the annotated element is subject to removal in a
+     * future version. The default value is {@code false}.
+     *
+     * @return whether the element is subject to removal
+     * @since 9
+     */
+    boolean forRemoval() default false;
 }
diff --git a/ojluni/src/main/java/java/lang/Enum.java b/ojluni/src/main/java/java/lang/Enum.java
index 988c133..6b37aea 100644
--- a/ojluni/src/main/java/java/lang/Enum.java
+++ b/ojluni/src/main/java/java/lang/Enum.java
@@ -239,7 +239,7 @@
     public static <T extends Enum<T>> T valueOf(Class<T> enumType,
                                                 String name) {
         Objects.requireNonNull(enumType, "enumType == null");
-        Objects.requireNonNull(enumType, "name == null");
+        Objects.requireNonNull(name, "name == null");
         T[] values = getSharedConstants(enumType);
         if (values == null) {
             throw new IllegalArgumentException(enumType.toString() + " is not an enum type.");
diff --git a/ojluni/src/main/java/java/lang/Math.java b/ojluni/src/main/java/java/lang/Math.java
index 17cbf6d..a04b951 100644
--- a/ojluni/src/main/java/java/lang/Math.java
+++ b/ojluni/src/main/java/java/lang/Math.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
  */
 
 package java.lang;
+
 import dalvik.annotation.optimization.CriticalNative;
 import java.util.Random;
 
@@ -99,13 +100,13 @@
  * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
  * throw an {@code ArithmeticException} when the results overflow.
  * For other arithmetic operations such as divide, absolute value,
- * increment, decrement, and negation overflow occurs only with
+ * increment by one, decrement by one, and negation, overflow occurs only with
  * a specific minimum or maximum value and should be checked against
  * the minimum or maximum as appropriate.
  *
  * @author  unascribed
  * @author  Joseph D. Darcy
- * @since   JDK1.0
+ * @since   1.0
  */
 
 public final class Math {
@@ -132,6 +133,18 @@
     public static final double PI = 3.14159265358979323846;
 
     /**
+     * Constant by which to multiply an angular value in degrees to obtain an
+     * angular value in radians.
+     */
+    private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
+
+    /**
+     * Constant by which to multiply an angular value in radians to obtain an
+     * angular value in degrees.
+     */
+    private static final double RADIANS_TO_DEGREES = 57.29577951308232;
+
+    /**
      * Returns the trigonometric sine of an angle.  Special cases:
      * <ul><li>If the argument is NaN or an infinity, then the
      * result is NaN.
@@ -236,7 +249,7 @@
      * @since   1.2
      */
     public static double toRadians(double angdeg) {
-        return angdeg / 180.0 * PI;
+        return angdeg * DEGREES_TO_RADIANS;
     }
 
     /**
@@ -252,7 +265,7 @@
      * @since   1.2
      */
     public static double toDegrees(double angrad) {
-        return angrad * 180.0 / PI;
+        return angrad * RADIANS_TO_DEGREES;
     }
 
     /**
@@ -893,6 +906,20 @@
     }
 
     /**
+     * Returns the product of the arguments, throwing an exception if the result
+     * overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @since 9
+     */
+    public static long multiplyExact(long x, int y) {
+        return multiplyExact(x, (long)y);
+    }
+
+    /**
      * Returns the product of the arguments,
      * throwing an exception if the result overflows a {@code long}.
      *
@@ -1037,17 +1064,66 @@
     }
 
     /**
+     * Returns the exact mathematical product of the arguments.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @since 9
+     */
+    public static long multiplyFull(int x, int y) {
+        return (long)x * (long)y;
+    }
+
+    /**
+     * Returns as a {@code long} the most significant 64 bits of the 128-bit
+     * product of two 64-bit factors.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @since 9
+     */
+    public static long multiplyHigh(long x, long y) {
+        if (x < 0 || y < 0) {
+            // Use technique from section 8-2 of Henry S. Warren, Jr.,
+            // Hacker's Delight (2nd ed.) (Addison Wesley, 2013), 173-174.
+            long x1 = x >> 32;
+            long x2 = x & 0xFFFFFFFFL;
+            long y1 = y >> 32;
+            long y2 = y & 0xFFFFFFFFL;
+            long z2 = x2 * y2;
+            long t = x1 * y2 + (z2 >>> 32);
+            long z1 = t & 0xFFFFFFFFL;
+            long z0 = t >> 32;
+            z1 += x2 * y1;
+            return x1 * y1 + z0 + (z1 >> 32);
+        } else {
+            // Use Karatsuba technique with two base 2^32 digits.
+            long x1 = x >>> 32;
+            long y1 = y >>> 32;
+            long x2 = x & 0xFFFFFFFFL;
+            long y2 = y & 0xFFFFFFFFL;
+            long A = x1 * y1;
+            long B = x2 * y2;
+            long C = (x1 + x2) * (y1 + y2);
+            long K = C - A - B;
+            return (((B >>> 32) + K) >>> 32) + A;
+        }
+    }
+
+    /**
      * Returns the largest (closest to positive infinity)
      * {@code int} value that is less than or equal to the algebraic quotient.
      * There is one special case, if the dividend is the
      * {@linkplain Integer#MIN_VALUE Integer.MIN_VALUE} and the divisor is {@code -1},
      * then integer overflow occurs and
-     * the result is equal to the {@code Integer.MIN_VALUE}.
+     * the result is equal to {@code Integer.MIN_VALUE}.
      * <p>
      * Normal integer division operates under the round to zero rounding mode
      * (truncation).  This operation instead acts under the round toward
      * negative infinity (floor) rounding mode.
-     * The floor rounding mode gives different results than truncation
+     * The floor rounding mode gives different results from truncation
      * when the exact result is negative.
      * <ul>
      *   <li>If the signs of the arguments are the same, the results of
@@ -1086,12 +1162,41 @@
      * There is one special case, if the dividend is the
      * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
      * then integer overflow occurs and
-     * the result is equal to the {@code Long.MIN_VALUE}.
+     * the result is equal to {@code Long.MIN_VALUE}.
      * <p>
      * Normal integer division operates under the round to zero rounding mode
      * (truncation).  This operation instead acts under the round toward
      * negative infinity (floor) rounding mode.
-     * The floor rounding mode gives different results than truncation
+     * The floor rounding mode gives different results from truncation
+     * when the exact result is negative.
+     * <p>
+     * For examples, see {@link #floorDiv(int, int)}.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorMod(long, int)
+     * @see #floor(double)
+     * @since 9
+     */
+    public static long floorDiv(long x, int y) {
+        return floorDiv(x, (long)y);
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
+     * the result is equal to {@code Long.MIN_VALUE}.
+     * <p>
+     * Normal integer division operates under the round to zero rounding mode
+     * (truncation).  This operation instead acts under the round toward
+     * negative infinity (floor) rounding mode.
+     * The floor rounding mode gives different results from truncation
      * when the exact result is negative.
      * <p>
      * For examples, see {@link #floorDiv(int, int)}.
@@ -1159,8 +1264,34 @@
      * @since 1.8
      */
     public static int floorMod(int x, int y) {
-        int r = x - floorDiv(x, y) * y;
-        return r;
+        return x - floorDiv(x, y) * y;
+    }
+
+    /**
+     * Returns the floor modulus of the {@code long} and {@code int} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     *
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * For examples, see {@link #floorMod(int, int)}.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see #floorDiv(long, int)
+     * @since 9
+     */
+    public static int floorMod(long x, int y) {
+        // Result cannot overflow the range of int.
+        return (int)(x - floorDiv(x, y) * y);
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/Runtime.java b/ojluni/src/main/java/java/lang/Runtime.java
index f5c52e7..b9baf65 100644
--- a/ojluni/src/main/java/java/lang/Runtime.java
+++ b/ojluni/src/main/java/java/lang/Runtime.java
@@ -78,11 +78,6 @@
      */
     private boolean shuttingDown;
 
-    /**
-     * Reflects whether we are tracing method calls.
-     */
-    private boolean tracingMethods;
-
     private static native void nativeExit(int code);
 
     /**
@@ -845,13 +840,8 @@
      *               <code>false</code> to disable this feature.
      */
     public void traceMethodCalls(boolean on) {
-        if (on != tracingMethods) {
-            if (on) {
-                VMDebug.startMethodTracing();
-            } else {
-                VMDebug.stopMethodTracing();
-            }
-            tracingMethods = on;
+        if (on) {
+            throw new UnsupportedOperationException();
         }
     }
 
diff --git a/ojluni/src/main/java/java/lang/Short.java b/ojluni/src/main/java/java/lang/Short.java
index 9fb3913..dd6e2e2 100644
--- a/ojluni/src/main/java/java/lang/Short.java
+++ b/ojluni/src/main/java/java/lang/Short.java
@@ -25,6 +25,9 @@
 
 package java.lang;
 
+// Android-removed: unsupported @HotSpotIntrinsicCandidate annotation.
+// import jdk.internal.HotSpotIntrinsicCandidate;
+
 /**
  * The {@code Short} class wraps a value of primitive type {@code
  * short} in an object.  An object of type {@code Short} contains a
@@ -38,7 +41,7 @@
  * @author  Nakul Saraiya
  * @author  Joseph D. Darcy
  * @see     java.lang.Number
- * @since   JDK1.1
+ * @since   1.1
  */
 public final class Short extends Number implements Comparable<Short> {
 
@@ -227,6 +230,8 @@
      * @return a {@code Short} instance representing {@code s}.
      * @since  1.5
      */
+    // Android-removed: unsupported @HotSpotIntrinsicCandidate annotation.
+    // @HotSpotIntrinsicCandidate
     public static Short valueOf(short s) {
         final int offset = 128;
         int sAsInt = s;
@@ -299,7 +304,13 @@
      *
      * @param value     the value to be represented by the
      *                  {@code Short}.
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor. The static factory
+     * {@link #valueOf(short)} is generally a better choice, as it is
+     * likely to yield significantly better space and time performance.
      */
+    @Deprecated(since="9")
     public Short(short value) {
         this.value = value;
     }
@@ -315,8 +326,14 @@
      *          {@code Short}
      * @throws  NumberFormatException If the {@code String}
      *          does not contain a parsable {@code short}.
-     * @see     java.lang.Short#parseShort(java.lang.String, int)
+     *
+     * @deprecated
+     * It is rarely appropriate to use this constructor.
+     * Use {@link #parseShort(String)} to convert a string to a
+     * {@code short} primitive, or use {@link #valueOf(String)}
+     * to convert a string to a {@code Short} object.
      */
+    @Deprecated(since="9")
     public Short(String s) throws NumberFormatException {
         this.value = parseShort(s, 10);
     }
@@ -334,6 +351,8 @@
      * Returns the value of this {@code Short} as a
      * {@code short}.
      */
+    // Android-removed: unsupported @HotSpotIntrinsicCandidate annotation.
+    // @HotSpotIntrinsicCandidate
     public short shortValue() {
         return value;
     }
@@ -464,6 +483,22 @@
     }
 
     /**
+     * Compares two {@code short} values numerically treating the values
+     * as unsigned.
+     *
+     * @param  x the first {@code short} to compare
+     * @param  y the second {@code short} to compare
+     * @return the value {@code 0} if {@code x == y}; a value less
+     *         than {@code 0} if {@code x < y} as unsigned values; and
+     *         a value greater than {@code 0} if {@code x > y} as
+     *         unsigned values
+     * @since 9
+     */
+    public static int compareUnsigned(short x, short y) {
+        return Short.toUnsignedInt(x) - Short.toUnsignedInt(y);
+    }
+
+    /**
      * The number of bits used to represent a {@code short} value in two's
      * complement binary form.
      * @since 1.5
@@ -487,6 +522,8 @@
      *     the bytes in the specified {@code short} value.
      * @since 1.5
      */
+    // Android-removed: unsupported @HotSpotIntrinsicCandidate annotation.
+    // @HotSpotIntrinsicCandidate
     public static short reverseBytes(short i) {
         return (short) (((i & 0xFF00) >> 8) | (i << 8));
     }
diff --git a/ojluni/src/main/java/java/lang/StrictMath.java b/ojluni/src/main/java/java/lang/StrictMath.java
index ae4af2b..c0a41b9 100644
--- a/ojluni/src/main/java/java/lang/StrictMath.java
+++ b/ojluni/src/main/java/java/lang/StrictMath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
  */
 
 package java.lang;
+
 import java.util.Random;
 import sun.misc.DoubleConsts;
 
@@ -68,7 +69,7 @@
  * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
  * throw an {@code ArithmeticException} when the results overflow.
  * For other arithmetic operations such as divide, absolute value,
- * increment, decrement, and negation overflow occurs only with
+ * increment by one, decrement by one, and negation overflow occurs only with
  * a specific minimum or maximum value and should be checked against
  * the minimum or maximum as appropriate.
  *
@@ -98,6 +99,19 @@
     public static final double PI = 3.14159265358979323846;
 
     /**
+     * Constant by which to multiply an angular value in degrees to obtain an
+     * angular value in radians.
+     */
+    private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
+
+    /**
+     * Constant by which to multiply an angular value in radians to obtain an
+     * angular value in degrees.
+     */
+
+    private static final double RADIANS_TO_DEGREES = 57.29577951308232;
+
+    /**
      * Returns the trigonometric sine of an angle. Special cases:
      * <ul><li>If the argument is NaN or an infinity, then the
      * result is NaN.
@@ -179,7 +193,7 @@
     public static strictfp double toRadians(double angdeg) {
         // Do not delegate to Math.toRadians(angdeg) because
         // this method has the strictfp modifier.
-        return angdeg / 180.0 * PI;
+        return angdeg * DEGREES_TO_RADIANS;
     }
 
     /**
@@ -196,7 +210,7 @@
     public static strictfp double toDegrees(double angrad) {
         // Do not delegate to Math.toDegrees(angrad) because
         // this method has the strictfp modifier.
-        return angrad * 180.0 / PI;
+        return angrad * RADIANS_TO_DEGREES;
     }
 
     /**
@@ -785,6 +799,21 @@
     }
 
     /**
+     * Returns the product of the arguments, throwing an exception if the result
+     * overflows a {@code long}.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#multiplyExact(long,int)
+     * @since 9
+     */
+    public static long multiplyExact(long x, int y) {
+        return Math.multiplyExact(x, y);
+    }
+
+    /**
      * Returns the product of the arguments,
      * throwing an exception if the result overflows a {@code long}.
      *
@@ -814,6 +843,33 @@
     }
 
     /**
+     * Returns the exact mathematical product of the arguments.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @see Math#multiplyFull(int,int)
+     * @since 9
+     */
+    public static long multiplyFull(int x, int y) {
+        return Math.multiplyFull(x, y);
+    }
+
+    /**
+     * Returns as a {@code long} the most significant 64 bits of the 128-bit
+     * product of two 64-bit factors.
+     *
+     * @param x the first value
+     * @param y the second value
+     * @return the result
+     * @see Math#multiplyHigh(long,long)
+     * @since 9
+     */
+    public static long multiplyHigh(long x, long y) {
+        return Math.multiplyHigh(x, y);
+    }
+
+    /**
      * Returns the largest (closest to positive infinity)
      * {@code int} value that is less than or equal to the algebraic quotient.
      * There is one special case, if the dividend is the
@@ -843,6 +899,30 @@
      * There is one special case, if the dividend is the
      * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
      * then integer overflow occurs and
+     * the result is equal to {@code Long.MIN_VALUE}.
+     * <p>
+     * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
+     * a comparison to the integer division {@code /} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the largest (closest to positive infinity)
+     * {@code int} value that is less than or equal to the algebraic quotient.
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorDiv(long, int)
+     * @see Math#floor(double)
+     * @since 9
+     */
+    public static long floorDiv(long x, int y) {
+        return Math.floorDiv(x, y);
+    }
+
+    /**
+     * Returns the largest (closest to positive infinity)
+     * {@code long} value that is less than or equal to the algebraic quotient.
+     * There is one special case, if the dividend is the
+     * {@linkplain Long#MIN_VALUE Long.MIN_VALUE} and the divisor is {@code -1},
+     * then integer overflow occurs and
      * the result is equal to the {@code Long.MIN_VALUE}.
      * <p>
      * See {@link Math#floorDiv(int, int) Math.floorDiv} for examples and
@@ -887,6 +967,35 @@
     public static int floorMod(int x, int y) {
         return Math.floorMod(x , y);
     }
+
+    /**
+     * Returns the floor modulus of the {@code long} and {@code int} arguments.
+     * <p>
+     * The floor modulus is {@code x - (floorDiv(x, y) * y)},
+     * has the same sign as the divisor {@code y}, and
+     * is in the range of {@code -abs(y) < r < +abs(y)}.
+     *
+     * <p>
+     * The relationship between {@code floorDiv} and {@code floorMod} is such that:
+     * <ul>
+     *   <li>{@code floorDiv(x, y) * y + floorMod(x, y) == x}
+     * </ul>
+     * <p>
+     * See {@link Math#floorMod(int, int) Math.floorMod} for examples and
+     * a comparison to the {@code %} operator.
+     *
+     * @param x the dividend
+     * @param y the divisor
+     * @return the floor modulus {@code x - (floorDiv(x, y) * y)}
+     * @throws ArithmeticException if the divisor {@code y} is zero
+     * @see Math#floorMod(long, int)
+     * @see StrictMath#floorDiv(long, int)
+     * @since 9
+     */
+    public static int floorMod(long x, int y) {
+        return Math.floorMod(x , y);
+    }
+
     /**
      * Returns the floor modulus of the {@code long} arguments.
      * <p>
diff --git a/ojluni/src/main/java/java/lang/System.java b/ojluni/src/main/java/java/lang/System.java
index 352d9ec..4abba4d 100644
--- a/ojluni/src/main/java/java/lang/System.java
+++ b/ojluni/src/main/java/java/lang/System.java
@@ -25,11 +25,9 @@
  */
 package java.lang;
 
-import com.android.icu.util.Icu4cMetadata;
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 import android.system.ErrnoException;
-import android.system.StructPasswd;
 import android.system.StructUtsname;
 import dalvik.system.VMRuntime;
 import java.io.*;
@@ -38,8 +36,8 @@
 import java.util.Locale;
 import java.util.Properties;
 import java.util.PropertyPermission;
+import libcore.icu.ICU;
 import libcore.io.Libcore;
-import libcore.timezone.TimeZoneDataFiles;
 
 import sun.reflect.CallerSensitive;
 import sun.reflect.Reflection;
@@ -982,12 +980,13 @@
 
         p.put("java.vm.version", runtime.vmVersion());
 
+        String userName;
         try {
-            StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
-            p.put("user.name", passwd.pw_name);
+            userName = Libcore.os.getpwuid(Libcore.os.getuid()).pw_name;
         } catch (ErrnoException exception) {
-            throw new AssertionError(exception);
+            userName = "unknown";
         }
+        p.put("user.name", userName);
 
         StructUtsname info = Libcore.os.uname();
         p.put("os.arch", info.machine);
@@ -997,16 +996,9 @@
         p.put("os.version", info.release);
 
         // Android-added: Undocumented properties that exist only on Android.
-        p.put("android.icu.library.version", Icu4cMetadata.getIcuVersion());
-        p.put("android.icu.unicode.version", Icu4cMetadata.getUnicodeVersion());
-        p.put("android.icu.cldr.version", Icu4cMetadata.getCldrVersion());
-
-        // Property override for ICU4J : this is the location of the ICU4C data. This
-        // is prioritized over the properties in ICUConfig.properties. The issue with using
-        // that is that it doesn't play well with jarjar and it needs complicated build rules
-        // to change its default value.
-        String icuDataPath = TimeZoneDataFiles.generateIcuDataPath();
-        p.put("android.icu.impl.ICUBinary.dataPath", icuDataPath);
+        p.put("android.icu.library.version", ICU.getIcuVersion());
+        p.put("android.icu.unicode.version", ICU.getUnicodeVersion());
+        p.put("android.icu.cldr.version", ICU.getCldrVersion());
 
         parsePropertyAssignments(p, specialProperties());
 
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index 699a1ac..3ca106e 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -40,8 +40,6 @@
 import java.util.concurrent.locks.LockSupport;
 import sun.nio.ch.Interruptible;
 import sun.reflect.CallerSensitive;
-import dalvik.system.RuntimeHooks;
-import dalvik.system.ThreadPrioritySetter;
 import dalvik.system.VMStack;
 import libcore.util.EmptyArray;
 
@@ -430,28 +428,27 @@
         }
 
         final int nanosPerMilli = 1000000;
-        long start = System.nanoTime();
-        long duration = (millis * nanosPerMilli) + nanos;
+        final long durationNanos;
+        if (millis >= Long.MAX_VALUE / nanosPerMilli - 1L) {
+          // > 292 years. Avoid overflow by capping it at roughly 292 years.
+          durationNanos = Long.MAX_VALUE;
+        } else {
+          durationNanos = (millis * nanosPerMilli) + nanos;
+        }
+        long startNanos = System.nanoTime();
 
         Object lock = currentThread().lock;
 
-        // The native sleep(...) method actually performs a special type of wait, which may return
-        // early, so loop until sleep duration passes.
+        // The native sleep(...) method actually does a monitor wait, which may return
+        // early, so loop until sleep duration passes. The monitor is only notified when
+        // we exit, which can't happen while we're sleeping.
         synchronized (lock) {
-            while (true) {
+            for (long elapsed = 0L; elapsed < durationNanos;
+                    elapsed = System.nanoTime() - startNanos) {
+                final long remaining = durationNanos - elapsed;
+                millis = remaining / nanosPerMilli;
+                nanos = (int) (remaining % nanosPerMilli);
                 sleep(lock, millis, nanos);
-
-                long now = System.nanoTime();
-                long elapsed = now - start;
-
-                if (elapsed >= duration) {
-                    break;
-                }
-
-                duration -= elapsed;
-                start = now;
-                millis = duration / nanosPerMilli;
-                nanos = (int) (duration % nanosPerMilli);
             }
         }
         // END Android-changed: Implement sleep() methods using a shared native implementation.
@@ -486,10 +483,10 @@
         this.name = name;
 
         Thread parent = currentThread();
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         // SecurityManager security = System.getSecurityManager();
         if (g == null) {
-            // Android-changed: SecurityManager stubbed out on Android
+            // Android-changed: SecurityManager stubbed out on Android.
             /*
             /* Determine if it's an applet or not *
 
@@ -507,7 +504,7 @@
             // }
         }
 
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         /*
         /* checkAccess regardless of whether or not threadgroup is
            explicitly passed in. *
@@ -1246,18 +1243,7 @@
             synchronized(this) {
                 this.priority = newPriority;
                 if (isAlive()) {
-                    // BEGIN Android-added: Customize behavior of Thread.setPriority().
-                    // http://b/139521784
-                    // setPriority0(newPriority);
-                    ThreadPrioritySetter threadPrioritySetter =
-                        RuntimeHooks.getThreadPrioritySetter();
-                    int nativeTid = this.getNativeTid();
-                    if (threadPrioritySetter != null && nativeTid != 0) {
-                        threadPrioritySetter.setPriority(nativeTid, newPriority);
-                    } else {
-                        setPriority0(newPriority);
-                    }
-                    // END Android-added: Customize behavior of Thread.setPriority().
+                    setPriority0(newPriority);
                 }
             }
         }
@@ -1422,6 +1408,8 @@
      *          cleared when this exception is thrown.
      */
     // BEGIN Android-changed: Synchronize on separate lock object not this Thread.
+    // nativePeer and hence isAlive() can change asynchronously, but Thread::Destroy
+    // will always acquire and notify lock after isAlive() changes to false.
     // public final synchronized void join(long millis)
     public final void join(long millis)
     throws InterruptedException {
@@ -1578,7 +1566,7 @@
      * @see        SecurityManager#checkAccess(Thread)
      */
     public final void checkAccess() {
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         // SecurityManager security = System.getSecurityManager();
         // if (security != null) {
         //     security.checkAccess(this);
@@ -1630,7 +1618,7 @@
      */
     @CallerSensitive
     public ClassLoader getContextClassLoader() {
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         /*
         if (contextClassLoader == null)
             return null;
@@ -1666,7 +1654,7 @@
      * @since 1.2
      */
     public void setContextClassLoader(ClassLoader cl) {
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         // SecurityManager sm = System.getSecurityManager();
         // if (sm != null) {
         //     sm.checkPermission(new RuntimePermission("setContextClassLoader"));
@@ -1773,7 +1761,7 @@
      * @since 1.5
      */
     public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         /*
         // check for getStackTrace permission
         SecurityManager security = System.getSecurityManager();
@@ -2097,7 +2085,7 @@
      * @since 1.5
      */
     public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
-        // Android-removed: SecurityManager stubbed out on Android
+        // Android-removed: SecurityManager stubbed out on Android.
         /*
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
@@ -2141,7 +2129,16 @@
         uncaughtExceptionPreHandler = eh;
     }
 
-    /** @hide */
+    /**
+     * Gets an {@link UncaughtExceptionHandler} that will be called before any
+     * returned by {@link #getUncaughtExceptionHandler()}. Can be {@code null} if
+     * was not explicitly set with
+     * {@link #setUncaughtExceptionPreHandler(UncaughtExceptionHandler)}.
+     *
+     * @return the uncaught exception prehandler for this thread
+     *
+     * @hide
+     */
     public static UncaughtExceptionHandler getUncaughtExceptionPreHandler() {
         return uncaughtExceptionPreHandler;
     }
@@ -2340,14 +2337,4 @@
 
     // Android-added: Android specific nativeGetStatus() method.
     private native int nativeGetStatus(boolean hasBeenStarted);
-
-    // BEGIN Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
-    /**
-     * Returns the thread ID of the underlying native thread -- which is different from
-     * the {@link #getId() managed thread ID} -- or 0 if the native thread is not
-     * started or has stopped.
-     */
-    @FastNative
-    private native int getNativeTid();
-    // END Android-added: Customize behavior of Thread.setPriority(). http://b/139521784
 }
diff --git a/ojluni/src/main/java/java/lang/ThreadLocal.java b/ojluni/src/main/java/java/lang/ThreadLocal.java
index c29ce7e..1422044 100644
--- a/ojluni/src/main/java/java/lang/ThreadLocal.java
+++ b/ojluni/src/main/java/java/lang/ThreadLocal.java
@@ -413,7 +413,8 @@
         private Entry getEntry(ThreadLocal<?> key) {
             int i = key.threadLocalHashCode & (table.length - 1);
             Entry e = table[i];
-            if (e != null && e.get() == key)
+            // Android-changed: Use refersTo()
+            if (e != null && e.refersTo(key))
                 return e;
             else
                 return getEntryAfterMiss(key, i, e);
@@ -433,10 +434,10 @@
             int len = tab.length;
 
             while (e != null) {
-                ThreadLocal<?> k = e.get();
-                if (k == key)
+                // Android-changed: Use refersTo()
+                if (e.refersTo(key))
                     return e;
-                if (k == null)
+                if (e.refersTo(null))
                     expungeStaleEntry(i);
                 else
                     i = nextIndex(i, len);
diff --git a/ojluni/src/main/java/java/lang/Throwable.java b/ojluni/src/main/java/java/lang/Throwable.java
index 5a3f8a8..7596681 100644
--- a/ojluni/src/main/java/java/lang/Throwable.java
+++ b/ojluni/src/main/java/java/lang/Throwable.java
@@ -155,7 +155,7 @@
             new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
     }
 
-    // Android-removed: Use libcore.util.EmptyArray for the empty stack trace
+    // 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.
@@ -211,11 +211,11 @@
      * @serial
      * @since 1.4
      */
-    // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+    // 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
+    // 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
@@ -234,7 +234,7 @@
      * @serial
      * @since 1.7
      */
-    // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL.
     // private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
     private List<Throwable> suppressedExceptions = Collections.emptyList();
 
@@ -689,7 +689,7 @@
                                          String caption,
                                          String prefix,
                                          Set<Throwable> dejaVu) {
-        // Android-removed: Use of assert keyword which breaks serialization of some subclasses
+        // 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)) {
@@ -794,17 +794,17 @@
     public synchronized Throwable fillInStackTrace() {
         if (stackTrace != null ||
             backtrace != null /* Out of protocol state */ ) {
-            // Android-changed: Use Android-specific nativeFillInStackTrace
+            // Android-changed: Use Android-specific nativeFillInStackTrace.
             // fillInStackTrace(0);
             backtrace = nativeFillInStackTrace();
-            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // 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
+    // Android-changed: Use Android-specific nativeFillInStackTrace.
     // private native Throwable fillInStackTrace(int dummy);
     @FastNative
     private static native Object nativeFillInStackTrace();
@@ -840,11 +840,11 @@
     private synchronized StackTraceElement[] getOurStackTrace() {
         // Initialize stack trace field with information from
         // backtrace if this is the first call to this method
-        // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+        // 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
+            // BEGIN Android-changed: Use Android-specific nativeGetStackTrace.
             // int depth = getStackTraceDepth();
             // stackTrace = new StackTraceElement[depth];
             // for (int i=0; i < depth; i++)
@@ -854,9 +854,9 @@
             if (stackTrace == null) {
                 return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
             }
-            // END Android-changed: Use Android-specific nativeGetStackTrace
+            // END Android-changed: Use Android-specific nativeGetStackTrace.
         } else if (stackTrace == null) {
-            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace.
             // return UNASSIGNED_STACK;
             return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
         }
@@ -907,7 +907,7 @@
         }
     }
 
-    // Android-removed: Unused native method getStackTraceDepth()
+    // Android-removed: Unused native method getStackTraceDepth().
     // /**
     //  * Returns the number of elements in the stack trace (or 0 if the stack
     //  * trace is unavailable).
@@ -925,7 +925,7 @@
      * @throws IndexOutOfBoundsException if {@code index < 0 ||
      *         index >= getStackTraceDepth() }
      */
-    // Android-changed: Use Android-specific nativeGetStackTrace
+    // Android-changed: Use Android-specific nativeGetStackTrace.
     // native StackTraceElement getStackTraceElement(int index);
     @FastNative
     private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
@@ -953,7 +953,7 @@
             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
+                // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL.
                 // suppressed = SUPPRESSED_SENTINEL;
                 suppressed = Collections.emptyList();
             } else { // Copy Throwables to new list
@@ -982,7 +982,7 @@
          */
         if (stackTrace != null) {
             if (stackTrace.length == 0) {
-                // Android-removed: clone() call not needed because of libcore.util.EmptyArray usage
+                // Android-removed: clone() call unneeded because of libcore.util.EmptyArray usage.
                 // stackTrace = UNASSIGNED_STACK.clone();
             }  else if (stackTrace.length == 1 &&
                         // Check for the marker of an immutable stack trace
@@ -999,7 +999,7 @@
             // 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
+            // Android-changed: Directly create empty array instead of cloning UNASSIGNED_STACK.
             // stackTrace = UNASSIGNED_STACK.clone();
             stackTrace = new StackTraceElement[0];
         }
@@ -1090,7 +1090,7 @@
         if (suppressedExceptions == null) // Suppressed exceptions not recorded
             return;
 
-        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL.
         // if (suppressedExceptions == SUPPRESSED_SENTINEL)
         if (suppressedExceptions.isEmpty())
             suppressedExceptions = new ArrayList<>(1);
@@ -1098,7 +1098,7 @@
         suppressedExceptions.add(exception);
     }
 
-    // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY
+    // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY.
     // private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
     private static Throwable[] EMPTY_THROWABLE_ARRAY;
 
@@ -1118,12 +1118,12 @@
      * @since 1.7
      */
     public final synchronized Throwable[] getSuppressed() {
-        // Android-added: Lazily initialize EMPTY_THROWABLE_ARRAY
+        // 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
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL.
         // if (suppressedExceptions == SUPPRESSED_SENTINEL ||
         //    suppressedExceptions == null)
         if (suppressedExceptions == null || suppressedExceptions.isEmpty())
diff --git a/ojluni/src/main/java/java/lang/annotation/Annotation.java b/ojluni/src/main/java/java/lang/annotation/Annotation.java
index 7de6746..efa0246 100644
--- a/ojluni/src/main/java/java/lang/annotation/Annotation.java
+++ b/ojluni/src/main/java/java/lang/annotation/Annotation.java
@@ -50,28 +50,28 @@
      * to the corresponding member of this annotation, as defined below:
      * <ul>
      *    <li>Two corresponding primitive typed members whose values are
-     *    <tt>x</tt> and <tt>y</tt> are considered equal if <tt>x == y</tt>,
-     *    unless their type is <tt>float</tt> or <tt>double</tt>.
+     *    {@code x} and {@code y} are considered equal if {@code x == y},
+     *    unless their type is {@code float} or {@code double}.
      *
-     *    <li>Two corresponding <tt>float</tt> members whose values
-     *    are <tt>x</tt> and <tt>y</tt> are considered equal if
-     *    <tt>Float.valueOf(x).equals(Float.valueOf(y))</tt>.
-     *    (Unlike the <tt>==</tt> operator, NaN is considered equal
-     *    to itself, and <tt>0.0f</tt> unequal to <tt>-0.0f</tt>.)
+     *    <li>Two corresponding {@code float} members whose values
+     *    are {@code x} and {@code y} are considered equal if
+     *    {@code Float.valueOf(x).equals(Float.valueOf(y))}.
+     *    (Unlike the {@code ==} operator, NaN is considered equal
+     *    to itself, and {@code 0.0f} unequal to {@code -0.0f}.)
      *
-     *    <li>Two corresponding <tt>double</tt> members whose values
-     *    are <tt>x</tt> and <tt>y</tt> are considered equal if
-     *    <tt>Double.valueOf(x).equals(Double.valueOf(y))</tt>.
-     *    (Unlike the <tt>==</tt> operator, NaN is considered equal
-     *    to itself, and <tt>0.0</tt> unequal to <tt>-0.0</tt>.)
+     *    <li>Two corresponding {@code double} members whose values
+     *    are {@code x} and {@code y} are considered equal if
+     *    {@code Double.valueOf(x).equals(Double.valueOf(y))}.
+     *    (Unlike the {@code ==} operator, NaN is considered equal
+     *    to itself, and {@code 0.0} unequal to {@code -0.0}.)
      *
-     *    <li>Two corresponding <tt>String</tt>, <tt>Class</tt>, enum, or
-     *    annotation typed members whose values are <tt>x</tt> and <tt>y</tt>
-     *    are considered equal if <tt>x.equals(y)</tt>.  (Note that this
+     *    <li>Two corresponding {@code String}, {@code Class}, enum, or
+     *    annotation typed members whose values are {@code x} and {@code y}
+     *    are considered equal if {@code x.equals(y)}.  (Note that this
      *    definition is recursive for annotation typed members.)
      *
-     *    <li>Two corresponding array typed members <tt>x</tt> and <tt>y</tt>
-     *    are considered equal if <tt>Arrays.equals(x, y)</tt>, for the
+     *    <li>Two corresponding array typed members {@code x} and {@code y}
+     *    are considered equal if {@code Arrays.equals(x, y)}, for the
      *    appropriate overloading of {@link java.util.Arrays#equals}.
      * </ul>
      *
@@ -93,16 +93,16 @@
      *
      * <p>The hash code of a member-value depends on its type:
      * <ul>
-     * <li>The hash code of a primitive value <tt><i>v</i></tt> is equal to
-     *     <tt><i>WrapperType</i>.valueOf(<i>v</i>).hashCode()</tt>, where
-     *     <tt><i>WrapperType</i></tt> is the wrapper type corresponding
-     *     to the primitive type of <tt><i>v</i></tt> ({@link Byte},
+     * <li>The hash code of a primitive value <i>{@code v}</i> is equal to
+     *     <code><i>WrapperType</i>.valueOf(<i>v</i>).hashCode()</code>, where
+     *     <i>{@code WrapperType}</i> is the wrapper type corresponding
+     *     to the primitive type of <i>{@code v}</i> ({@link Byte},
      *     {@link Character}, {@link Double}, {@link Float}, {@link Integer},
      *     {@link Long}, {@link Short}, or {@link Boolean}).
      *
      * <li>The hash code of a string, enum, class, or annotation member-value
-     I     <tt><i>v</i></tt> is computed as by calling
-     *     <tt><i>v</i>.hashCode()</tt>.  (In the case of annotation
+     I     <i>{@code v}</i> is computed as by calling
+     *     <code><i>v</i>.hashCode()</code>.  (In the case of annotation
      *     member values, this is a recursive definition.)
      *
      * <li>The hash code of an array member-value is computed by calling
diff --git a/ojluni/src/main/java/java/lang/annotation/AnnotationFormatError.java b/ojluni/src/main/java/java/lang/annotation/AnnotationFormatError.java
index f02104f..c296ced 100644
--- a/ojluni/src/main/java/java/lang/annotation/AnnotationFormatError.java
+++ b/ojluni/src/main/java/java/lang/annotation/AnnotationFormatError.java
@@ -40,7 +40,7 @@
     private static final long serialVersionUID = -4256701562333669892L;
 
     /**
-     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * Constructs a new {@code AnnotationFormatError} with the specified
      * detail message.
      *
      * @param   message   the detail message.
@@ -50,13 +50,13 @@
     }
 
     /**
-     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * Constructs a new {@code AnnotationFormatError} with the specified
      * detail message and cause.  Note that the detail message associated
-     * with <code>cause</code> is <i>not</i> automatically incorporated in
+     * with {@code cause} is <i>not</i> automatically incorporated in
      * this error's detail message.
      *
      * @param  message the detail message
-     * @param  cause the cause (A <tt>null</tt> value is permitted, and
+     * @param  cause the cause (A {@code null} value is permitted, and
      *     indicates that the cause is nonexistent or unknown.)
      */
     public AnnotationFormatError(String message, Throwable cause) {
@@ -65,12 +65,12 @@
 
 
     /**
-     * Constructs a new <tt>AnnotationFormatError</tt> with the specified
+     * Constructs a new {@code AnnotationFormatError} with the specified
      * cause and a detail message of
-     * <tt>(cause == null ? null : cause.toString())</tt> (which
-     * typically contains the class and detail message of <tt>cause</tt>).
+     * {@code (cause == null ? null : cause.toString())} (which
+     * typically contains the class and detail message of {@code cause}).
      *
-     * @param  cause the cause (A <tt>null</tt> value is permitted, and
+     * @param  cause the cause (A {@code null} value is permitted, and
      *     indicates that the cause is nonexistent or unknown.)
      */
     public AnnotationFormatError(Throwable cause) {
diff --git a/ojluni/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java b/ojluni/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
index 88e2712..5152da2 100644
--- a/ojluni/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
+++ b/ojluni/src/main/java/java/lang/annotation/AnnotationTypeMismatchException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,9 +42,9 @@
     private static final long serialVersionUID = 8125925355765570191L;
 
     /**
-     * The <tt>Method</tt> object for the annotation element.
+     * The {@code Method} object for the annotation element.
      */
-    private final Method element;
+    private final transient Method element;
 
     /**
      * The (erroneous) type of data found in the annotation.  This string
@@ -57,10 +57,12 @@
      * Constructs an AnnotationTypeMismatchException for the specified
      * annotation type element and found data type.
      *
-     * @param element the <tt>Method</tt> object for the annotation element
+     * @param element the {@code Method} object for the annotation
+     * element, may be {@code null}
      * @param foundType the (erroneous) type of data found in the annotation.
      *        This string may, but is not required to, contain the value
-     *        as well.  The exact format of the string is unspecified.
+     *        as well.  The exact format of the string is unspecified,
+     *        may be {@code null}.
      */
     public AnnotationTypeMismatchException(Method element, String foundType) {
         super("Incorrectly typed data found for annotation element " + element
@@ -70,9 +72,12 @@
     }
 
     /**
-     * Returns the <tt>Method</tt> object for the incorrectly typed element.
+     * Returns the {@code Method} object for the incorrectly typed element.
+     * The value may be unavailable if this exception has been
+     * serialized and then read back in.
      *
-     * @return the <tt>Method</tt> object for the incorrectly typed element
+     * @return the {@code Method} object for the incorrectly typed
+     * element, or {@code null} if unavailable
      */
     public Method element() {
         return this.element;
@@ -81,7 +86,8 @@
     /**
      * Returns the type of data found in the incorrectly typed element.
      * The returned string may, but is not required to, contain the value
-     * as well.  The exact format of the string is unspecified.
+     * as well.  The exact format of the string is unspecified and the string
+     * may be {@code null}.
      *
      * @return the type of data found in the incorrectly typed element
      */
diff --git a/ojluni/src/main/java/java/lang/annotation/Documented.java b/ojluni/src/main/java/java/lang/annotation/Documented.java
index 348a312..be263c7 100644
--- a/ojluni/src/main/java/java/lang/annotation/Documented.java
+++ b/ojluni/src/main/java/java/lang/annotation/Documented.java
@@ -26,12 +26,24 @@
 package java.lang.annotation;
 
 /**
- * Indicates that annotations with a type are to be documented by javadoc
- * and similar tools by default.  This type should be used to annotate the
- * declarations of types whose annotations affect the use of annotated
- * elements by their clients.  If a type declaration is annotated with
- * Documented, its annotations become part of the public API
- * of the annotated elements.
+ * If the annotation {@code @Documented} is present on the declaration
+ * of an annotation type <i>A</i>, then any {@code @A} annotation on
+ * an element is considered part of the element's public contract.
+ *
+ * In more detail, when an annotation type <i>A</i> is annotated with
+ * {@code Documented}, the presence and value of annotations of type
+ * <i>A</i> are a part of the public contract of the elements <i>A</i>
+ * annotates.
+ *
+ * Conversely, if an annotation type <i>B</i> is <em>not</em>
+ * annotated with {@code Documented}, the presence and value of
+ * <i>B</i> annotations are <em>not</em> part of the public contract
+ * of the elements <i>B</i> annotates.
+ *
+ * Concretely, if an annotation type is annotated with {@code
+ * Documented}, by default a tool like javadoc will display
+ * annotations of that type in its output while annotations of
+ * annotation types without {@code Documented} will not be displayed.
  *
  * @author  Joshua Bloch
  * @since 1.5
diff --git a/ojluni/src/main/java/java/lang/annotation/ElementType.java b/ojluni/src/main/java/java/lang/annotation/ElementType.java
index 4590f39..bbab9cd 100644
--- a/ojluni/src/main/java/java/lang/annotation/ElementType.java
+++ b/ojluni/src/main/java/java/lang/annotation/ElementType.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
@@ -28,7 +28,7 @@
 /**
  * The constants of this enumerated type provide a simple classification of the
  * syntactic locations where annotations may appear in a Java program. These
- * constants are used in {@link Target java.lang.annotation.Target}
+ * constants are used in {@link java.lang.annotation.Target Target}
  * meta-annotations to specify where it is legal to write annotations of a
  * given type.
  *
@@ -37,16 +37,16 @@
  * <em>type contexts</em> , where annotations apply to types used in
  * declarations and expressions.
  *
- * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
- * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
- * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
- * to the declaration contexts in JLS 9.6.4.1.
+ * <p>The constants {@link #ANNOTATION_TYPE}, {@link #CONSTRUCTOR}, {@link
+ * #FIELD}, {@link #LOCAL_VARIABLE}, {@link #METHOD}, {@link #PACKAGE}, {@link
+ * #MODULE}, {@link #PARAMETER}, {@link #TYPE}, and {@link #TYPE_PARAMETER}
+ * correspond to the declaration contexts in JLS 9.6.4.1.
  *
  * <p>For example, an annotation whose type is meta-annotated with
  * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
  * field declaration.
  *
- * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
+ * <p>The constant {@link #TYPE_USE} corresponds to the type contexts in JLS
  * 4.11, as well as to two declaration contexts: type declarations (including
  * annotation type declarations) and type parameter declarations.
  *
@@ -107,5 +107,12 @@
      *
      * @since 1.8
      */
-    TYPE_USE
+    TYPE_USE,
+
+    /**
+     * Module declaration.
+     *
+     * @since 9
+     */
+    MODULE
 }
diff --git a/ojluni/src/main/java/java/lang/annotation/Inherited.java b/ojluni/src/main/java/java/lang/annotation/Inherited.java
index 83391e2..9b4080c 100644
--- a/ojluni/src/main/java/java/lang/annotation/Inherited.java
+++ b/ojluni/src/main/java/java/lang/annotation/Inherited.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -44,7 +44,7 @@
  *
  * @author  Joshua Bloch
  * @since 1.5
- * @jls 9.6.3.3 @Inherited
+ * @jls 9.6.4.3 @Inherited
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/ojluni/src/main/java/java/lang/annotation/Repeatable.java b/ojluni/src/main/java/java/lang/annotation/Repeatable.java
index 7a2daa8..f9dc170 100644
--- a/ojluni/src/main/java/java/lang/annotation/Repeatable.java
+++ b/ojluni/src/main/java/java/lang/annotation/Repeatable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -33,8 +33,8 @@
  * type</em> for the repeatable annotation type.
  *
  * @since 1.8
- * @jls 9.6 Annotation Types
- * @jls 9.7 Annotations
+ * @jls 9.6.3 Repeatable Annotation Types
+ * @jls 9.7.5 Multiple Annotations of the Same Type
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/ojluni/src/main/java/java/lang/annotation/Retention.java b/ojluni/src/main/java/java/lang/annotation/Retention.java
index 5efa43f..6c2a604 100644
--- a/ojluni/src/main/java/java/lang/annotation/Retention.java
+++ b/ojluni/src/main/java/java/lang/annotation/Retention.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -38,7 +38,7 @@
  *
  * @author  Joshua Bloch
  * @since 1.5
- * @jls 9.6.3.2 @Retention
+ * @jls 9.6.4.2 @Retention
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/ojluni/src/main/java/java/lang/annotation/Target.java b/ojluni/src/main/java/java/lang/annotation/Target.java
index 1ad4056..fabb062 100644
--- a/ojluni/src/main/java/java/lang/annotation/Target.java
+++ b/ojluni/src/main/java/java/lang/annotation/Target.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -72,6 +72,7 @@
  * @since 1.5
  * @jls 9.6.4.1 @Target
  * @jls 9.7.4 Where Annotations May Appear
+ * @jls 9.7.5 Multiple Annotations of the Same Type
  */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
diff --git a/ojluni/src/main/java/java/lang/invoke/CallSite.java b/ojluni/src/main/java/java/lang/invoke/CallSite.java
index 85b4bb9..069b2fd 100644
--- a/ojluni/src/main/java/java/lang/invoke/CallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/CallSite.java
@@ -25,7 +25,7 @@
 
 package java.lang.invoke;
 
-// Android-changed: Not using Empty
+// Android-changed: Not using Empty.
 //import sun.invoke.empty.Empty;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
@@ -104,9 +104,10 @@
      */
     /*package-private*/
     CallSite(MethodType type) {
-        // Android-changed: No cache for these so create uninitializedCallSite target here using
-        // method handle transformations to create a method handle that has the expected method
-        // type but throws an IllegalStateException.
+        // Android-changed: No cache for these.
+        // Instead create uninitializedCallSite target here using method handle transformations
+        // to create a method handle that has the expected method type but throws an
+        // IllegalStateException.
         // target = makeUninitializedCallSite(type);
         this.target = MethodHandles.throwException(type.returnType(), IllegalStateException.class);
         this.target = MethodHandles.insertArguments(
@@ -115,8 +116,7 @@
             this.target = MethodHandles.dropArguments(this.target, 0, type.ptypes());
         }
 
-        // Android-changed: Using initializer method for GET_TARGET
-        // rather than complex static initializer.
+        // Android-changed: Using initializer method for GET_TARGET instead of static initializer.
         initializeGetTarget();
     }
 
@@ -130,8 +130,7 @@
         target.type();  // null check
         this.target = target;
 
-        // Android-changed: Using initializer method for GET_TARGET
-        // rather than complex static initializer.
+        // Android-changed: Using initializer method for GET_TARGET instead of static initializer.
         initializeGetTarget();
     }
 
@@ -153,8 +152,7 @@
         checkTargetChange(this.target, boundTarget);
         this.target = boundTarget;
 
-        // Android-changed: Using initializer method for GET_TARGET
-        // rather than complex static initializer.
+        // Android-changed: Using initializer method for GET_TARGET instead of static initializer.
         initializeGetTarget();
     }
 
@@ -244,9 +242,9 @@
     private static MethodHandle GET_TARGET = null;
 
     private void initializeGetTarget() {
-        // Android-changed: moved from static initializer for
-        // GET_TARGET to avoid issues with running early. Called from
-        // constructors. CallSite creation is not performance critical.
+        // Android-changed: moved from static initializer for GET_TARGET.
+        // This avoids issues with running early. Called from constructors.
+        // CallSite creation is not performance critical.
         synchronized (CallSite.class) {
             if (GET_TARGET == null) {
                 try {
diff --git a/ojluni/src/main/java/java/lang/ref/Reference.java b/ojluni/src/main/java/java/lang/ref/Reference.java
index e5126b5..faaddd7 100644
--- a/ojluni/src/main/java/java/lang/ref/Reference.java
+++ b/ojluni/src/main/java/java/lang/ref/Reference.java
@@ -42,6 +42,7 @@
 public abstract class Reference<T> {
     // BEGIN Android-changed: Reimplemented to accommodate a different GC and compiler.
     // ClassLinker knows about the fields of this class.
+    // Backported refersTo() from OpenJDK 16.
 
     /**
      * Forces JNI path.
@@ -56,11 +57,16 @@
      * Used by the reference processor to determine whether or not the referent
      * can be immediately returned. Because the referent might get swept during
      * GC, the slow path, which passes through JNI, must be taken.
+     * This is only modified with mutators suspended, and hence does not need to
+     * be volatile.
      */
     private static boolean slowPathEnabled = false;
 
     // Treated specially by GC. ART's ClassLinker::LinkFields() knows this is the
     // alphabetically last non-static field.
+    // We assume that Reference.get() and Reference.clear() are intended to be
+    // callable concurrently, and thus referent accesses should be treated as
+    // volatile everywhere.
     volatile T referent;
 
     final ReferenceQueue<? super T> queue;
@@ -108,6 +114,23 @@
     private final native T getReferent();
 
     /**
+     * Tests if the referent of this reference object is {@code obj}.
+     * Using a {@code null} {@code obj} returns {@code true} if the
+     * reference object has been cleared.
+     *
+     * @param  obj the object to compare with this reference object's referent
+     * @return {@code true} if {@code obj} is the referent of this reference object
+     * @hide
+     */
+    public final boolean refersTo(T obj) {
+        return refersTo0(obj);
+    }
+
+    /* Implementation of refersTo(). */
+    @FastNative
+    private final native boolean refersTo0(Object o);
+
+    /**
      * Clears this reference object.  Invoking this method will not cause this
      * object to be enqueued.
      *
@@ -125,15 +148,38 @@
 
     /* -- Queue operations -- */
 
+    // Android-changed: deprecate since 9.
+    // @Deprecated(since="16")
     /**
-     * Tells whether or not this reference object has been enqueued, either by
-     * the program or by the garbage collector.  If this reference object was
-     * not registered with a queue when it was created, then this method will
-     * always return <code>false</code>.
+     * Tests if this reference object is in its associated queue, if any.
+     * This method returns {@code true} only if all of the following conditions
+     * are met:
+     * <ul>
+     * <li>this reference object was registered with a queue when it was created; and
+     * <li>the garbage collector has added this reference object to the queue
+     *     or {@link #enqueue()} is called; and
+     * <li>this reference object is not yet removed from the queue.
+     * </ul>
+     * Otherwise, this method returns {@code false}.
+     * This method may return {@code false} if this reference object has been cleared
+     * but not enqueued due to the race condition.
      *
-     * @return   <code>true</code> if and only if this reference object has
-     *           been enqueued
+     * @deprecated
+     * This method was never implemented to test if a reference object has
+     * been cleared and enqueued as it was previously specified since 1.2.
+     * This method could be misused due to the inherent race condition
+     * or without an associated {@code ReferenceQueue}.
+     * An application relying on this method to release critical resources
+     * could cause serious performance issue.
+     * An application should use {@link ReferenceQueue} to reliably determine
+     * what reference objects that have been enqueued or
+     * {@code refersTo(null)} to determine if this reference
+     * object has been cleared.
+     *
+     * @return   {@code true} if and only if this reference object is
+     *           in its associated queue (if any).
      */
+    @Deprecated(since="9")
     public boolean isEnqueued() {
         // Contrary to what the documentation says, this method returns false
         // after this reference object has been removed from its queue
diff --git a/ojluni/src/main/java/java/lang/reflect/AccessibleObject.java b/ojluni/src/main/java/java/lang/reflect/AccessibleObject.java
index 18442fa..2ba6276 100644
--- a/ojluni/src/main/java/java/lang/reflect/AccessibleObject.java
+++ b/ojluni/src/main/java/java/lang/reflect/AccessibleObject.java
@@ -146,7 +146,7 @@
             // }
 
             Class<?> clazz = c.getDeclaringClass();
-            if (c.getDeclaringClass() == Class.class) {
+            if (clazz == Class.class) {
                 throw new SecurityException("Can not make a java.lang.Class" +
                                             " constructor accessible");
             } else if (clazz == Method.class) {
diff --git a/ojluni/src/main/java/java/lang/reflect/Array.java b/ojluni/src/main/java/java/lang/reflect/Array.java
index 95a8091..db7e9a2 100644
--- a/ojluni/src/main/java/java/lang/reflect/Array.java
+++ b/ojluni/src/main/java/java/lang/reflect/Array.java
@@ -111,7 +111,7 @@
      */
     public static Object newInstance(Class<?> componentType, int... dimensions)
         throws IllegalArgumentException, NegativeArraySizeException {
-        // Android-changed: New implementation of newInstance(Class, int...)
+        // Android-changed: New implementation of newInstance(Class, int...).
         if (dimensions.length <= 0 || dimensions.length > 255) {
             throw new IllegalArgumentException("Bad number of dimensions: " + dimensions.length);
         }
@@ -132,7 +132,7 @@
      * @exception IllegalArgumentException if the object argument is not
      * an array
      */
-    // Android-changed: Non-native implementation of getLength(Object)
+    // Android-changed: Non-native implementation of getLength(Object).
     // Android-changed: Removal of explicit throws IllegalArgumentException from method signature.
     public static int getLength(Object array)
         /* throws IllegalArgumentException */ {
@@ -174,7 +174,7 @@
      * argument is negative, or if it is greater than or equal to the
      * length of the specified array
      */
-    // Android-changed: Non-native implementation of get(Object, int)
+    // Android-changed: Non-native implementation of get(Object, int).
     public static Object get(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof Object[]) {
@@ -226,7 +226,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getBoolean(Object, int)
+    // Android-changed: Non-native implementation of getBoolean(Object, int).
     public static boolean getBoolean(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof boolean[]) {
@@ -251,7 +251,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getByte(Object, int)
+    // Android-changed: Non-native implementation of getByte(Object, int).
     public static byte getByte(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof byte[]) {
@@ -276,7 +276,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getChar(Object, int)
+    // Android-changed: Non-native implementation of getChar(Object, int).
     public static char getChar(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof char[]) {
@@ -301,7 +301,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getShort(Object, int)
+    // Android-changed: Non-native implementation of getShort(Object, int).
     public static short getShort(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof short[]) {
@@ -328,7 +328,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getInt(Object, int)
+    // Android-changed: Non-native implementation of getInt(Object, int).
     public static int getInt(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof int[]) {
@@ -359,7 +359,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getLong(Object, int)
+    // Android-changed: Non-native implementation of getLong(Object, int).
     public static long getLong(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof long[]) {
@@ -392,7 +392,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getFloat(Object, int)
+    // Android-changed: Non-native implementation of getFloat(Object, int).
     public static float getFloat(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof float[]) {
@@ -427,7 +427,7 @@
      * length of the specified array
      * @see Array#get
      */
-    // Android-changed: Non-native implementation of getDouble(Object, int)
+    // Android-changed: Non-native implementation of getDouble(Object, int).
     public static double getDouble(Object array, int index)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof double[]) {
@@ -465,7 +465,7 @@
      * argument is negative, or if it is greater than or equal to
      * the length of the specified array
      */
-    // Android-changed: Non-native implementation of set(Object, int, Object)
+    // Android-changed: Non-native implementation of set(Object, int, Object).
     public static void set(Object array, int index, Object value)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (!array.getClass().isArray()) {
@@ -518,8 +518,8 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setBoolean(Object, int, boolean)
-    // Android-changed: Removal of explicit runtime exceptions throws clause
+    // Android-changed: Non-native implementation of setBoolean(Object, int, boolean).
+    // Android-changed: Removal of explicit runtime exceptions throws clause.
     public static void setBoolean(Object array, int index, boolean z)
         /* throws IllegalArgumentException, ArrayIndexOutOfBoundsException */ {
         if (array instanceof boolean[]) {
@@ -546,7 +546,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setByte(Object, int, byte)
+    // Android-changed: Non-native implementation of setByte(Object, int, byte).
     public static void setByte(Object array, int index, byte b)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof byte[]) {
@@ -583,7 +583,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setChar(Object, int, char)
+    // Android-changed: Non-native implementation of setChar(Object, int, char).
     public static void setChar(Object array, int index, char c)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof char[]) {
@@ -618,7 +618,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setShort(Object, int, short)
+    // Android-changed: Non-native implementation of setShort(Object, int, short).
     public static void setShort(Object array, int index, short s)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof short[]) {
@@ -653,7 +653,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setInt(Object, int, int)
+    // Android-changed: Non-native implementation of setInt(Object, int, int).
     public static void setInt(Object array, int index, int i)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof int[]) {
@@ -686,7 +686,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setBoolean(Object, int, long)
+    // Android-changed: Non-native implementation of setBoolean(Object, int, long).
     public static void setLong(Object array, int index, long l)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof long[]) {
@@ -745,7 +745,7 @@
      * the length of the specified array
      * @see Array#set
      */
-    // Android-changed: Non-native implementation of setDouble(Object, int, double)
+    // Android-changed: Non-native implementation of setDouble(Object, int, double).
     public static void setDouble(Object array, int index, double d)
         throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
         if (array instanceof double[]) {
@@ -759,7 +759,7 @@
      * Private
      */
 
-    // Android-added: Added javadocs for newArray(Class, int)
+    // Android-added: Added javadocs for newArray(Class, int).
     /**
      * Returns a new array of the specified component type and length.
      * Equivalent to {@code new componentType[size]}.
@@ -769,7 +769,7 @@
      * @throws NegativeArraySizeException
      *             if {@code size < 0}
      */
-    // Android-changed: Non-native implementation of newArray(Class, int)
+    // Android-changed: Non-native implementation of newArray(Class, int).
     private static Object newArray(Class<?> componentType, int length)
         throws NegativeArraySizeException {
         if (!componentType.isPrimitive()) {
@@ -803,7 +803,7 @@
         throws IllegalArgumentException, NegativeArraySizeException;
     */
 
-    // Android-added: createMultiArray(Class, int[]) method. Used instead of multiNewArray
+    // Android-added: createMultiArray(Class, int[]) method. Used instead of multiNewArray.
     /*
      * Create a multi-dimensional array of objects with the specified type.
      */
diff --git a/ojluni/src/main/java/java/math/BigDecimal.java b/ojluni/src/main/java/java/math/BigDecimal.java
new file mode 100644
index 0000000..9e012a6
--- /dev/null
+++ b/ojluni/src/main/java/java/math/BigDecimal.java
@@ -0,0 +1,5285 @@
+/*
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
+ */
+
+package java.math;
+
+import static java.math.BigInteger.LONG_MASK;
+import java.util.Arrays;
+
+/**
+ * Immutable, arbitrary-precision signed decimal numbers.  A
+ * {@code BigDecimal} consists of an arbitrary precision integer
+ * <i>unscaled value</i> and a 32-bit integer <i>scale</i>.  If zero
+ * or positive, the scale is the number of digits to the right of the
+ * decimal point.  If negative, the unscaled value of the number is
+ * multiplied by ten to the power of the negation of the scale.  The
+ * value of the number represented by the {@code BigDecimal} is
+ * therefore <tt>(unscaledValue &times; 10<sup>-scale</sup>)</tt>.
+ *
+ * <p>The {@code BigDecimal} class provides operations for
+ * arithmetic, scale manipulation, rounding, comparison, hashing, and
+ * format conversion.  The {@link #toString} method provides a
+ * canonical representation of a {@code BigDecimal}.
+ *
+ * <p>The {@code BigDecimal} class gives its user complete control
+ * over rounding behavior.  If no rounding mode is specified and the
+ * exact result cannot be represented, an exception is thrown;
+ * otherwise, calculations can be carried out to a chosen precision
+ * and rounding mode by supplying an appropriate {@link MathContext}
+ * object to the operation.  In either case, eight <em>rounding
+ * modes</em> are provided for the control of rounding.  Using the
+ * integer fields in this class (such as {@link #ROUND_HALF_UP}) to
+ * represent rounding mode is largely obsolete; the enumeration values
+ * of the {@code RoundingMode} {@code enum}, (such as {@link
+ * RoundingMode#HALF_UP}) should be used instead.
+ *
+ * <p>When a {@code MathContext} object is supplied with a precision
+ * setting of 0 (for example, {@link MathContext#UNLIMITED}),
+ * arithmetic operations are exact, as are the arithmetic methods
+ * which take no {@code MathContext} object.  (This is the only
+ * behavior that was supported in releases prior to 5.)  As a
+ * corollary of computing the exact result, the rounding mode setting
+ * of a {@code MathContext} object with a precision setting of 0 is
+ * not used and thus irrelevant.  In the case of divide, the exact
+ * quotient could have an infinitely long decimal expansion; for
+ * example, 1 divided by 3.  If the quotient has a nonterminating
+ * decimal expansion and the operation is specified to return an exact
+ * result, an {@code ArithmeticException} is thrown.  Otherwise, the
+ * exact result of the division is returned, as done for other
+ * operations.
+ *
+ * <p>When the precision setting is not 0, the rules of
+ * {@code BigDecimal} arithmetic are broadly compatible with selected
+ * modes of operation of the arithmetic defined in ANSI X3.274-1996
+ * and ANSI X3.274-1996/AM 1-2000 (section 7.4).  Unlike those
+ * standards, {@code BigDecimal} includes many rounding modes, which
+ * were mandatory for division in {@code BigDecimal} releases prior
+ * to 5.  Any conflicts between these ANSI standards and the
+ * {@code BigDecimal} specification are resolved in favor of
+ * {@code BigDecimal}.
+ *
+ * <p>Since the same numerical value can have different
+ * representations (with different scales), the rules of arithmetic
+ * and rounding must specify both the numerical result and the scale
+ * used in the result's representation.
+ *
+ *
+ * <p>In general the rounding modes and precision setting determine
+ * how operations return results with a limited number of digits when
+ * the exact result has more digits (perhaps infinitely many in the
+ * case of division) than the number of digits returned.
+ *
+ * First, the
+ * total number of digits to return is specified by the
+ * {@code MathContext}'s {@code precision} setting; this determines
+ * the result's <i>precision</i>.  The digit count starts from the
+ * leftmost nonzero digit of the exact result.  The rounding mode
+ * determines how any discarded trailing digits affect the returned
+ * result.
+ *
+ * <p>For all arithmetic operators , the operation is carried out as
+ * though an exact intermediate result were first calculated and then
+ * rounded to the number of digits specified by the precision setting
+ * (if necessary), using the selected rounding mode.  If the exact
+ * result is not returned, some digit positions of the exact result
+ * are discarded.  When rounding increases the magnitude of the
+ * returned result, it is possible for a new digit position to be
+ * created by a carry propagating to a leading {@literal "9"} digit.
+ * For example, rounding the value 999.9 to three digits rounding up
+ * would be numerically equal to one thousand, represented as
+ * 100&times;10<sup>1</sup>.  In such cases, the new {@literal "1"} is
+ * the leading digit position of the returned result.
+ *
+ * <p>Besides a logical exact result, each arithmetic operation has a
+ * preferred scale for representing a result.  The preferred
+ * scale for each operation is listed in the table below.
+ *
+ * <table border>
+ * <caption><b>Preferred Scales for Results of Arithmetic Operations
+ * </b></caption>
+ * <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
+ * <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
+ * <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
+ * <tr><td>Multiply</td><td>multiplier.scale() + multiplicand.scale()</td>
+ * <tr><td>Divide</td><td>dividend.scale() - divisor.scale()</td>
+ * </table>
+ *
+ * These scales are the ones used by the methods which return exact
+ * arithmetic results; except that an exact divide may have to use a
+ * larger scale since the exact result may have more digits.  For
+ * example, {@code 1/32} is {@code 0.03125}.
+ *
+ * <p>Before rounding, the scale of the logical exact intermediate
+ * result is the preferred scale for that operation.  If the exact
+ * numerical result cannot be represented in {@code precision}
+ * digits, rounding selects the set of digits to return and the scale
+ * of the result is reduced from the scale of the intermediate result
+ * to the least scale which can represent the {@code precision}
+ * digits actually returned.  If the exact result can be represented
+ * with at most {@code precision} digits, the representation
+ * of the result with the scale closest to the preferred scale is
+ * returned.  In particular, an exactly representable quotient may be
+ * represented in fewer than {@code precision} digits by removing
+ * trailing zeros and decreasing the scale.  For example, rounding to
+ * three digits using the {@linkplain RoundingMode#FLOOR floor}
+ * rounding mode, <br>
+ *
+ * {@code 19/100 = 0.19   // integer=19,  scale=2} <br>
+ *
+ * but<br>
+ *
+ * {@code 21/110 = 0.190  // integer=190, scale=3} <br>
+ *
+ * <p>Note that for add, subtract, and multiply, the reduction in
+ * scale will equal the number of digit positions of the exact result
+ * which are discarded. If the rounding causes a carry propagation to
+ * create a new high-order digit position, an additional digit of the
+ * result is discarded than when no new digit position is created.
+ *
+ * <p>Other methods may have slightly different rounding semantics.
+ * For example, the result of the {@code pow} method using the
+ * {@linkplain #pow(int, MathContext) specified algorithm} can
+ * occasionally differ from the rounded mathematical result by more
+ * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>.
+ *
+ * <p>Two types of operations are provided for manipulating the scale
+ * of a {@code BigDecimal}: scaling/rounding operations and decimal
+ * point motion operations.  Scaling/rounding operations ({@link
+ * #setScale setScale} and {@link #round round}) return a
+ * {@code BigDecimal} whose value is approximately (or exactly) equal
+ * to that of the operand, but whose scale or precision is the
+ * specified value; that is, they increase or decrease the precision
+ * of the stored number with minimal effect on its value.  Decimal
+ * point motion operations ({@link #movePointLeft movePointLeft} and
+ * {@link #movePointRight movePointRight}) return a
+ * {@code BigDecimal} created from the operand by moving the decimal
+ * point a specified distance in the specified direction.
+ *
+ * <p>For the sake of brevity and clarity, pseudo-code is used
+ * throughout the descriptions of {@code BigDecimal} methods.  The
+ * pseudo-code expression {@code (i + j)} is shorthand for "a
+ * {@code BigDecimal} whose value is that of the {@code BigDecimal}
+ * {@code i} added to that of the {@code BigDecimal}
+ * {@code j}." The pseudo-code expression {@code (i == j)} is
+ * shorthand for "{@code true} if and only if the
+ * {@code BigDecimal} {@code i} represents the same value as the
+ * {@code BigDecimal} {@code j}." Other pseudo-code expressions
+ * are interpreted similarly.  Square brackets are used to represent
+ * the particular {@code BigInteger} and scale pair defining a
+ * {@code BigDecimal} value; for example [19, 2] is the
+ * {@code BigDecimal} numerically equal to 0.19 having a scale of 2.
+ *
+ * <p>Note: care should be exercised if {@code BigDecimal} objects
+ * are used as keys in a {@link java.util.SortedMap SortedMap} or
+ * elements in a {@link java.util.SortedSet SortedSet} since
+ * {@code BigDecimal}'s <i>natural ordering</i> is <i>inconsistent
+ * with equals</i>.  See {@link Comparable}, {@link
+ * java.util.SortedMap} or {@link java.util.SortedSet} for more
+ * information.
+ *
+ * <p>All methods and constructors for this class throw
+ * {@code NullPointerException} when passed a {@code null} object
+ * reference for any input parameter.
+ *
+ * @see     BigInteger
+ * @see     MathContext
+ * @see     RoundingMode
+ * @see     java.util.SortedMap
+ * @see     java.util.SortedSet
+ * @author  Josh Bloch
+ * @author  Mike Cowlishaw
+ * @author  Joseph D. Darcy
+ * @author  Sergey V. Kuksenko
+ */
+public class BigDecimal extends Number implements Comparable<BigDecimal> {
+    /**
+     * The unscaled value of this BigDecimal, as returned by {@link
+     * #unscaledValue}.
+     *
+     * @serial
+     * @see #unscaledValue
+     */
+    private final BigInteger intVal;
+
+    /**
+     * The scale of this BigDecimal, as returned by {@link #scale}.
+     *
+     * @serial
+     * @see #scale
+     */
+    private final int scale;  // Note: this may have any value, so
+                              // calculations must be done in longs
+
+    /**
+     * The number of decimal digits in this BigDecimal, or 0 if the
+     * number of digits are not known (lookaside information).  If
+     * nonzero, the value is guaranteed correct.  Use the precision()
+     * method to obtain and set the value if it might be 0.  This
+     * field is mutable until set nonzero.
+     *
+     * @since  1.5
+     */
+    private transient int precision;
+
+    /**
+     * Used to store the canonical string representation, if computed.
+     */
+    private transient String stringCache;
+
+    /**
+     * Sentinel value for {@link #intCompact} indicating the
+     * significand information is only available from {@code intVal}.
+     */
+    static final long INFLATED = Long.MIN_VALUE;
+
+    private static final BigInteger INFLATED_BIGINT = BigInteger.valueOf(INFLATED);
+
+    /**
+     * If the absolute value of the significand of this BigDecimal is
+     * less than or equal to {@code Long.MAX_VALUE}, the value can be
+     * compactly stored in this field and used in computations.
+     */
+    private final transient long intCompact;
+
+    // All 18-digit base ten strings fit into a long; not all 19-digit
+    // strings will
+    private static final int MAX_COMPACT_DIGITS = 18;
+
+    /* Appease the serialization gods */
+    private static final long serialVersionUID = 6108874887143696463L;
+
+    private static final ThreadLocal<StringBuilderHelper>
+        threadLocalStringBuilderHelper = new ThreadLocal<StringBuilderHelper>() {
+        @Override
+        protected StringBuilderHelper initialValue() {
+            return new StringBuilderHelper();
+        }
+    };
+
+    // Cache of common small BigDecimal values.
+    private static final BigDecimal zeroThroughTen[] = {
+        new BigDecimal(BigInteger.ZERO,       0,  0, 1),
+        new BigDecimal(BigInteger.ONE,        1,  0, 1),
+        new BigDecimal(BigInteger.valueOf(2), 2,  0, 1),
+        new BigDecimal(BigInteger.valueOf(3), 3,  0, 1),
+        new BigDecimal(BigInteger.valueOf(4), 4,  0, 1),
+        new BigDecimal(BigInteger.valueOf(5), 5,  0, 1),
+        new BigDecimal(BigInteger.valueOf(6), 6,  0, 1),
+        new BigDecimal(BigInteger.valueOf(7), 7,  0, 1),
+        new BigDecimal(BigInteger.valueOf(8), 8,  0, 1),
+        new BigDecimal(BigInteger.valueOf(9), 9,  0, 1),
+        new BigDecimal(BigInteger.TEN,        10, 0, 2),
+    };
+
+    // Cache of zero scaled by 0 - 15
+    private static final BigDecimal[] ZERO_SCALED_BY = {
+        zeroThroughTen[0],
+        new BigDecimal(BigInteger.ZERO, 0, 1, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 2, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 3, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 4, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 5, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 6, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 7, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 8, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 9, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 10, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 11, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 12, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 13, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 14, 1),
+        new BigDecimal(BigInteger.ZERO, 0, 15, 1),
+    };
+
+    // Half of Long.MIN_VALUE & Long.MAX_VALUE.
+    private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2;
+    private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2;
+
+    // Constants
+    /**
+     * The value 0, with a scale of 0.
+     *
+     * @since  1.5
+     */
+    public static final BigDecimal ZERO =
+        zeroThroughTen[0];
+
+    /**
+     * The value 1, with a scale of 0.
+     *
+     * @since  1.5
+     */
+    public static final BigDecimal ONE =
+        zeroThroughTen[1];
+
+    /**
+     * The value 10, with a scale of 0.
+     *
+     * @since  1.5
+     */
+    public static final BigDecimal TEN =
+        zeroThroughTen[10];
+
+    // Constructors
+
+    /**
+     * Trusted package private constructor.
+     * Trusted simply means if val is INFLATED, intVal could not be null and
+     * if intVal is null, val could not be INFLATED.
+     */
+    BigDecimal(BigInteger intVal, long val, int scale, int prec) {
+        this.scale = scale;
+        this.precision = prec;
+        this.intCompact = val;
+        this.intVal = intVal;
+    }
+
+    /**
+     * Translates a character array representation of a
+     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
+     * same sequence of characters as the {@link #BigDecimal(String)}
+     * constructor, while allowing a sub-array to be specified.
+     *
+     * <p>Note that if the sequence of characters is already available
+     * within a character array, using this constructor is faster than
+     * converting the {@code char} array to string and using the
+     * {@code BigDecimal(String)} constructor .
+     *
+     * @param  in {@code char} array that is the source of characters.
+     * @param  offset first character in the array to inspect.
+     * @param  len number of characters to consider.
+     * @throws NumberFormatException if {@code in} is not a valid
+     *         representation of a {@code BigDecimal} or the defined subarray
+     *         is not wholly within {@code in}.
+     * @since  1.5
+     */
+    public BigDecimal(char[] in, int offset, int len) {
+        this(in,offset,len,MathContext.UNLIMITED);
+    }
+
+    /**
+     * Translates a character array representation of a
+     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
+     * same sequence of characters as the {@link #BigDecimal(String)}
+     * constructor, while allowing a sub-array to be specified and
+     * with rounding according to the context settings.
+     *
+     * <p>Note that if the sequence of characters is already available
+     * within a character array, using this constructor is faster than
+     * converting the {@code char} array to string and using the
+     * {@code BigDecimal(String)} constructor .
+     *
+     * @param  in {@code char} array that is the source of characters.
+     * @param  offset first character in the array to inspect.
+     * @param  len number of characters to consider..
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @throws NumberFormatException if {@code in} is not a valid
+     *         representation of a {@code BigDecimal} or the defined subarray
+     *         is not wholly within {@code in}.
+     * @since  1.5
+     */
+    public BigDecimal(char[] in, int offset, int len, MathContext mc) {
+        // protect against huge length, negative values, and integer overflow
+        if ((in.length | len | offset) < 0 || len > in.length - offset) {
+            throw new NumberFormatException
+                ("Bad offset or len arguments for char[] input.");
+        }
+
+        // This is the primary string to BigDecimal constructor; all
+        // incoming strings end up here; it uses explicit (inline)
+        // parsing for speed and generates at most one intermediate
+        // (temporary) object (a char[] array) for non-compact case.
+
+        // Use locals for all fields values until completion
+        int prec = 0;                 // record precision value
+        int scl = 0;                  // record scale value
+        long rs = 0;                  // the compact value in long
+        BigInteger rb = null;         // the inflated value in BigInteger
+        // use array bounds checking to handle too-long, len == 0,
+        // bad offset, etc.
+        try {
+            // handle the sign
+            boolean isneg = false;          // assume positive
+            if (in[offset] == '-') {
+                isneg = true;               // leading minus means negative
+                offset++;
+                len--;
+            } else if (in[offset] == '+') { // leading + allowed
+                offset++;
+                len--;
+            }
+
+            // should now be at numeric part of the significand
+            boolean dot = false;             // true when there is a '.'
+            long exp = 0;                    // exponent
+            char c;                          // current character
+            boolean isCompact = (len <= MAX_COMPACT_DIGITS);
+            // integer significand array & idx is the index to it. The array
+            // is ONLY used when we can't use a compact representation.
+            int idx = 0;
+            if (isCompact) {
+                // First compact case, we need not to preserve the character
+                // and we can just compute the value in place.
+                for (; len > 0; offset++, len--) {
+                    c = in[offset];
+                    if ((c == '0')) { // have zero
+                        if (prec == 0)
+                            prec = 1;
+                        else if (rs != 0) {
+                            rs *= 10;
+                            ++prec;
+                        } // else digit is a redundant leading zero
+                        if (dot)
+                            ++scl;
+                    } else if ((c >= '1' && c <= '9')) { // have digit
+                        int digit = c - '0';
+                        if (prec != 1 || rs != 0)
+                            ++prec; // prec unchanged if preceded by 0s
+                        rs = rs * 10 + digit;
+                        if (dot)
+                            ++scl;
+                    } else if (c == '.') {   // have dot
+                        // have dot
+                        if (dot) // two dots
+                            throw new NumberFormatException();
+                        dot = true;
+                    } else if (Character.isDigit(c)) { // slow path
+                        int digit = Character.digit(c, 10);
+                        if (digit == 0) {
+                            if (prec == 0)
+                                prec = 1;
+                            else if (rs != 0) {
+                                rs *= 10;
+                                ++prec;
+                            } // else digit is a redundant leading zero
+                        } else {
+                            if (prec != 1 || rs != 0)
+                                ++prec; // prec unchanged if preceded by 0s
+                            rs = rs * 10 + digit;
+                        }
+                        if (dot)
+                            ++scl;
+                    } else if ((c == 'e') || (c == 'E')) {
+                        exp = parseExp(in, offset, len);
+                        // Next test is required for backwards compatibility
+                        if ((int) exp != exp) // overflow
+                            throw new NumberFormatException();
+                        break; // [saves a test]
+                    } else {
+                        throw new NumberFormatException();
+                    }
+                }
+                if (prec == 0) // no digits found
+                    throw new NumberFormatException();
+                // Adjust scale if exp is not zero.
+                if (exp != 0) { // had significant exponent
+                    scl = adjustScale(scl, exp);
+                }
+                rs = isneg ? -rs : rs;
+                int mcp = mc.precision;
+                int drop = prec - mcp; // prec has range [1, MAX_INT], mcp has range [0, MAX_INT];
+                                       // therefore, this subtract cannot overflow
+                if (mcp > 0 && drop > 0) {  // do rounding
+                    while (drop > 0) {
+                        scl = checkScaleNonZero((long) scl - drop);
+                        rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                        prec = longDigitLength(rs);
+                        drop = prec - mcp;
+                    }
+                }
+            } else {
+                char coeff[] = new char[len];
+                for (; len > 0; offset++, len--) {
+                    c = in[offset];
+                    // have digit
+                    if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
+                        // First compact case, we need not to preserve the character
+                        // and we can just compute the value in place.
+                        if (c == '0' || Character.digit(c, 10) == 0) {
+                            if (prec == 0) {
+                                coeff[idx] = c;
+                                prec = 1;
+                            } else if (idx != 0) {
+                                coeff[idx++] = c;
+                                ++prec;
+                            } // else c must be a redundant leading zero
+                        } else {
+                            if (prec != 1 || idx != 0)
+                                ++prec; // prec unchanged if preceded by 0s
+                            coeff[idx++] = c;
+                        }
+                        if (dot)
+                            ++scl;
+                        continue;
+                    }
+                    // have dot
+                    if (c == '.') {
+                        // have dot
+                        if (dot) // two dots
+                            throw new NumberFormatException();
+                        dot = true;
+                        continue;
+                    }
+                    // exponent expected
+                    if ((c != 'e') && (c != 'E'))
+                        throw new NumberFormatException();
+                    exp = parseExp(in, offset, len);
+                    // Next test is required for backwards compatibility
+                    if ((int) exp != exp) // overflow
+                        throw new NumberFormatException();
+                    break; // [saves a test]
+                }
+                // here when no characters left
+                if (prec == 0) // no digits found
+                    throw new NumberFormatException();
+                // Adjust scale if exp is not zero.
+                if (exp != 0) { // had significant exponent
+                    scl = adjustScale(scl, exp);
+                }
+                // Remove leading zeros from precision (digits count)
+                rb = new BigInteger(coeff, isneg ? -1 : 1, prec);
+                rs = compactValFor(rb);
+                int mcp = mc.precision;
+                if (mcp > 0 && (prec > mcp)) {
+                    if (rs == INFLATED) {
+                        int drop = prec - mcp;
+                        while (drop > 0) {
+                            scl = checkScaleNonZero((long) scl - drop);
+                            rb = divideAndRoundByTenPow(rb, drop, mc.roundingMode.oldMode);
+                            rs = compactValFor(rb);
+                            if (rs != INFLATED) {
+                                prec = longDigitLength(rs);
+                                break;
+                            }
+                            prec = bigDigitLength(rb);
+                            drop = prec - mcp;
+                        }
+                    }
+                    if (rs != INFLATED) {
+                        int drop = prec - mcp;
+                        while (drop > 0) {
+                            scl = checkScaleNonZero((long) scl - drop);
+                            rs = divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                            prec = longDigitLength(rs);
+                            drop = prec - mcp;
+                        }
+                        rb = null;
+                    }
+                }
+            }
+        } catch (ArrayIndexOutOfBoundsException e) {
+            throw new NumberFormatException();
+        } catch (NegativeArraySizeException e) {
+            throw new NumberFormatException();
+        }
+        this.scale = scl;
+        this.precision = prec;
+        this.intCompact = rs;
+        this.intVal = rb;
+    }
+
+    private int adjustScale(int scl, long exp) {
+        long adjustedScale = scl - exp;
+        if (adjustedScale > Integer.MAX_VALUE || adjustedScale < Integer.MIN_VALUE)
+            throw new NumberFormatException("Scale out of range.");
+        scl = (int) adjustedScale;
+        return scl;
+    }
+
+    /*
+     * parse exponent
+     */
+    private static long parseExp(char[] in, int offset, int len){
+        long exp = 0;
+        offset++;
+        char c = in[offset];
+        len--;
+        boolean negexp = (c == '-');
+        // optional sign
+        if (negexp || c == '+') {
+            offset++;
+            c = in[offset];
+            len--;
+        }
+        if (len <= 0) // no exponent digits
+            throw new NumberFormatException();
+        // skip leading zeros in the exponent
+        while (len > 10 && (c=='0' || (Character.digit(c, 10) == 0))) {
+            offset++;
+            c = in[offset];
+            len--;
+        }
+        if (len > 10) // too many nonzero exponent digits
+            throw new NumberFormatException();
+        // c now holds first digit of exponent
+        for (;; len--) {
+            int v;
+            if (c >= '0' && c <= '9') {
+                v = c - '0';
+            } else {
+                v = Character.digit(c, 10);
+                if (v < 0) // not a digit
+                    throw new NumberFormatException();
+            }
+            exp = exp * 10 + v;
+            if (len == 1)
+                break; // that was final character
+            offset++;
+            c = in[offset];
+        }
+        if (negexp) // apply sign
+            exp = -exp;
+        return exp;
+    }
+
+    /**
+     * Translates a character array representation of a
+     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
+     * same sequence of characters as the {@link #BigDecimal(String)}
+     * constructor.
+     *
+     * <p>Note that if the sequence of characters is already available
+     * as a character array, using this constructor is faster than
+     * converting the {@code char} array to string and using the
+     * {@code BigDecimal(String)} constructor .
+     *
+     * @param in {@code char} array that is the source of characters.
+     * @throws NumberFormatException if {@code in} is not a valid
+     *         representation of a {@code BigDecimal}.
+     * @since  1.5
+     */
+    public BigDecimal(char[] in) {
+        this(in, 0, in.length);
+    }
+
+    /**
+     * Translates a character array representation of a
+     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
+     * same sequence of characters as the {@link #BigDecimal(String)}
+     * constructor and with rounding according to the context
+     * settings.
+     *
+     * <p>Note that if the sequence of characters is already available
+     * as a character array, using this constructor is faster than
+     * converting the {@code char} array to string and using the
+     * {@code BigDecimal(String)} constructor .
+     *
+     * @param  in {@code char} array that is the source of characters.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @throws NumberFormatException if {@code in} is not a valid
+     *         representation of a {@code BigDecimal}.
+     * @since  1.5
+     */
+    public BigDecimal(char[] in, MathContext mc) {
+        this(in, 0, in.length, mc);
+    }
+
+    /**
+     * Translates the string representation of a {@code BigDecimal}
+     * into a {@code BigDecimal}.  The string representation consists
+     * of an optional sign, {@code '+'} (<tt> '&#92;u002B'</tt>) or
+     * {@code '-'} (<tt>'&#92;u002D'</tt>), followed by a sequence of
+     * zero or more decimal digits ("the integer"), optionally
+     * followed by a fraction, optionally followed by an exponent.
+     *
+     * <p>The fraction consists of a decimal point followed by zero
+     * or more decimal digits.  The string must contain at least one
+     * digit in either the integer or the fraction.  The number formed
+     * by the sign, the integer and the fraction is referred to as the
+     * <i>significand</i>.
+     *
+     * <p>The exponent consists of the character {@code 'e'}
+     * (<tt>'&#92;u0065'</tt>) or {@code 'E'} (<tt>'&#92;u0045'</tt>)
+     * followed by one or more decimal digits.  The value of the
+     * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
+     * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
+     *
+     * <p>More formally, the strings this constructor accepts are
+     * described by the following grammar:
+     * <blockquote>
+     * <dl>
+     * <dt><i>BigDecimalString:</i>
+     * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
+     * <dt><i>Sign:</i>
+     * <dd>{@code +}
+     * <dd>{@code -}
+     * <dt><i>Significand:</i>
+     * <dd><i>IntegerPart</i> {@code .} <i>FractionPart<sub>opt</sub></i>
+     * <dd>{@code .} <i>FractionPart</i>
+     * <dd><i>IntegerPart</i>
+     * <dt><i>IntegerPart:</i>
+     * <dd><i>Digits</i>
+     * <dt><i>FractionPart:</i>
+     * <dd><i>Digits</i>
+     * <dt><i>Exponent:</i>
+     * <dd><i>ExponentIndicator SignedInteger</i>
+     * <dt><i>ExponentIndicator:</i>
+     * <dd>{@code e}
+     * <dd>{@code E}
+     * <dt><i>SignedInteger:</i>
+     * <dd><i>Sign<sub>opt</sub> Digits</i>
+     * <dt><i>Digits:</i>
+     * <dd><i>Digit</i>
+     * <dd><i>Digits Digit</i>
+     * <dt><i>Digit:</i>
+     * <dd>any character for which {@link Character#isDigit}
+     * returns {@code true}, including 0, 1, 2 ...
+     * </dl>
+     * </blockquote>
+     *
+     * <p>The scale of the returned {@code BigDecimal} will be the
+     * number of digits in the fraction, or zero if the string
+     * contains no decimal point, subject to adjustment for any
+     * exponent; if the string contains an exponent, the exponent is
+     * subtracted from the scale.  The value of the resulting scale
+     * must lie between {@code Integer.MIN_VALUE} and
+     * {@code Integer.MAX_VALUE}, inclusive.
+     *
+     * <p>The character-to-digit mapping is provided by {@link
+     * java.lang.Character#digit} set to convert to radix 10.  The
+     * String may not contain any extraneous characters (whitespace,
+     * for example).
+     *
+     * <p><b>Examples:</b><br>
+     * The value of the returned {@code BigDecimal} is equal to
+     * <i>significand</i> &times; 10<sup>&nbsp;<i>exponent</i></sup>.
+     * For each string on the left, the resulting representation
+     * [{@code BigInteger}, {@code scale}] is shown on the right.
+     * <pre>
+     * "0"            [0,0]
+     * "0.00"         [0,2]
+     * "123"          [123,0]
+     * "-123"         [-123,0]
+     * "1.23E3"       [123,-1]
+     * "1.23E+3"      [123,-1]
+     * "12.3E+7"      [123,-6]
+     * "12.0"         [120,1]
+     * "12.3"         [123,1]
+     * "0.00123"      [123,5]
+     * "-1.23E-12"    [-123,14]
+     * "1234.5E-4"    [12345,5]
+     * "0E+7"         [0,-7]
+     * "-0"           [0,0]
+     * </pre>
+     *
+     * <p>Note: For values other than {@code float} and
+     * {@code double} NaN and &plusmn;Infinity, this constructor is
+     * compatible with the values returned by {@link Float#toString}
+     * and {@link Double#toString}.  This is generally the preferred
+     * way to convert a {@code float} or {@code double} into a
+     * BigDecimal, as it doesn't suffer from the unpredictability of
+     * the {@link #BigDecimal(double)} constructor.
+     *
+     * @param val String representation of {@code BigDecimal}.
+     *
+     * @throws NumberFormatException if {@code val} is not a valid
+     *         representation of a {@code BigDecimal}.
+     */
+    public BigDecimal(String val) {
+        this(val.toCharArray(), 0, val.length());
+    }
+
+    /**
+     * Translates the string representation of a {@code BigDecimal}
+     * into a {@code BigDecimal}, accepting the same strings as the
+     * {@link #BigDecimal(String)} constructor, with rounding
+     * according to the context settings.
+     *
+     * @param  val string representation of a {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @throws NumberFormatException if {@code val} is not a valid
+     *         representation of a BigDecimal.
+     * @since  1.5
+     */
+    public BigDecimal(String val, MathContext mc) {
+        this(val.toCharArray(), 0, val.length(), mc);
+    }
+
+    /**
+     * Translates a {@code double} into a {@code BigDecimal} which
+     * is the exact decimal representation of the {@code double}'s
+     * binary floating-point value.  The scale of the returned
+     * {@code BigDecimal} is the smallest value such that
+     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
+     * <p>
+     * <b>Notes:</b>
+     * <ol>
+     * <li>
+     * The results of this constructor can be somewhat unpredictable.
+     * One might assume that writing {@code new BigDecimal(0.1)} in
+     * Java creates a {@code BigDecimal} which is exactly equal to
+     * 0.1 (an unscaled value of 1, with a scale of 1), but it is
+     * actually equal to
+     * 0.1000000000000000055511151231257827021181583404541015625.
+     * This is because 0.1 cannot be represented exactly as a
+     * {@code double} (or, for that matter, as a binary fraction of
+     * any finite length).  Thus, the value that is being passed
+     * <i>in</i> to the constructor is not exactly equal to 0.1,
+     * appearances notwithstanding.
+     *
+     * <li>
+     * The {@code String} constructor, on the other hand, is
+     * perfectly predictable: writing {@code new BigDecimal("0.1")}
+     * creates a {@code BigDecimal} which is <i>exactly</i> equal to
+     * 0.1, as one would expect.  Therefore, it is generally
+     * recommended that the {@linkplain #BigDecimal(String)
+     * <tt>String</tt> constructor} be used in preference to this one.
+     *
+     * <li>
+     * When a {@code double} must be used as a source for a
+     * {@code BigDecimal}, note that this constructor provides an
+     * exact conversion; it does not give the same result as
+     * converting the {@code double} to a {@code String} using the
+     * {@link Double#toString(double)} method and then using the
+     * {@link #BigDecimal(String)} constructor.  To get that result,
+     * use the {@code static} {@link #valueOf(double)} method.
+     * </ol>
+     *
+     * @param val {@code double} value to be converted to
+     *        {@code BigDecimal}.
+     * @throws NumberFormatException if {@code val} is infinite or NaN.
+     */
+    public BigDecimal(double val) {
+        this(val,MathContext.UNLIMITED);
+    }
+
+    /**
+     * Translates a {@code double} into a {@code BigDecimal}, with
+     * rounding according to the context settings.  The scale of the
+     * {@code BigDecimal} is the smallest value such that
+     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
+     *
+     * <p>The results of this constructor can be somewhat unpredictable
+     * and its use is generally not recommended; see the notes under
+     * the {@link #BigDecimal(double)} constructor.
+     *
+     * @param  val {@code double} value to be converted to
+     *         {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         RoundingMode is UNNECESSARY.
+     * @throws NumberFormatException if {@code val} is infinite or NaN.
+     * @since  1.5
+     */
+    public BigDecimal(double val, MathContext mc) {
+        if (Double.isInfinite(val) || Double.isNaN(val))
+            throw new NumberFormatException("Infinite or NaN");
+        // Translate the double into sign, exponent and significand, according
+        // to the formulae in JLS, Section 20.10.22.
+        long valBits = Double.doubleToLongBits(val);
+        int sign = ((valBits >> 63) == 0 ? 1 : -1);
+        int exponent = (int) ((valBits >> 52) & 0x7ffL);
+        long significand = (exponent == 0
+                ? (valBits & ((1L << 52) - 1)) << 1
+                : (valBits & ((1L << 52) - 1)) | (1L << 52));
+        exponent -= 1075;
+        // At this point, val == sign * significand * 2**exponent.
+
+        /*
+         * Special case zero to suppress nonterminating normalization and bogus
+         * scale calculation.
+         */
+        if (significand == 0) {
+            this.intVal = BigInteger.ZERO;
+            this.scale = 0;
+            this.intCompact = 0;
+            this.precision = 1;
+            return;
+        }
+        // Normalize
+        while ((significand & 1) == 0) { // i.e., significand is even
+            significand >>= 1;
+            exponent++;
+        }
+        int scale = 0;
+        // Calculate intVal and scale
+        BigInteger intVal;
+        long compactVal = sign * significand;
+        if (exponent == 0) {
+            intVal = (compactVal == INFLATED) ? INFLATED_BIGINT : null;
+        } else {
+            if (exponent < 0) {
+                intVal = BigInteger.valueOf(5).pow(-exponent).multiply(compactVal);
+                scale = -exponent;
+            } else { //  (exponent > 0)
+                intVal = BigInteger.valueOf(2).pow(exponent).multiply(compactVal);
+            }
+            compactVal = compactValFor(intVal);
+        }
+        int prec = 0;
+        int mcp = mc.precision;
+        if (mcp > 0) { // do rounding
+            int mode = mc.roundingMode.oldMode;
+            int drop;
+            if (compactVal == INFLATED) {
+                prec = bigDigitLength(intVal);
+                drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    intVal = divideAndRoundByTenPow(intVal, drop, mode);
+                    compactVal = compactValFor(intVal);
+                    if (compactVal != INFLATED) {
+                        break;
+                    }
+                    prec = bigDigitLength(intVal);
+                    drop = prec - mcp;
+                }
+            }
+            if (compactVal != INFLATED) {
+                prec = longDigitLength(compactVal);
+                drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                    prec = longDigitLength(compactVal);
+                    drop = prec - mcp;
+                }
+                intVal = null;
+            }
+        }
+        this.intVal = intVal;
+        this.intCompact = compactVal;
+        this.scale = scale;
+        this.precision = prec;
+    }
+
+    /**
+     * Translates a {@code BigInteger} into a {@code BigDecimal}.
+     * The scale of the {@code BigDecimal} is zero.
+     *
+     * @param val {@code BigInteger} value to be converted to
+     *            {@code BigDecimal}.
+     */
+    public BigDecimal(BigInteger val) {
+        scale = 0;
+        intVal = val;
+        intCompact = compactValFor(val);
+    }
+
+    /**
+     * Translates a {@code BigInteger} into a {@code BigDecimal}
+     * rounding according to the context settings.  The scale of the
+     * {@code BigDecimal} is zero.
+     *
+     * @param val {@code BigInteger} value to be converted to
+     *            {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal(BigInteger val, MathContext mc) {
+        this(val,0,mc);
+    }
+
+    /**
+     * Translates a {@code BigInteger} unscaled value and an
+     * {@code int} scale into a {@code BigDecimal}.  The value of
+     * the {@code BigDecimal} is
+     * <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
+     *
+     * @param unscaledVal unscaled value of the {@code BigDecimal}.
+     * @param scale scale of the {@code BigDecimal}.
+     */
+    public BigDecimal(BigInteger unscaledVal, int scale) {
+        // Negative scales are now allowed
+        this.intVal = unscaledVal;
+        this.intCompact = compactValFor(unscaledVal);
+        this.scale = scale;
+    }
+
+    /**
+     * Translates a {@code BigInteger} unscaled value and an
+     * {@code int} scale into a {@code BigDecimal}, with rounding
+     * according to the context settings.  The value of the
+     * {@code BigDecimal} is <tt>(unscaledVal &times;
+     * 10<sup>-scale</sup>)</tt>, rounded according to the
+     * {@code precision} and rounding mode settings.
+     *
+     * @param  unscaledVal unscaled value of the {@code BigDecimal}.
+     * @param  scale scale of the {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
+        long compactVal = compactValFor(unscaledVal);
+        int mcp = mc.precision;
+        int prec = 0;
+        if (mcp > 0) { // do rounding
+            int mode = mc.roundingMode.oldMode;
+            if (compactVal == INFLATED) {
+                prec = bigDigitLength(unscaledVal);
+                int drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    unscaledVal = divideAndRoundByTenPow(unscaledVal, drop, mode);
+                    compactVal = compactValFor(unscaledVal);
+                    if (compactVal != INFLATED) {
+                        break;
+                    }
+                    prec = bigDigitLength(unscaledVal);
+                    drop = prec - mcp;
+                }
+            }
+            if (compactVal != INFLATED) {
+                prec = longDigitLength(compactVal);
+                int drop = prec - mcp;     // drop can't be more than 18
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mode);
+                    prec = longDigitLength(compactVal);
+                    drop = prec - mcp;
+                }
+                unscaledVal = null;
+            }
+        }
+        this.intVal = unscaledVal;
+        this.intCompact = compactVal;
+        this.scale = scale;
+        this.precision = prec;
+    }
+
+    /**
+     * Translates an {@code int} into a {@code BigDecimal}.  The
+     * scale of the {@code BigDecimal} is zero.
+     *
+     * @param val {@code int} value to be converted to
+     *            {@code BigDecimal}.
+     * @since  1.5
+     */
+    public BigDecimal(int val) {
+        this.intCompact = val;
+        this.scale = 0;
+        this.intVal = null;
+    }
+
+    /**
+     * Translates an {@code int} into a {@code BigDecimal}, with
+     * rounding according to the context settings.  The scale of the
+     * {@code BigDecimal}, before any rounding, is zero.
+     *
+     * @param  val {@code int} value to be converted to {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal(int val, MathContext mc) {
+        int mcp = mc.precision;
+        long compactVal = val;
+        int scale = 0;
+        int prec = 0;
+        if (mcp > 0) { // do rounding
+            prec = longDigitLength(compactVal);
+            int drop = prec - mcp; // drop can't be more than 18
+            while (drop > 0) {
+                scale = checkScaleNonZero((long) scale - drop);
+                compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                prec = longDigitLength(compactVal);
+                drop = prec - mcp;
+            }
+        }
+        this.intVal = null;
+        this.intCompact = compactVal;
+        this.scale = scale;
+        this.precision = prec;
+    }
+
+    /**
+     * Translates a {@code long} into a {@code BigDecimal}.  The
+     * scale of the {@code BigDecimal} is zero.
+     *
+     * @param val {@code long} value to be converted to {@code BigDecimal}.
+     * @since  1.5
+     */
+    public BigDecimal(long val) {
+        this.intCompact = val;
+        this.intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
+        this.scale = 0;
+    }
+
+    /**
+     * Translates a {@code long} into a {@code BigDecimal}, with
+     * rounding according to the context settings.  The scale of the
+     * {@code BigDecimal}, before any rounding, is zero.
+     *
+     * @param  val {@code long} value to be converted to {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal(long val, MathContext mc) {
+        int mcp = mc.precision;
+        int mode = mc.roundingMode.oldMode;
+        int prec = 0;
+        int scale = 0;
+        BigInteger intVal = (val == INFLATED) ? INFLATED_BIGINT : null;
+        if (mcp > 0) { // do rounding
+            if (val == INFLATED) {
+                prec = 19;
+                int drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    intVal = divideAndRoundByTenPow(intVal, drop, mode);
+                    val = compactValFor(intVal);
+                    if (val != INFLATED) {
+                        break;
+                    }
+                    prec = bigDigitLength(intVal);
+                    drop = prec - mcp;
+                }
+            }
+            if (val != INFLATED) {
+                prec = longDigitLength(val);
+                int drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    val = divideAndRound(val, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                    prec = longDigitLength(val);
+                    drop = prec - mcp;
+                }
+                intVal = null;
+            }
+        }
+        this.intVal = intVal;
+        this.intCompact = val;
+        this.scale = scale;
+        this.precision = prec;
+    }
+
+    // Static Factory Methods
+
+    /**
+     * Translates a {@code long} unscaled value and an
+     * {@code int} scale into a {@code BigDecimal}.  This
+     * {@literal "static factory method"} is provided in preference to
+     * a ({@code long}, {@code int}) constructor because it
+     * allows for reuse of frequently used {@code BigDecimal} values..
+     *
+     * @param unscaledVal unscaled value of the {@code BigDecimal}.
+     * @param scale scale of the {@code BigDecimal}.
+     * @return a {@code BigDecimal} whose value is
+     *         <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
+     */
+    public static BigDecimal valueOf(long unscaledVal, int scale) {
+        if (scale == 0)
+            return valueOf(unscaledVal);
+        else if (unscaledVal == 0) {
+            return zeroValueOf(scale);
+        }
+        return new BigDecimal(unscaledVal == INFLATED ?
+                              INFLATED_BIGINT : null,
+                              unscaledVal, scale, 0);
+    }
+
+    /**
+     * Translates a {@code long} value into a {@code BigDecimal}
+     * with a scale of zero.  This {@literal "static factory method"}
+     * is provided in preference to a ({@code long}) constructor
+     * because it allows for reuse of frequently used
+     * {@code BigDecimal} values.
+     *
+     * @param val value of the {@code BigDecimal}.
+     * @return a {@code BigDecimal} whose value is {@code val}.
+     */
+    public static BigDecimal valueOf(long val) {
+        if (val >= 0 && val < zeroThroughTen.length)
+            return zeroThroughTen[(int)val];
+        else if (val != INFLATED)
+            return new BigDecimal(null, val, 0, 0);
+        return new BigDecimal(INFLATED_BIGINT, val, 0, 0);
+    }
+
+    static BigDecimal valueOf(long unscaledVal, int scale, int prec) {
+        if (scale == 0 && unscaledVal >= 0 && unscaledVal < zeroThroughTen.length) {
+            return zeroThroughTen[(int) unscaledVal];
+        } else if (unscaledVal == 0) {
+            return zeroValueOf(scale);
+        }
+        return new BigDecimal(unscaledVal == INFLATED ? INFLATED_BIGINT : null,
+                unscaledVal, scale, prec);
+    }
+
+    static BigDecimal valueOf(BigInteger intVal, int scale, int prec) {
+        long val = compactValFor(intVal);
+        if (val == 0) {
+            return zeroValueOf(scale);
+        } else if (scale == 0 && val >= 0 && val < zeroThroughTen.length) {
+            return zeroThroughTen[(int) val];
+        }
+        return new BigDecimal(intVal, val, scale, prec);
+    }
+
+    static BigDecimal zeroValueOf(int scale) {
+        if (scale >= 0 && scale < ZERO_SCALED_BY.length)
+            return ZERO_SCALED_BY[scale];
+        else
+            return new BigDecimal(BigInteger.ZERO, 0, scale, 1);
+    }
+
+    /**
+     * Translates a {@code double} into a {@code BigDecimal}, using
+     * the {@code double}'s canonical string representation provided
+     * by the {@link Double#toString(double)} method.
+     *
+     * <p><b>Note:</b> This is generally the preferred way to convert
+     * a {@code double} (or {@code float}) into a
+     * {@code BigDecimal}, as the value returned is equal to that
+     * resulting from constructing a {@code BigDecimal} from the
+     * result of using {@link Double#toString(double)}.
+     *
+     * @param  val {@code double} to convert to a {@code BigDecimal}.
+     * @return a {@code BigDecimal} whose value is equal to or approximately
+     *         equal to the value of {@code val}.
+     * @throws NumberFormatException if {@code val} is infinite or NaN.
+     * @since  1.5
+     */
+    public static BigDecimal valueOf(double val) {
+        // Reminder: a zero double returns '0.0', so we cannot fastpath
+        // to use the constant ZERO.  This might be important enough to
+        // justify a factory approach, a cache, or a few private
+        // constants, later.
+        return new BigDecimal(Double.toString(val));
+    }
+
+    // Arithmetic Operations
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this +
+     * augend)}, and whose scale is {@code max(this.scale(),
+     * augend.scale())}.
+     *
+     * @param  augend value to be added to this {@code BigDecimal}.
+     * @return {@code this + augend}
+     */
+    public BigDecimal add(BigDecimal augend) {
+        if (this.intCompact != INFLATED) {
+            if ((augend.intCompact != INFLATED)) {
+                return add(this.intCompact, this.scale, augend.intCompact, augend.scale);
+            } else {
+                return add(this.intCompact, this.scale, augend.intVal, augend.scale);
+            }
+        } else {
+            if ((augend.intCompact != INFLATED)) {
+                return add(augend.intCompact, augend.scale, this.intVal, this.scale);
+            } else {
+                return add(this.intVal, this.scale, augend.intVal, augend.scale);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this + augend)},
+     * with rounding according to the context settings.
+     *
+     * If either number is zero and the precision setting is nonzero then
+     * the other number, rounded if necessary, is used as the result.
+     *
+     * @param  augend value to be added to this {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @return {@code this + augend}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal add(BigDecimal augend, MathContext mc) {
+        if (mc.precision == 0)
+            return add(augend);
+        BigDecimal lhs = this;
+
+        // If either number is zero then the other number, rounded and
+        // scaled if necessary, is used as the result.
+        {
+            boolean lhsIsZero = lhs.signum() == 0;
+            boolean augendIsZero = augend.signum() == 0;
+
+            if (lhsIsZero || augendIsZero) {
+                int preferredScale = Math.max(lhs.scale(), augend.scale());
+                BigDecimal result;
+
+                if (lhsIsZero && augendIsZero)
+                    return zeroValueOf(preferredScale);
+                result = lhsIsZero ? doRound(augend, mc) : doRound(lhs, mc);
+
+                if (result.scale() == preferredScale)
+                    return result;
+                else if (result.scale() > preferredScale) {
+                    return stripZerosToMatchScale(result.intVal, result.intCompact, result.scale, preferredScale);
+                } else { // result.scale < preferredScale
+                    int precisionDiff = mc.precision - result.precision();
+                    int scaleDiff     = preferredScale - result.scale();
+
+                    if (precisionDiff >= scaleDiff)
+                        return result.setScale(preferredScale); // can achieve target scale
+                    else
+                        return result.setScale(result.scale() + precisionDiff);
+                }
+            }
+        }
+
+        long padding = (long) lhs.scale - augend.scale;
+        if (padding != 0) { // scales differ; alignment needed
+            BigDecimal arg[] = preAlign(lhs, augend, padding, mc);
+            matchScale(arg);
+            lhs = arg[0];
+            augend = arg[1];
+        }
+        return doRound(lhs.inflated().add(augend.inflated()), lhs.scale, mc);
+    }
+
+    /**
+     * Returns an array of length two, the sum of whose entries is
+     * equal to the rounded sum of the {@code BigDecimal} arguments.
+     *
+     * <p>If the digit positions of the arguments have a sufficient
+     * gap between them, the value smaller in magnitude can be
+     * condensed into a {@literal "sticky bit"} and the end result will
+     * round the same way <em>if</em> the precision of the final
+     * result does not include the high order digit of the small
+     * magnitude operand.
+     *
+     * <p>Note that while strictly speaking this is an optimization,
+     * it makes a much wider range of additions practical.
+     *
+     * <p>This corresponds to a pre-shift operation in a fixed
+     * precision floating-point adder; this method is complicated by
+     * variable precision of the result as determined by the
+     * MathContext.  A more nuanced operation could implement a
+     * {@literal "right shift"} on the smaller magnitude operand so
+     * that the number of digits of the smaller operand could be
+     * reduced even though the significands partially overlapped.
+     */
+    private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend, long padding, MathContext mc) {
+        assert padding != 0;
+        BigDecimal big;
+        BigDecimal small;
+
+        if (padding < 0) { // lhs is big; augend is small
+            big = lhs;
+            small = augend;
+        } else { // lhs is small; augend is big
+            big = augend;
+            small = lhs;
+        }
+
+        /*
+         * This is the estimated scale of an ulp of the result; it assumes that
+         * the result doesn't have a carry-out on a true add (e.g. 999 + 1 =>
+         * 1000) or any subtractive cancellation on borrowing (e.g. 100 - 1.2 =>
+         * 98.8)
+         */
+        long estResultUlpScale = (long) big.scale - big.precision() + mc.precision;
+
+        /*
+         * The low-order digit position of big is big.scale().  This
+         * is true regardless of whether big has a positive or
+         * negative scale.  The high-order digit position of small is
+         * small.scale - (small.precision() - 1).  To do the full
+         * condensation, the digit positions of big and small must be
+         * disjoint *and* the digit positions of small should not be
+         * directly visible in the result.
+         */
+        long smallHighDigitPos = (long) small.scale - small.precision() + 1;
+        if (smallHighDigitPos > big.scale + 2 && // big and small disjoint
+            smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible
+            small = BigDecimal.valueOf(small.signum(), this.checkScale(Math.max(big.scale, estResultUlpScale) + 3));
+        }
+
+        // Since addition is symmetric, preserving input order in
+        // returned operands doesn't matter
+        BigDecimal[] result = {big, small};
+        return result;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this -
+     * subtrahend)}, and whose scale is {@code max(this.scale(),
+     * subtrahend.scale())}.
+     *
+     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
+     * @return {@code this - subtrahend}
+     */
+    public BigDecimal subtract(BigDecimal subtrahend) {
+        if (this.intCompact != INFLATED) {
+            if ((subtrahend.intCompact != INFLATED)) {
+                return add(this.intCompact, this.scale, -subtrahend.intCompact, subtrahend.scale);
+            } else {
+                return add(this.intCompact, this.scale, subtrahend.intVal.negate(), subtrahend.scale);
+            }
+        } else {
+            if ((subtrahend.intCompact != INFLATED)) {
+                // Pair of subtrahend values given before pair of
+                // values from this BigDecimal to avoid need for
+                // method overloading on the specialized add method
+                return add(-subtrahend.intCompact, subtrahend.scale, this.intVal, this.scale);
+            } else {
+                return add(this.intVal, this.scale, subtrahend.intVal.negate(), subtrahend.scale);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this - subtrahend)},
+     * with rounding according to the context settings.
+     *
+     * If {@code subtrahend} is zero then this, rounded if necessary, is used as the
+     * result.  If this is zero then the result is {@code subtrahend.negate(mc)}.
+     *
+     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @return {@code this - subtrahend}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
+        if (mc.precision == 0)
+            return subtract(subtrahend);
+        // share the special rounding code in add()
+        return add(subtrahend.negate(), mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
+     * multiplicand)</tt>, and whose scale is {@code (this.scale() +
+     * multiplicand.scale())}.
+     *
+     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
+     * @return {@code this * multiplicand}
+     */
+    public BigDecimal multiply(BigDecimal multiplicand) {
+        int productScale = checkScale((long) scale + multiplicand.scale);
+        if (this.intCompact != INFLATED) {
+            if ((multiplicand.intCompact != INFLATED)) {
+                return multiply(this.intCompact, multiplicand.intCompact, productScale);
+            } else {
+                return multiply(this.intCompact, multiplicand.intVal, productScale);
+            }
+        } else {
+            if ((multiplicand.intCompact != INFLATED)) {
+                return multiply(multiplicand.intCompact, this.intVal, productScale);
+            } else {
+                return multiply(this.intVal, multiplicand.intVal, productScale);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
+     * multiplicand)</tt>, with rounding according to the context settings.
+     *
+     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
+     * @param  mc the context to use.
+     * @return {@code this * multiplicand}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
+        if (mc.precision == 0)
+            return multiply(multiplicand);
+        int productScale = checkScale((long) scale + multiplicand.scale);
+        if (this.intCompact != INFLATED) {
+            if ((multiplicand.intCompact != INFLATED)) {
+                return multiplyAndRound(this.intCompact, multiplicand.intCompact, productScale, mc);
+            } else {
+                return multiplyAndRound(this.intCompact, multiplicand.intVal, productScale, mc);
+            }
+        } else {
+            if ((multiplicand.intCompact != INFLATED)) {
+                return multiplyAndRound(multiplicand.intCompact, this.intVal, productScale, mc);
+            } else {
+                return multiplyAndRound(this.intVal, multiplicand.intVal, productScale, mc);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, and whose scale is as specified.  If rounding must
+     * be performed to generate a result with the specified scale, the
+     * specified rounding mode is applied.
+     *
+     * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
+     * should be used in preference to this legacy method.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
+     * @param  roundingMode rounding mode to apply.
+     * @return {@code this / divisor}
+     * @throws ArithmeticException if {@code divisor} is zero,
+     *         {@code roundingMode==ROUND_UNNECESSARY} and
+     *         the specified scale is insufficient to represent the result
+     *         of the division exactly.
+     * @throws IllegalArgumentException if {@code roundingMode} does not
+     *         represent a valid rounding mode.
+     * @see    #ROUND_UP
+     * @see    #ROUND_DOWN
+     * @see    #ROUND_CEILING
+     * @see    #ROUND_FLOOR
+     * @see    #ROUND_HALF_UP
+     * @see    #ROUND_HALF_DOWN
+     * @see    #ROUND_HALF_EVEN
+     * @see    #ROUND_UNNECESSARY
+     */
+    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
+        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
+            throw new IllegalArgumentException("Invalid rounding mode");
+        if (this.intCompact != INFLATED) {
+            if ((divisor.intCompact != INFLATED)) {
+                return divide(this.intCompact, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
+            } else {
+                return divide(this.intCompact, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
+            }
+        } else {
+            if ((divisor.intCompact != INFLATED)) {
+                return divide(this.intVal, this.scale, divisor.intCompact, divisor.scale, scale, roundingMode);
+            } else {
+                return divide(this.intVal, this.scale, divisor.intVal, divisor.scale, scale, roundingMode);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, and whose scale is as specified.  If rounding must
+     * be performed to generate a result with the specified scale, the
+     * specified rounding mode is applied.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
+     * @param  roundingMode rounding mode to apply.
+     * @return {@code this / divisor}
+     * @throws ArithmeticException if {@code divisor} is zero,
+     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
+     *         the specified scale is insufficient to represent the result
+     *         of the division exactly.
+     * @since 1.5
+     */
+    public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
+        return divide(divisor, scale, roundingMode.oldMode);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, and whose scale is {@code this.scale()}.  If
+     * rounding must be performed to generate a result with the given
+     * scale, the specified rounding mode is applied.
+     *
+     * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
+     * should be used in preference to this legacy method.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  roundingMode rounding mode to apply.
+     * @return {@code this / divisor}
+     * @throws ArithmeticException if {@code divisor==0}, or
+     *         {@code roundingMode==ROUND_UNNECESSARY} and
+     *         {@code this.scale()} is insufficient to represent the result
+     *         of the division exactly.
+     * @throws IllegalArgumentException if {@code roundingMode} does not
+     *         represent a valid rounding mode.
+     * @see    #ROUND_UP
+     * @see    #ROUND_DOWN
+     * @see    #ROUND_CEILING
+     * @see    #ROUND_FLOOR
+     * @see    #ROUND_HALF_UP
+     * @see    #ROUND_HALF_DOWN
+     * @see    #ROUND_HALF_EVEN
+     * @see    #ROUND_UNNECESSARY
+     */
+    public BigDecimal divide(BigDecimal divisor, int roundingMode) {
+        return this.divide(divisor, scale, roundingMode);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, and whose scale is {@code this.scale()}.  If
+     * rounding must be performed to generate a result with the given
+     * scale, the specified rounding mode is applied.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  roundingMode rounding mode to apply.
+     * @return {@code this / divisor}
+     * @throws ArithmeticException if {@code divisor==0}, or
+     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
+     *         {@code this.scale()} is insufficient to represent the result
+     *         of the division exactly.
+     * @since 1.5
+     */
+    public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
+        return this.divide(divisor, scale, roundingMode.oldMode);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, and whose preferred scale is {@code (this.scale() -
+     * divisor.scale())}; if the exact quotient cannot be
+     * represented (because it has a non-terminating decimal
+     * expansion) an {@code ArithmeticException} is thrown.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @throws ArithmeticException if the exact quotient does not have a
+     *         terminating decimal expansion
+     * @return {@code this / divisor}
+     * @since 1.5
+     * @author Joseph D. Darcy
+     */
+    public BigDecimal divide(BigDecimal divisor) {
+        /*
+         * Handle zero cases first.
+         */
+        if (divisor.signum() == 0) {   // x/0
+            if (this.signum() == 0)    // 0/0
+                throw new ArithmeticException("Division undefined");  // NaN
+            throw new ArithmeticException("Division by zero");
+        }
+
+        // Calculate preferred scale
+        int preferredScale = saturateLong((long) this.scale - divisor.scale);
+
+        if (this.signum() == 0) // 0/y
+            return zeroValueOf(preferredScale);
+        else {
+            /*
+             * If the quotient this/divisor has a terminating decimal
+             * expansion, the expansion can have no more than
+             * (a.precision() + ceil(10*b.precision)/3) digits.
+             * Therefore, create a MathContext object with this
+             * precision and do a divide with the UNNECESSARY rounding
+             * mode.
+             */
+            MathContext mc = new MathContext( (int)Math.min(this.precision() +
+                                                            (long)Math.ceil(10.0*divisor.precision()/3.0),
+                                                            Integer.MAX_VALUE),
+                                              RoundingMode.UNNECESSARY);
+            BigDecimal quotient;
+            try {
+                quotient = this.divide(divisor, mc);
+            } catch (ArithmeticException e) {
+                throw new ArithmeticException("Non-terminating decimal expansion; " +
+                                              "no exact representable decimal result.");
+            }
+
+            int quotientScale = quotient.scale();
+
+            // divide(BigDecimal, mc) tries to adjust the quotient to
+            // the desired one by removing trailing zeros; since the
+            // exact divide method does not have an explicit digit
+            // limit, we can add zeros too.
+            if (preferredScale > quotientScale)
+                return quotient.setScale(preferredScale, ROUND_UNNECESSARY);
+
+            return quotient;
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this /
+     * divisor)}, with rounding according to the context settings.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  mc the context to use.
+     * @return {@code this / divisor}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY} or
+     *         {@code mc.precision == 0} and the quotient has a
+     *         non-terminating decimal expansion.
+     * @since  1.5
+     */
+    public BigDecimal divide(BigDecimal divisor, MathContext mc) {
+        int mcp = mc.precision;
+        if (mcp == 0)
+            return divide(divisor);
+
+        BigDecimal dividend = this;
+        long preferredScale = (long)dividend.scale - divisor.scale;
+        // Now calculate the answer.  We use the existing
+        // divide-and-round method, but as this rounds to scale we have
+        // to normalize the values here to achieve the desired result.
+        // For x/y we first handle y=0 and x=0, and then normalize x and
+        // y to give x' and y' with the following constraints:
+        //   (a) 0.1 <= x' < 1
+        //   (b)  x' <= y' < 10*x'
+        // Dividing x'/y' with the required scale set to mc.precision then
+        // will give a result in the range 0.1 to 1 rounded to exactly
+        // the right number of digits (except in the case of a result of
+        // 1.000... which can arise when x=y, or when rounding overflows
+        // The 1.000... case will reduce properly to 1.
+        if (divisor.signum() == 0) {      // x/0
+            if (dividend.signum() == 0)    // 0/0
+                throw new ArithmeticException("Division undefined");  // NaN
+            throw new ArithmeticException("Division by zero");
+        }
+        if (dividend.signum() == 0) // 0/y
+            return zeroValueOf(saturateLong(preferredScale));
+        int xscale = dividend.precision();
+        int yscale = divisor.precision();
+        if(dividend.intCompact!=INFLATED) {
+            if(divisor.intCompact!=INFLATED) {
+                return divide(dividend.intCompact, xscale, divisor.intCompact, yscale, preferredScale, mc);
+            } else {
+                return divide(dividend.intCompact, xscale, divisor.intVal, yscale, preferredScale, mc);
+            }
+        } else {
+            if(divisor.intCompact!=INFLATED) {
+                return divide(dividend.intVal, xscale, divisor.intCompact, yscale, preferredScale, mc);
+            } else {
+                return divide(dividend.intVal, xscale, divisor.intVal, yscale, preferredScale, mc);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is the integer part
+     * of the quotient {@code (this / divisor)} rounded down.  The
+     * preferred scale of the result is {@code (this.scale() -
+     * divisor.scale())}.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @return The integer part of {@code this / divisor}.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @since  1.5
+     */
+    public BigDecimal divideToIntegralValue(BigDecimal divisor) {
+        // Calculate preferred scale
+        int preferredScale = saturateLong((long) this.scale - divisor.scale);
+        if (this.compareMagnitude(divisor) < 0) {
+            // much faster when this << divisor
+            return zeroValueOf(preferredScale);
+        }
+
+        if (this.signum() == 0 && divisor.signum() != 0)
+            return this.setScale(preferredScale, ROUND_UNNECESSARY);
+
+        // Perform a divide with enough digits to round to a correct
+        // integer value; then remove any fractional digits
+
+        int maxDigits = (int)Math.min(this.precision() +
+                                      (long)Math.ceil(10.0*divisor.precision()/3.0) +
+                                      Math.abs((long)this.scale() - divisor.scale()) + 2,
+                                      Integer.MAX_VALUE);
+        BigDecimal quotient = this.divide(divisor, new MathContext(maxDigits,
+                                                                   RoundingMode.DOWN));
+        if (quotient.scale > 0) {
+            quotient = quotient.setScale(0, RoundingMode.DOWN);
+            quotient = stripZerosToMatchScale(quotient.intVal, quotient.intCompact, quotient.scale, preferredScale);
+        }
+
+        if (quotient.scale < preferredScale) {
+            // pad with zeros if necessary
+            quotient = quotient.setScale(preferredScale, ROUND_UNNECESSARY);
+        }
+
+        return quotient;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is the integer part
+     * of {@code (this / divisor)}.  Since the integer part of the
+     * exact quotient does not depend on the rounding mode, the
+     * rounding mode does not affect the values returned by this
+     * method.  The preferred scale of the result is
+     * {@code (this.scale() - divisor.scale())}.  An
+     * {@code ArithmeticException} is thrown if the integer part of
+     * the exact quotient needs more than {@code mc.precision}
+     * digits.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  mc the context to use.
+     * @return The integer part of {@code this / divisor}.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @throws ArithmeticException if {@code mc.precision} {@literal >} 0 and the result
+     *         requires a precision of more than {@code mc.precision} digits.
+     * @since  1.5
+     * @author Joseph D. Darcy
+     */
+    public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
+        if (mc.precision == 0 || // exact result
+            (this.compareMagnitude(divisor) < 0)) // zero result
+            return divideToIntegralValue(divisor);
+
+        // Calculate preferred scale
+        int preferredScale = saturateLong((long)this.scale - divisor.scale);
+
+        /*
+         * Perform a normal divide to mc.precision digits.  If the
+         * remainder has absolute value less than the divisor, the
+         * integer portion of the quotient fits into mc.precision
+         * digits.  Next, remove any fractional digits from the
+         * quotient and adjust the scale to the preferred value.
+         */
+        BigDecimal result = this.divide(divisor, new MathContext(mc.precision, RoundingMode.DOWN));
+
+        if (result.scale() < 0) {
+            /*
+             * Result is an integer. See if quotient represents the
+             * full integer portion of the exact quotient; if it does,
+             * the computed remainder will be less than the divisor.
+             */
+            BigDecimal product = result.multiply(divisor);
+            // If the quotient is the full integer value,
+            // |dividend-product| < |divisor|.
+            if (this.subtract(product).compareMagnitude(divisor) >= 0) {
+                throw new ArithmeticException("Division impossible");
+            }
+        } else if (result.scale() > 0) {
+            /*
+             * Integer portion of quotient will fit into precision
+             * digits; recompute quotient to scale 0 to avoid double
+             * rounding and then try to adjust, if necessary.
+             */
+            result = result.setScale(0, RoundingMode.DOWN);
+        }
+        // else result.scale() == 0;
+
+        int precisionDiff;
+        if ((preferredScale > result.scale()) &&
+            (precisionDiff = mc.precision - result.precision()) > 0) {
+            return result.setScale(result.scale() +
+                                   Math.min(precisionDiff, preferredScale - result.scale) );
+        } else {
+            return stripZerosToMatchScale(result.intVal,result.intCompact,result.scale,preferredScale);
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this % divisor)}.
+     *
+     * <p>The remainder is given by
+     * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}.
+     * Note that this is not the modulo operation (the result can be
+     * negative).
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @return {@code this % divisor}.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @since  1.5
+     */
+    public BigDecimal remainder(BigDecimal divisor) {
+        BigDecimal divrem[] = this.divideAndRemainder(divisor);
+        return divrem[1];
+    }
+
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (this %
+     * divisor)}, with rounding according to the context settings.
+     * The {@code MathContext} settings affect the implicit divide
+     * used to compute the remainder.  The remainder computation
+     * itself is by definition exact.  Therefore, the remainder may
+     * contain more than {@code mc.getPrecision()} digits.
+     *
+     * <p>The remainder is given by
+     * {@code this.subtract(this.divideToIntegralValue(divisor,
+     * mc).multiply(divisor))}.  Note that this is not the modulo
+     * operation (the result can be negative).
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided.
+     * @param  mc the context to use.
+     * @return {@code this % divisor}, rounded as necessary.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
+     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
+     *         require a precision of more than {@code mc.precision} digits.
+     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
+     * @since  1.5
+     */
+    public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
+        BigDecimal divrem[] = this.divideAndRemainder(divisor, mc);
+        return divrem[1];
+    }
+
+    /**
+     * Returns a two-element {@code BigDecimal} array containing the
+     * result of {@code divideToIntegralValue} followed by the result of
+     * {@code remainder} on the two operands.
+     *
+     * <p>Note that if both the integer quotient and remainder are
+     * needed, this method is faster than using the
+     * {@code divideToIntegralValue} and {@code remainder} methods
+     * separately because the division need only be carried out once.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided,
+     *         and the remainder computed.
+     * @return a two element {@code BigDecimal} array: the quotient
+     *         (the result of {@code divideToIntegralValue}) is the initial element
+     *         and the remainder is the final element.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
+     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
+     * @since  1.5
+     */
+    public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
+        // we use the identity  x = i * y + r to determine r
+        BigDecimal[] result = new BigDecimal[2];
+
+        result[0] = this.divideToIntegralValue(divisor);
+        result[1] = this.subtract(result[0].multiply(divisor));
+        return result;
+    }
+
+    /**
+     * Returns a two-element {@code BigDecimal} array containing the
+     * result of {@code divideToIntegralValue} followed by the result of
+     * {@code remainder} on the two operands calculated with rounding
+     * according to the context settings.
+     *
+     * <p>Note that if both the integer quotient and remainder are
+     * needed, this method is faster than using the
+     * {@code divideToIntegralValue} and {@code remainder} methods
+     * separately because the division need only be carried out once.
+     *
+     * @param  divisor value by which this {@code BigDecimal} is to be divided,
+     *         and the remainder computed.
+     * @param  mc the context to use.
+     * @return a two element {@code BigDecimal} array: the quotient
+     *         (the result of {@code divideToIntegralValue}) is the
+     *         initial element and the remainder is the final element.
+     * @throws ArithmeticException if {@code divisor==0}
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
+     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
+     *         require a precision of more than {@code mc.precision} digits.
+     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
+     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
+     * @since  1.5
+     */
+    public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
+        if (mc.precision == 0)
+            return divideAndRemainder(divisor);
+
+        BigDecimal[] result = new BigDecimal[2];
+        BigDecimal lhs = this;
+
+        result[0] = lhs.divideToIntegralValue(divisor, mc);
+        result[1] = lhs.subtract(result[0].multiply(divisor));
+        return result;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is
+     * <tt>(this<sup>n</sup>)</tt>, The power is computed exactly, to
+     * unlimited precision.
+     *
+     * <p>The parameter {@code n} must be in the range 0 through
+     * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
+     * #ONE}.
+     *
+     * Note that future releases may expand the allowable exponent
+     * range of this method.
+     *
+     * @param  n power to raise this {@code BigDecimal} to.
+     * @return <tt>this<sup>n</sup></tt>
+     * @throws ArithmeticException if {@code n} is out of range.
+     * @since  1.5
+     */
+    public BigDecimal pow(int n) {
+        if (n < 0 || n > 999999999)
+            throw new ArithmeticException("Invalid operation");
+        // No need to calculate pow(n) if result will over/underflow.
+        // Don't attempt to support "supernormal" numbers.
+        int newScale = checkScale((long)scale * n);
+        return new BigDecimal(this.inflated().pow(n), newScale);
+    }
+
+
+    /**
+     * Returns a {@code BigDecimal} whose value is
+     * <tt>(this<sup>n</sup>)</tt>.  The current implementation uses
+     * the core algorithm defined in ANSI standard X3.274-1996 with
+     * rounding according to the context settings.  In general, the
+     * returned numerical value is within two ulps of the exact
+     * numerical value for the chosen precision.  Note that future
+     * releases may use a different algorithm with a decreased
+     * allowable error bound and increased allowable exponent range.
+     *
+     * <p>The X3.274-1996 algorithm is:
+     *
+     * <ul>
+     * <li> An {@code ArithmeticException} exception is thrown if
+     *  <ul>
+     *    <li>{@code abs(n) > 999999999}
+     *    <li>{@code mc.precision == 0} and {@code n < 0}
+     *    <li>{@code mc.precision > 0} and {@code n} has more than
+     *    {@code mc.precision} decimal digits
+     *  </ul>
+     *
+     * <li> if {@code n} is zero, {@link #ONE} is returned even if
+     * {@code this} is zero, otherwise
+     * <ul>
+     *   <li> if {@code n} is positive, the result is calculated via
+     *   the repeated squaring technique into a single accumulator.
+     *   The individual multiplications with the accumulator use the
+     *   same math context settings as in {@code mc} except for a
+     *   precision increased to {@code mc.precision + elength + 1}
+     *   where {@code elength} is the number of decimal digits in
+     *   {@code n}.
+     *
+     *   <li> if {@code n} is negative, the result is calculated as if
+     *   {@code n} were positive; this value is then divided into one
+     *   using the working precision specified above.
+     *
+     *   <li> The final value from either the positive or negative case
+     *   is then rounded to the destination precision.
+     *   </ul>
+     * </ul>
+     *
+     * @param  n power to raise this {@code BigDecimal} to.
+     * @param  mc the context to use.
+     * @return <tt>this<sup>n</sup></tt> using the ANSI standard X3.274-1996
+     *         algorithm
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}, or {@code n} is out
+     *         of range.
+     * @since  1.5
+     */
+    public BigDecimal pow(int n, MathContext mc) {
+        if (mc.precision == 0)
+            return pow(n);
+        if (n < -999999999 || n > 999999999)
+            throw new ArithmeticException("Invalid operation");
+        if (n == 0)
+            return ONE;                      // x**0 == 1 in X3.274
+        BigDecimal lhs = this;
+        MathContext workmc = mc;           // working settings
+        int mag = Math.abs(n);               // magnitude of n
+        if (mc.precision > 0) {
+            int elength = longDigitLength(mag); // length of n in digits
+            if (elength > mc.precision)        // X3.274 rule
+                throw new ArithmeticException("Invalid operation");
+            workmc = new MathContext(mc.precision + elength + 1,
+                                      mc.roundingMode);
+        }
+        // ready to carry out power calculation...
+        BigDecimal acc = ONE;           // accumulator
+        boolean seenbit = false;        // set once we've seen a 1-bit
+        for (int i=1;;i++) {            // for each bit [top bit ignored]
+            mag += mag;                 // shift left 1 bit
+            if (mag < 0) {              // top bit is set
+                seenbit = true;         // OK, we're off
+                acc = acc.multiply(lhs, workmc); // acc=acc*x
+            }
+            if (i == 31)
+                break;                  // that was the last bit
+            if (seenbit)
+                acc=acc.multiply(acc, workmc);   // acc=acc*acc [square]
+                // else (!seenbit) no point in squaring ONE
+        }
+        // if negative n, calculate the reciprocal using working precision
+        if (n < 0) // [hence mc.precision>0]
+            acc=ONE.divide(acc, workmc);
+        // round to final precision and strip zeros
+        return doRound(acc, mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is the absolute value
+     * of this {@code BigDecimal}, and whose scale is
+     * {@code this.scale()}.
+     *
+     * @return {@code abs(this)}
+     */
+    public BigDecimal abs() {
+        return (signum() < 0 ? negate() : this);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is the absolute value
+     * of this {@code BigDecimal}, with rounding according to the
+     * context settings.
+     *
+     * @param mc the context to use.
+     * @return {@code abs(this)}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since 1.5
+     */
+    public BigDecimal abs(MathContext mc) {
+        return (signum() < 0 ? negate(mc) : plus(mc));
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (-this)},
+     * and whose scale is {@code this.scale()}.
+     *
+     * @return {@code -this}.
+     */
+    public BigDecimal negate() {
+        if (intCompact == INFLATED) {
+            return new BigDecimal(intVal.negate(), INFLATED, scale, precision);
+        } else {
+            return valueOf(-intCompact, scale, precision);
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (-this)},
+     * with rounding according to the context settings.
+     *
+     * @param mc the context to use.
+     * @return {@code -this}, rounded as necessary.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @since  1.5
+     */
+    public BigDecimal negate(MathContext mc) {
+        return negate().plus(mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (+this)}, and whose
+     * scale is {@code this.scale()}.
+     *
+     * <p>This method, which simply returns this {@code BigDecimal}
+     * is included for symmetry with the unary minus method {@link
+     * #negate()}.
+     *
+     * @return {@code this}.
+     * @see #negate()
+     * @since  1.5
+     */
+    public BigDecimal plus() {
+        return this;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (+this)},
+     * with rounding according to the context settings.
+     *
+     * <p>The effect of this method is identical to that of the {@link
+     * #round(MathContext)} method.
+     *
+     * @param mc the context to use.
+     * @return {@code this}, rounded as necessary.  A zero result will
+     *         have a scale of 0.
+     * @throws ArithmeticException if the result is inexact but the
+     *         rounding mode is {@code UNNECESSARY}.
+     * @see    #round(MathContext)
+     * @since  1.5
+     */
+    public BigDecimal plus(MathContext mc) {
+        if (mc.precision == 0)                 // no rounding please
+            return this;
+        return doRound(this, mc);
+    }
+
+    /**
+     * Returns the signum function of this {@code BigDecimal}.
+     *
+     * @return -1, 0, or 1 as the value of this {@code BigDecimal}
+     *         is negative, zero, or positive.
+     */
+    public int signum() {
+        return (intCompact != INFLATED)?
+            Long.signum(intCompact):
+            intVal.signum();
+    }
+
+    /**
+     * Returns the <i>scale</i> of this {@code BigDecimal}.  If zero
+     * or positive, the scale is the number of digits to the right of
+     * the decimal point.  If negative, the unscaled value of the
+     * number is multiplied by ten to the power of the negation of the
+     * scale.  For example, a scale of {@code -3} means the unscaled
+     * value is multiplied by 1000.
+     *
+     * @return the scale of this {@code BigDecimal}.
+     */
+    public int scale() {
+        return scale;
+    }
+
+    /**
+     * Returns the <i>precision</i> of this {@code BigDecimal}.  (The
+     * precision is the number of digits in the unscaled value.)
+     *
+     * <p>The precision of a zero value is 1.
+     *
+     * @return the precision of this {@code BigDecimal}.
+     * @since  1.5
+     */
+    public int precision() {
+        int result = precision;
+        if (result == 0) {
+            long s = intCompact;
+            if (s != INFLATED)
+                result = longDigitLength(s);
+            else
+                result = bigDigitLength(intVal);
+            precision = result;
+        }
+        return result;
+    }
+
+
+    /**
+     * Returns a {@code BigInteger} whose value is the <i>unscaled
+     * value</i> of this {@code BigDecimal}.  (Computes <tt>(this *
+     * 10<sup>this.scale()</sup>)</tt>.)
+     *
+     * @return the unscaled value of this {@code BigDecimal}.
+     * @since  1.2
+     */
+    public BigInteger unscaledValue() {
+        return this.inflated();
+    }
+
+    // Rounding Modes
+
+    /**
+     * Rounding mode to round away from zero.  Always increments the
+     * digit prior to a nonzero discarded fraction.  Note that this rounding
+     * mode never decreases the magnitude of the calculated value.
+     */
+    public final static int ROUND_UP =           0;
+
+    /**
+     * Rounding mode to round towards zero.  Never increments the digit
+     * prior to a discarded fraction (i.e., truncates).  Note that this
+     * rounding mode never increases the magnitude of the calculated value.
+     */
+    public final static int ROUND_DOWN =         1;
+
+    /**
+     * Rounding mode to round towards positive infinity.  If the
+     * {@code BigDecimal} is positive, behaves as for
+     * {@code ROUND_UP}; if negative, behaves as for
+     * {@code ROUND_DOWN}.  Note that this rounding mode never
+     * decreases the calculated value.
+     */
+    public final static int ROUND_CEILING =      2;
+
+    /**
+     * Rounding mode to round towards negative infinity.  If the
+     * {@code BigDecimal} is positive, behave as for
+     * {@code ROUND_DOWN}; if negative, behave as for
+     * {@code ROUND_UP}.  Note that this rounding mode never
+     * increases the calculated value.
+     */
+    public final static int ROUND_FLOOR =        3;
+
+    /**
+     * Rounding mode to round towards {@literal "nearest neighbor"}
+     * unless both neighbors are equidistant, in which case round up.
+     * Behaves as for {@code ROUND_UP} if the discarded fraction is
+     * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
+     * that this is the rounding mode that most of us were taught in
+     * grade school.
+     */
+    public final static int ROUND_HALF_UP =      4;
+
+    /**
+     * Rounding mode to round towards {@literal "nearest neighbor"}
+     * unless both neighbors are equidistant, in which case round
+     * down.  Behaves as for {@code ROUND_UP} if the discarded
+     * fraction is {@literal >} 0.5; otherwise, behaves as for
+     * {@code ROUND_DOWN}.
+     */
+    public final static int ROUND_HALF_DOWN =    5;
+
+    /**
+     * Rounding mode to round towards the {@literal "nearest neighbor"}
+     * unless both neighbors are equidistant, in which case, round
+     * towards the even neighbor.  Behaves as for
+     * {@code ROUND_HALF_UP} if the digit to the left of the
+     * discarded fraction is odd; behaves as for
+     * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
+     * rounding mode that minimizes cumulative error when applied
+     * repeatedly over a sequence of calculations.
+     */
+    public final static int ROUND_HALF_EVEN =    6;
+
+    /**
+     * Rounding mode to assert that the requested operation has an exact
+     * result, hence no rounding is necessary.  If this rounding mode is
+     * specified on an operation that yields an inexact result, an
+     * {@code ArithmeticException} is thrown.
+     */
+    public final static int ROUND_UNNECESSARY =  7;
+
+
+    // Scaling/Rounding Operations
+
+    /**
+     * Returns a {@code BigDecimal} rounded according to the
+     * {@code MathContext} settings.  If the precision setting is 0 then
+     * no rounding takes place.
+     *
+     * <p>The effect of this method is identical to that of the
+     * {@link #plus(MathContext)} method.
+     *
+     * @param mc the context to use.
+     * @return a {@code BigDecimal} rounded according to the
+     *         {@code MathContext} settings.
+     * @throws ArithmeticException if the rounding mode is
+     *         {@code UNNECESSARY} and the
+     *         {@code BigDecimal}  operation would require rounding.
+     * @see    #plus(MathContext)
+     * @since  1.5
+     */
+    public BigDecimal round(MathContext mc) {
+        return plus(mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose scale is the specified
+     * value, and whose unscaled value is determined by multiplying or
+     * dividing this {@code BigDecimal}'s unscaled value by the
+     * appropriate power of ten to maintain its overall value.  If the
+     * scale is reduced by the operation, the unscaled value must be
+     * divided (rather than multiplied), and the value may be changed;
+     * in this case, the specified rounding mode is applied to the
+     * division.
+     *
+     * <p>Note that since BigDecimal objects are immutable, calls of
+     * this method do <i>not</i> result in the original object being
+     * modified, contrary to the usual convention of having methods
+     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
+     * Instead, {@code setScale} returns an object with the proper
+     * scale; the returned object may or may not be newly allocated.
+     *
+     * @param  newScale scale of the {@code BigDecimal} value to be returned.
+     * @param  roundingMode The rounding mode to apply.
+     * @return a {@code BigDecimal} whose scale is the specified value,
+     *         and whose unscaled value is determined by multiplying or
+     *         dividing this {@code BigDecimal}'s unscaled value by the
+     *         appropriate power of ten to maintain its overall value.
+     * @throws ArithmeticException if {@code roundingMode==UNNECESSARY}
+     *         and the specified scaling operation would require
+     *         rounding.
+     * @see    RoundingMode
+     * @since  1.5
+     */
+    public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
+        return setScale(newScale, roundingMode.oldMode);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose scale is the specified
+     * value, and whose unscaled value is determined by multiplying or
+     * dividing this {@code BigDecimal}'s unscaled value by the
+     * appropriate power of ten to maintain its overall value.  If the
+     * scale is reduced by the operation, the unscaled value must be
+     * divided (rather than multiplied), and the value may be changed;
+     * in this case, the specified rounding mode is applied to the
+     * division.
+     *
+     * <p>Note that since BigDecimal objects are immutable, calls of
+     * this method do <i>not</i> result in the original object being
+     * modified, contrary to the usual convention of having methods
+     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
+     * Instead, {@code setScale} returns an object with the proper
+     * scale; the returned object may or may not be newly allocated.
+     *
+     * <p>The new {@link #setScale(int, RoundingMode)} method should
+     * be used in preference to this legacy method.
+     *
+     * @param  newScale scale of the {@code BigDecimal} value to be returned.
+     * @param  roundingMode The rounding mode to apply.
+     * @return a {@code BigDecimal} whose scale is the specified value,
+     *         and whose unscaled value is determined by multiplying or
+     *         dividing this {@code BigDecimal}'s unscaled value by the
+     *         appropriate power of ten to maintain its overall value.
+     * @throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY}
+     *         and the specified scaling operation would require
+     *         rounding.
+     * @throws IllegalArgumentException if {@code roundingMode} does not
+     *         represent a valid rounding mode.
+     * @see    #ROUND_UP
+     * @see    #ROUND_DOWN
+     * @see    #ROUND_CEILING
+     * @see    #ROUND_FLOOR
+     * @see    #ROUND_HALF_UP
+     * @see    #ROUND_HALF_DOWN
+     * @see    #ROUND_HALF_EVEN
+     * @see    #ROUND_UNNECESSARY
+     */
+    public BigDecimal setScale(int newScale, int roundingMode) {
+        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
+            throw new IllegalArgumentException("Invalid rounding mode");
+
+        int oldScale = this.scale;
+        if (newScale == oldScale)        // easy case
+            return this;
+        if (this.signum() == 0)            // zero can have any scale
+            return zeroValueOf(newScale);
+        if(this.intCompact!=INFLATED) {
+            long rs = this.intCompact;
+            if (newScale > oldScale) {
+                int raise = checkScale((long) newScale - oldScale);
+                if ((rs = longMultiplyPowerTen(rs, raise)) != INFLATED) {
+                    return valueOf(rs,newScale);
+                }
+                BigInteger rb = bigMultiplyPowerTen(raise);
+                return new BigDecimal(rb, INFLATED, newScale, (precision > 0) ? precision + raise : 0);
+            } else {
+                // newScale < oldScale -- drop some digits
+                // Can't predict the precision due to the effect of rounding.
+                int drop = checkScale((long) oldScale - newScale);
+                if (drop < LONG_TEN_POWERS_TABLE.length) {
+                    return divideAndRound(rs, LONG_TEN_POWERS_TABLE[drop], newScale, roundingMode, newScale);
+                } else {
+                    return divideAndRound(this.inflated(), bigTenToThe(drop), newScale, roundingMode, newScale);
+                }
+            }
+        } else {
+            if (newScale > oldScale) {
+                int raise = checkScale((long) newScale - oldScale);
+                BigInteger rb = bigMultiplyPowerTen(this.intVal,raise);
+                return new BigDecimal(rb, INFLATED, newScale, (precision > 0) ? precision + raise : 0);
+            } else {
+                // newScale < oldScale -- drop some digits
+                // Can't predict the precision due to the effect of rounding.
+                int drop = checkScale((long) oldScale - newScale);
+                if (drop < LONG_TEN_POWERS_TABLE.length)
+                    return divideAndRound(this.intVal, LONG_TEN_POWERS_TABLE[drop], newScale, roundingMode,
+                                          newScale);
+                else
+                    return divideAndRound(this.intVal,  bigTenToThe(drop), newScale, roundingMode, newScale);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose scale is the specified
+     * value, and whose value is numerically equal to this
+     * {@code BigDecimal}'s.  Throws an {@code ArithmeticException}
+     * if this is not possible.
+     *
+     * <p>This call is typically used to increase the scale, in which
+     * case it is guaranteed that there exists a {@code BigDecimal}
+     * of the specified scale and the correct value.  The call can
+     * also be used to reduce the scale if the caller knows that the
+     * {@code BigDecimal} has sufficiently many zeros at the end of
+     * its fractional part (i.e., factors of ten in its integer value)
+     * to allow for the rescaling without changing its value.
+     *
+     * <p>This method returns the same result as the two-argument
+     * versions of {@code setScale}, but saves the caller the trouble
+     * of specifying a rounding mode in cases where it is irrelevant.
+     *
+     * <p>Note that since {@code BigDecimal} objects are immutable,
+     * calls of this method do <i>not</i> result in the original
+     * object being modified, contrary to the usual convention of
+     * having methods named <tt>set<i>X</i></tt> mutate field
+     * <i>{@code X}</i>.  Instead, {@code setScale} returns an
+     * object with the proper scale; the returned object may or may
+     * not be newly allocated.
+     *
+     * @param  newScale scale of the {@code BigDecimal} value to be returned.
+     * @return a {@code BigDecimal} whose scale is the specified value, and
+     *         whose unscaled value is determined by multiplying or dividing
+     *         this {@code BigDecimal}'s unscaled value by the appropriate
+     *         power of ten to maintain its overall value.
+     * @throws ArithmeticException if the specified scaling operation would
+     *         require rounding.
+     * @see    #setScale(int, int)
+     * @see    #setScale(int, RoundingMode)
+     */
+    public BigDecimal setScale(int newScale) {
+        return setScale(newScale, ROUND_UNNECESSARY);
+    }
+
+    // Decimal Point Motion Operations
+
+    /**
+     * Returns a {@code BigDecimal} which is equivalent to this one
+     * with the decimal point moved {@code n} places to the left.  If
+     * {@code n} is non-negative, the call merely adds {@code n} to
+     * the scale.  If {@code n} is negative, the call is equivalent
+     * to {@code movePointRight(-n)}.  The {@code BigDecimal}
+     * returned by this call has value <tt>(this &times;
+     * 10<sup>-n</sup>)</tt> and scale {@code max(this.scale()+n,
+     * 0)}.
+     *
+     * @param  n number of places to move the decimal point to the left.
+     * @return a {@code BigDecimal} which is equivalent to this one with the
+     *         decimal point moved {@code n} places to the left.
+     * @throws ArithmeticException if scale overflows.
+     */
+    public BigDecimal movePointLeft(int n) {
+        // Cannot use movePointRight(-n) in case of n==Integer.MIN_VALUE
+        int newScale = checkScale((long)scale + n);
+        BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
+        return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} which is equivalent to this one
+     * with the decimal point moved {@code n} places to the right.
+     * If {@code n} is non-negative, the call merely subtracts
+     * {@code n} from the scale.  If {@code n} is negative, the call
+     * is equivalent to {@code movePointLeft(-n)}.  The
+     * {@code BigDecimal} returned by this call has value <tt>(this
+     * &times; 10<sup>n</sup>)</tt> and scale {@code max(this.scale()-n,
+     * 0)}.
+     *
+     * @param  n number of places to move the decimal point to the right.
+     * @return a {@code BigDecimal} which is equivalent to this one
+     *         with the decimal point moved {@code n} places to the right.
+     * @throws ArithmeticException if scale overflows.
+     */
+    public BigDecimal movePointRight(int n) {
+        // Cannot use movePointLeft(-n) in case of n==Integer.MIN_VALUE
+        int newScale = checkScale((long)scale - n);
+        BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
+        return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
+    }
+
+    /**
+     * Returns a BigDecimal whose numerical value is equal to
+     * ({@code this} * 10<sup>n</sup>).  The scale of
+     * the result is {@code (this.scale() - n)}.
+     *
+     * @param n the exponent power of ten to scale by
+     * @return a BigDecimal whose numerical value is equal to
+     * ({@code this} * 10<sup>n</sup>)
+     * @throws ArithmeticException if the scale would be
+     *         outside the range of a 32-bit integer.
+     *
+     * @since 1.5
+     */
+    public BigDecimal scaleByPowerOfTen(int n) {
+        return new BigDecimal(intVal, intCompact,
+                              checkScale((long)scale - n), precision);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} which is numerically equal to
+     * this one but with any trailing zeros removed from the
+     * representation.  For example, stripping the trailing zeros from
+     * the {@code BigDecimal} value {@code 600.0}, which has
+     * [{@code BigInteger}, {@code scale}] components equals to
+     * [6000, 1], yields {@code 6E2} with [{@code BigInteger},
+     * {@code scale}] components equals to [6, -2].  If
+     * this BigDecimal is numerically equal to zero, then
+     * {@code BigDecimal.ZERO} is returned.
+     *
+     * @return a numerically equal {@code BigDecimal} with any
+     * trailing zeros removed.
+     * @since 1.5
+     */
+    public BigDecimal stripTrailingZeros() {
+        if (intCompact == 0 || (intVal != null && intVal.signum() == 0)) {
+            return BigDecimal.ZERO;
+        } else if (intCompact != INFLATED) {
+            return createAndStripZerosToMatchScale(intCompact, scale, Long.MIN_VALUE);
+        } else {
+            return createAndStripZerosToMatchScale(intVal, scale, Long.MIN_VALUE);
+        }
+    }
+
+    // Comparison Operations
+
+    /**
+     * Compares this {@code BigDecimal} with the specified
+     * {@code BigDecimal}.  Two {@code BigDecimal} objects that are
+     * equal in value but have a different scale (like 2.0 and 2.00)
+     * are considered equal by this method.  This method is provided
+     * in preference to individual methods for each of the six boolean
+     * comparison operators ({@literal <}, ==,
+     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The
+     * suggested idiom for performing these comparisons is:
+     * {@code (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
+     * &lt;<i>op</i>&gt; is one of the six comparison operators.
+     *
+     * @param  val {@code BigDecimal} to which this {@code BigDecimal} is
+     *         to be compared.
+     * @return -1, 0, or 1 as this {@code BigDecimal} is numerically
+     *          less than, equal to, or greater than {@code val}.
+     */
+    public int compareTo(BigDecimal val) {
+        // Quick path for equal scale and non-inflated case.
+        if (scale == val.scale) {
+            long xs = intCompact;
+            long ys = val.intCompact;
+            if (xs != INFLATED && ys != INFLATED)
+                return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
+        }
+        int xsign = this.signum();
+        int ysign = val.signum();
+        if (xsign != ysign)
+            return (xsign > ysign) ? 1 : -1;
+        if (xsign == 0)
+            return 0;
+        int cmp = compareMagnitude(val);
+        return (xsign > 0) ? cmp : -cmp;
+    }
+
+    /**
+     * Version of compareTo that ignores sign.
+     */
+    private int compareMagnitude(BigDecimal val) {
+        // Match scales, avoid unnecessary inflation
+        long ys = val.intCompact;
+        long xs = this.intCompact;
+        if (xs == 0)
+            return (ys == 0) ? 0 : -1;
+        if (ys == 0)
+            return 1;
+
+        long sdiff = (long)this.scale - val.scale;
+        if (sdiff != 0) {
+            // Avoid matching scales if the (adjusted) exponents differ
+            long xae = (long)this.precision() - this.scale;   // [-1]
+            long yae = (long)val.precision() - val.scale;     // [-1]
+            if (xae < yae)
+                return -1;
+            if (xae > yae)
+                return 1;
+            BigInteger rb = null;
+            if (sdiff < 0) {
+                // The cases sdiff <= Integer.MIN_VALUE intentionally fall through.
+                if ( sdiff > Integer.MIN_VALUE &&
+                      (xs == INFLATED ||
+                      (xs = longMultiplyPowerTen(xs, (int)-sdiff)) == INFLATED) &&
+                     ys == INFLATED) {
+                    rb = bigMultiplyPowerTen((int)-sdiff);
+                    return rb.compareMagnitude(val.intVal);
+                }
+            } else { // sdiff > 0
+                // The cases sdiff > Integer.MAX_VALUE intentionally fall through.
+                if ( sdiff <= Integer.MAX_VALUE &&
+                      (ys == INFLATED ||
+                      (ys = longMultiplyPowerTen(ys, (int)sdiff)) == INFLATED) &&
+                     xs == INFLATED) {
+                    rb = val.bigMultiplyPowerTen((int)sdiff);
+                    return this.intVal.compareMagnitude(rb);
+                }
+            }
+        }
+        if (xs != INFLATED)
+            return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
+        else if (ys != INFLATED)
+            return 1;
+        else
+            return this.intVal.compareMagnitude(val.intVal);
+    }
+
+    /**
+     * Compares this {@code BigDecimal} with the specified
+     * {@code Object} for equality.  Unlike {@link
+     * #compareTo(BigDecimal) compareTo}, this method considers two
+     * {@code BigDecimal} objects equal only if they are equal in
+     * value and scale (thus 2.0 is not equal to 2.00 when compared by
+     * this method).
+     *
+     * @param  x {@code Object} to which this {@code BigDecimal} is
+     *         to be compared.
+     * @return {@code true} if and only if the specified {@code Object} is a
+     *         {@code BigDecimal} whose value and scale are equal to this
+     *         {@code BigDecimal}'s.
+     * @see    #compareTo(java.math.BigDecimal)
+     * @see    #hashCode
+     */
+    @Override
+    public boolean equals(Object x) {
+        if (!(x instanceof BigDecimal))
+            return false;
+        BigDecimal xDec = (BigDecimal) x;
+        if (x == this)
+            return true;
+        if (scale != xDec.scale)
+            return false;
+        long s = this.intCompact;
+        long xs = xDec.intCompact;
+        if (s != INFLATED) {
+            if (xs == INFLATED)
+                xs = compactValFor(xDec.intVal);
+            return xs == s;
+        } else if (xs != INFLATED)
+            return xs == compactValFor(this.intVal);
+
+        return this.inflated().equals(xDec.inflated());
+    }
+
+    /**
+     * Returns the minimum of this {@code BigDecimal} and
+     * {@code val}.
+     *
+     * @param  val value with which the minimum is to be computed.
+     * @return the {@code BigDecimal} whose value is the lesser of this
+     *         {@code BigDecimal} and {@code val}.  If they are equal,
+     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
+     *         method, {@code this} is returned.
+     * @see    #compareTo(java.math.BigDecimal)
+     */
+    public BigDecimal min(BigDecimal val) {
+        return (compareTo(val) <= 0 ? this : val);
+    }
+
+    /**
+     * Returns the maximum of this {@code BigDecimal} and {@code val}.
+     *
+     * @param  val value with which the maximum is to be computed.
+     * @return the {@code BigDecimal} whose value is the greater of this
+     *         {@code BigDecimal} and {@code val}.  If they are equal,
+     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
+     *         method, {@code this} is returned.
+     * @see    #compareTo(java.math.BigDecimal)
+     */
+    public BigDecimal max(BigDecimal val) {
+        return (compareTo(val) >= 0 ? this : val);
+    }
+
+    // Hash Function
+
+    /**
+     * Returns the hash code for this {@code BigDecimal}.  Note that
+     * two {@code BigDecimal} objects that are numerically equal but
+     * differ in scale (like 2.0 and 2.00) will generally <i>not</i>
+     * have the same hash code.
+     *
+     * @return hash code for this {@code BigDecimal}.
+     * @see #equals(Object)
+     */
+    @Override
+    public int hashCode() {
+        if (intCompact != INFLATED) {
+            long val2 = (intCompact < 0)? -intCompact : intCompact;
+            int temp = (int)( ((int)(val2 >>> 32)) * 31  +
+                              (val2 & LONG_MASK));
+            return 31*((intCompact < 0) ?-temp:temp) + scale;
+        } else
+            return 31*intVal.hashCode() + scale;
+    }
+
+    // Format Converters
+
+    /**
+     * Returns the string representation of this {@code BigDecimal},
+     * using scientific notation if an exponent is needed.
+     *
+     * <p>A standard canonical string form of the {@code BigDecimal}
+     * is created as though by the following steps: first, the
+     * absolute value of the unscaled value of the {@code BigDecimal}
+     * is converted to a string in base ten using the characters
+     * {@code '0'} through {@code '9'} with no leading zeros (except
+     * if its value is zero, in which case a single {@code '0'}
+     * character is used).
+     *
+     * <p>Next, an <i>adjusted exponent</i> is calculated; this is the
+     * negated scale, plus the number of characters in the converted
+     * unscaled value, less one.  That is,
+     * {@code -scale+(ulength-1)}, where {@code ulength} is the
+     * length of the absolute value of the unscaled value in decimal
+     * digits (its <i>precision</i>).
+     *
+     * <p>If the scale is greater than or equal to zero and the
+     * adjusted exponent is greater than or equal to {@code -6}, the
+     * number will be converted to a character form without using
+     * exponential notation.  In this case, if the scale is zero then
+     * no decimal point is added and if the scale is positive a
+     * decimal point will be inserted with the scale specifying the
+     * number of characters to the right of the decimal point.
+     * {@code '0'} characters are added to the left of the converted
+     * unscaled value as necessary.  If no character precedes the
+     * decimal point after this insertion then a conventional
+     * {@code '0'} character is prefixed.
+     *
+     * <p>Otherwise (that is, if the scale is negative, or the
+     * adjusted exponent is less than {@code -6}), the number will be
+     * converted to a character form using exponential notation.  In
+     * this case, if the converted {@code BigInteger} has more than
+     * one digit a decimal point is inserted after the first digit.
+     * An exponent in character form is then suffixed to the converted
+     * unscaled value (perhaps with inserted decimal point); this
+     * comprises the letter {@code 'E'} followed immediately by the
+     * adjusted exponent converted to a character form.  The latter is
+     * in base ten, using the characters {@code '0'} through
+     * {@code '9'} with no leading zeros, and is always prefixed by a
+     * sign character {@code '-'} (<tt>'&#92;u002D'</tt>) if the
+     * adjusted exponent is negative, {@code '+'}
+     * (<tt>'&#92;u002B'</tt>) otherwise).
+     *
+     * <p>Finally, the entire string is prefixed by a minus sign
+     * character {@code '-'} (<tt>'&#92;u002D'</tt>) if the unscaled
+     * value is less than zero.  No sign character is prefixed if the
+     * unscaled value is zero or positive.
+     *
+     * <p><b>Examples:</b>
+     * <p>For each representation [<i>unscaled value</i>, <i>scale</i>]
+     * on the left, the resulting string is shown on the right.
+     * <pre>
+     * [123,0]      "123"
+     * [-123,0]     "-123"
+     * [123,-1]     "1.23E+3"
+     * [123,-3]     "1.23E+5"
+     * [123,1]      "12.3"
+     * [123,5]      "0.00123"
+     * [123,10]     "1.23E-8"
+     * [-123,12]    "-1.23E-10"
+     * </pre>
+     *
+     * <b>Notes:</b>
+     * <ol>
+     *
+     * <li>There is a one-to-one mapping between the distinguishable
+     * {@code BigDecimal} values and the result of this conversion.
+     * That is, every distinguishable {@code BigDecimal} value
+     * (unscaled value and scale) has a unique string representation
+     * as a result of using {@code toString}.  If that string
+     * representation is converted back to a {@code BigDecimal} using
+     * the {@link #BigDecimal(String)} constructor, then the original
+     * value will be recovered.
+     *
+     * <li>The string produced for a given number is always the same;
+     * it is not affected by locale.  This means that it can be used
+     * as a canonical string representation for exchanging decimal
+     * data, or as a key for a Hashtable, etc.  Locale-sensitive
+     * number formatting and parsing is handled by the {@link
+     * java.text.NumberFormat} class and its subclasses.
+     *
+     * <li>The {@link #toEngineeringString} method may be used for
+     * presenting numbers with exponents in engineering notation, and the
+     * {@link #setScale(int,RoundingMode) setScale} method may be used for
+     * rounding a {@code BigDecimal} so it has a known number of digits after
+     * the decimal point.
+     *
+     * <li>The digit-to-character mapping provided by
+     * {@code Character.forDigit} is used.
+     *
+     * </ol>
+     *
+     * @return string representation of this {@code BigDecimal}.
+     * @see    Character#forDigit
+     * @see    #BigDecimal(java.lang.String)
+     */
+    @Override
+    public String toString() {
+        String sc = stringCache;
+        if (sc == null)
+            stringCache = sc = layoutChars(true);
+        return sc;
+    }
+
+    /**
+     * Returns a string representation of this {@code BigDecimal},
+     * using engineering notation if an exponent is needed.
+     *
+     * <p>Returns a string that represents the {@code BigDecimal} as
+     * described in the {@link #toString()} method, except that if
+     * exponential notation is used, the power of ten is adjusted to
+     * be a multiple of three (engineering notation) such that the
+     * integer part of nonzero values will be in the range 1 through
+     * 999.  If exponential notation is used for zero values, a
+     * decimal point and one or two fractional zero digits are used so
+     * that the scale of the zero value is preserved.  Note that
+     * unlike the output of {@link #toString()}, the output of this
+     * method is <em>not</em> guaranteed to recover the same [integer,
+     * scale] pair of this {@code BigDecimal} if the output string is
+     * converting back to a {@code BigDecimal} using the {@linkplain
+     * #BigDecimal(String) string constructor}.  The result of this method meets
+     * the weaker constraint of always producing a numerically equal
+     * result from applying the string constructor to the method's output.
+     *
+     * @return string representation of this {@code BigDecimal}, using
+     *         engineering notation if an exponent is needed.
+     * @since  1.5
+     */
+    public String toEngineeringString() {
+        return layoutChars(false);
+    }
+
+    /**
+     * Returns a string representation of this {@code BigDecimal}
+     * without an exponent field.  For values with a positive scale,
+     * the number of digits to the right of the decimal point is used
+     * to indicate scale.  For values with a zero or negative scale,
+     * the resulting string is generated as if the value were
+     * converted to a numerically equal value with zero scale and as
+     * if all the trailing zeros of the zero scale value were present
+     * in the result.
+     *
+     * The entire string is prefixed by a minus sign character '-'
+     * (<tt>'&#92;u002D'</tt>) if the unscaled value is less than
+     * zero. No sign character is prefixed if the unscaled value is
+     * zero or positive.
+     *
+     * Note that if the result of this method is passed to the
+     * {@linkplain #BigDecimal(String) string constructor}, only the
+     * numerical value of this {@code BigDecimal} will necessarily be
+     * recovered; the representation of the new {@code BigDecimal}
+     * may have a different scale.  In particular, if this
+     * {@code BigDecimal} has a negative scale, the string resulting
+     * from this method will have a scale of zero when processed by
+     * the string constructor.
+     *
+     * (This method behaves analogously to the {@code toString}
+     * method in 1.4 and earlier releases.)
+     *
+     * @return a string representation of this {@code BigDecimal}
+     * without an exponent field.
+     * @since 1.5
+     * @see #toString()
+     * @see #toEngineeringString()
+     */
+    public String toPlainString() {
+        if(scale==0) {
+            if(intCompact!=INFLATED) {
+                return Long.toString(intCompact);
+            } else {
+                return intVal.toString();
+            }
+        }
+        if(this.scale<0) { // No decimal point
+            if(signum()==0) {
+                return "0";
+            }
+            int tailingZeros = checkScaleNonZero((-(long)scale));
+            StringBuilder buf;
+            if(intCompact!=INFLATED) {
+                buf = new StringBuilder(20+tailingZeros);
+                buf.append(intCompact);
+            } else {
+                String str = intVal.toString();
+                buf = new StringBuilder(str.length()+tailingZeros);
+                buf.append(str);
+            }
+            for (int i = 0; i < tailingZeros; i++)
+                buf.append('0');
+            return buf.toString();
+        }
+        String str ;
+        if(intCompact!=INFLATED) {
+            str = Long.toString(Math.abs(intCompact));
+        } else {
+            str = intVal.abs().toString();
+        }
+        return getValueString(signum(), str, scale);
+    }
+
+    /* Returns a digit.digit string */
+    private String getValueString(int signum, String intString, int scale) {
+        /* Insert decimal point */
+        StringBuilder buf;
+        int insertionPoint = intString.length() - scale;
+        if (insertionPoint == 0) {  /* Point goes right before intVal */
+            return (signum<0 ? "-0." : "0.") + intString;
+        } else if (insertionPoint > 0) { /* Point goes inside intVal */
+            buf = new StringBuilder(intString);
+            buf.insert(insertionPoint, '.');
+            if (signum < 0)
+                buf.insert(0, '-');
+        } else { /* We must insert zeros between point and intVal */
+            buf = new StringBuilder(3-insertionPoint + intString.length());
+            buf.append(signum<0 ? "-0." : "0.");
+            for (int i=0; i<-insertionPoint; i++)
+                buf.append('0');
+            buf.append(intString);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code BigInteger}.
+     * This conversion is analogous to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code long} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * any fractional part of this
+     * {@code BigDecimal} will be discarded.  Note that this
+     * conversion can lose information about the precision of the
+     * {@code BigDecimal} value.
+     * <p>
+     * To have an exception thrown if the conversion is inexact (in
+     * other words if a nonzero fractional part is discarded), use the
+     * {@link #toBigIntegerExact()} method.
+     *
+     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
+     */
+    public BigInteger toBigInteger() {
+        // force to an integer, quietly
+        return this.setScale(0, ROUND_DOWN).inflated();
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code BigInteger},
+     * checking for lost information.  An exception is thrown if this
+     * {@code BigDecimal} has a nonzero fractional part.
+     *
+     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
+     * @throws ArithmeticException if {@code this} has a nonzero
+     *         fractional part.
+     * @since  1.5
+     */
+    public BigInteger toBigIntegerExact() {
+        // round to an integer, with Exception if decimal part non-0
+        return this.setScale(0, ROUND_UNNECESSARY).inflated();
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code long}.
+     * This conversion is analogous to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code short} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * any fractional part of this
+     * {@code BigDecimal} will be discarded, and if the resulting
+     * "{@code BigInteger}" is too big to fit in a
+     * {@code long}, only the low-order 64 bits are returned.
+     * Note that this conversion can lose information about the
+     * overall magnitude and precision of this {@code BigDecimal} value as well
+     * as return a result with the opposite sign.
+     *
+     * @return this {@code BigDecimal} converted to a {@code long}.
+     */
+    public long longValue(){
+        if (intCompact != INFLATED && scale == 0) {
+            return intCompact;
+        } else {
+            // Fastpath zero and small values
+            if (this.signum() == 0 || fractionOnly() ||
+                // Fastpath very large-scale values that will result
+                // in a truncated value of zero. If the scale is -64
+                // or less, there are at least 64 powers of 10 in the
+                // value of the numerical result. Since 10 = 2*5, in
+                // that case there would also be 64 powers of 2 in the
+                // result, meaning all 64 bits of a long will be zero.
+                scale <= -64) {
+                return 0;
+            } else {
+                return toBigInteger().longValue();
+            }
+        }
+    }
+
+    /**
+     * Return true if a nonzero BigDecimal has an absolute value less
+     * than one; i.e. only has fraction digits.
+     */
+    private boolean fractionOnly() {
+        assert this.signum() != 0;
+        return (this.precision() - this.scale) <= 0;
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code long}, checking
+     * for lost information.  If this {@code BigDecimal} has a
+     * nonzero fractional part or is out of the possible range for a
+     * {@code long} result then an {@code ArithmeticException} is
+     * thrown.
+     *
+     * @return this {@code BigDecimal} converted to a {@code long}.
+     * @throws ArithmeticException if {@code this} has a nonzero
+     *         fractional part, or will not fit in a {@code long}.
+     * @since  1.5
+     */
+    public long longValueExact() {
+        if (intCompact != INFLATED && scale == 0)
+            return intCompact;
+
+        // Fastpath zero
+        if (this.signum() == 0)
+            return 0;
+
+        // Fastpath numbers less than 1.0 (the latter can be very slow
+        // to round if very small)
+        if (fractionOnly())
+            throw new ArithmeticException("Rounding necessary");
+
+        // If more than 19 digits in integer part it cannot possibly fit
+        if ((precision() - scale) > 19) // [OK for negative scale too]
+            throw new java.lang.ArithmeticException("Overflow");
+
+        // round to an integer, with Exception if decimal part non-0
+        BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
+        if (num.precision() >= 19) // need to check carefully
+            LongOverflow.check(num);
+        return num.inflated().longValue();
+    }
+
+    private static class LongOverflow {
+        /** BigInteger equal to Long.MIN_VALUE. */
+        private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
+
+        /** BigInteger equal to Long.MAX_VALUE. */
+        private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
+
+        public static void check(BigDecimal num) {
+            BigInteger intVal = num.inflated();
+            if (intVal.compareTo(LONGMIN) < 0 ||
+                intVal.compareTo(LONGMAX) > 0)
+                throw new java.lang.ArithmeticException("Overflow");
+        }
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to an {@code int}.
+     * This conversion is analogous to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code short} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * any fractional part of this
+     * {@code BigDecimal} will be discarded, and if the resulting
+     * "{@code BigInteger}" is too big to fit in an
+     * {@code int}, only the low-order 32 bits are returned.
+     * Note that this conversion can lose information about the
+     * overall magnitude and precision of this {@code BigDecimal}
+     * value as well as return a result with the opposite sign.
+     *
+     * @return this {@code BigDecimal} converted to an {@code int}.
+     */
+    public int intValue() {
+        return  (intCompact != INFLATED && scale == 0) ?
+            (int)intCompact :
+            (int)longValue();
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to an {@code int}, checking
+     * for lost information.  If this {@code BigDecimal} has a
+     * nonzero fractional part or is out of the possible range for an
+     * {@code int} result then an {@code ArithmeticException} is
+     * thrown.
+     *
+     * @return this {@code BigDecimal} converted to an {@code int}.
+     * @throws ArithmeticException if {@code this} has a nonzero
+     *         fractional part, or will not fit in an {@code int}.
+     * @since  1.5
+     */
+    public int intValueExact() {
+       long num;
+       num = this.longValueExact();     // will check decimal part
+       if ((int)num != num)
+           throw new java.lang.ArithmeticException("Overflow");
+       return (int)num;
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code short}, checking
+     * for lost information.  If this {@code BigDecimal} has a
+     * nonzero fractional part or is out of the possible range for a
+     * {@code short} result then an {@code ArithmeticException} is
+     * thrown.
+     *
+     * @return this {@code BigDecimal} converted to a {@code short}.
+     * @throws ArithmeticException if {@code this} has a nonzero
+     *         fractional part, or will not fit in a {@code short}.
+     * @since  1.5
+     */
+    public short shortValueExact() {
+       long num;
+       num = this.longValueExact();     // will check decimal part
+       if ((short)num != num)
+           throw new java.lang.ArithmeticException("Overflow");
+       return (short)num;
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code byte}, checking
+     * for lost information.  If this {@code BigDecimal} has a
+     * nonzero fractional part or is out of the possible range for a
+     * {@code byte} result then an {@code ArithmeticException} is
+     * thrown.
+     *
+     * @return this {@code BigDecimal} converted to a {@code byte}.
+     * @throws ArithmeticException if {@code this} has a nonzero
+     *         fractional part, or will not fit in a {@code byte}.
+     * @since  1.5
+     */
+    public byte byteValueExact() {
+       long num;
+       num = this.longValueExact();     // will check decimal part
+       if ((byte)num != num)
+           throw new java.lang.ArithmeticException("Overflow");
+       return (byte)num;
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code float}.
+     * This conversion is similar to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code float} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this {@code BigDecimal} has too great a
+     * magnitude to represent as a {@code float}, it will be
+     * converted to {@link Float#NEGATIVE_INFINITY} or {@link
+     * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
+     * the return value is finite, this conversion can lose
+     * information about the precision of the {@code BigDecimal}
+     * value.
+     *
+     * @return this {@code BigDecimal} converted to a {@code float}.
+     */
+    public float floatValue(){
+        if(intCompact != INFLATED) {
+            if (scale == 0) {
+                return (float)intCompact;
+            } else {
+                /*
+                 * If both intCompact and the scale can be exactly
+                 * represented as float values, perform a single float
+                 * multiply or divide to compute the (properly
+                 * rounded) result.
+                 */
+                if (Math.abs(intCompact) < 1L<<22 ) {
+                    // Don't have too guard against
+                    // Math.abs(MIN_VALUE) because of outer check
+                    // against INFLATED.
+                    if (scale > 0 && scale < float10pow.length) {
+                        return (float)intCompact / float10pow[scale];
+                    } else if (scale < 0 && scale > -float10pow.length) {
+                        return (float)intCompact * float10pow[-scale];
+                    }
+                }
+            }
+        }
+        // Somewhat inefficient, but guaranteed to work.
+        return Float.parseFloat(this.toString());
+    }
+
+    /**
+     * Converts this {@code BigDecimal} to a {@code double}.
+     * This conversion is similar to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code float} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this {@code BigDecimal} has too great a
+     * magnitude represent as a {@code double}, it will be
+     * converted to {@link Double#NEGATIVE_INFINITY} or {@link
+     * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
+     * the return value is finite, this conversion can lose
+     * information about the precision of the {@code BigDecimal}
+     * value.
+     *
+     * @return this {@code BigDecimal} converted to a {@code double}.
+     */
+    public double doubleValue(){
+        if(intCompact != INFLATED) {
+            if (scale == 0) {
+                return (double)intCompact;
+            } else {
+                /*
+                 * If both intCompact and the scale can be exactly
+                 * represented as double values, perform a single
+                 * double multiply or divide to compute the (properly
+                 * rounded) result.
+                 */
+                if (Math.abs(intCompact) < 1L<<52 ) {
+                    // Don't have too guard against
+                    // Math.abs(MIN_VALUE) because of outer check
+                    // against INFLATED.
+                    if (scale > 0 && scale < double10pow.length) {
+                        return (double)intCompact / double10pow[scale];
+                    } else if (scale < 0 && scale > -double10pow.length) {
+                        return (double)intCompact * double10pow[-scale];
+                    }
+                }
+            }
+        }
+        // Somewhat inefficient, but guaranteed to work.
+        return Double.parseDouble(this.toString());
+    }
+
+    /**
+     * Powers of 10 which can be represented exactly in {@code
+     * double}.
+     */
+    private static final double double10pow[] = {
+        1.0e0,  1.0e1,  1.0e2,  1.0e3,  1.0e4,  1.0e5,
+        1.0e6,  1.0e7,  1.0e8,  1.0e9,  1.0e10, 1.0e11,
+        1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17,
+        1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22
+    };
+
+    /**
+     * Powers of 10 which can be represented exactly in {@code
+     * float}.
+     */
+    private static final float float10pow[] = {
+        1.0e0f, 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
+        1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
+    };
+
+    /**
+     * Returns the size of an ulp, a unit in the last place, of this
+     * {@code BigDecimal}.  An ulp of a nonzero {@code BigDecimal}
+     * value is the positive distance between this value and the
+     * {@code BigDecimal} value next larger in magnitude with the
+     * same number of digits.  An ulp of a zero value is numerically
+     * equal to 1 with the scale of {@code this}.  The result is
+     * stored with the same scale as {@code this} so the result
+     * for zero and nonzero values is equal to {@code [1,
+     * this.scale()]}.
+     *
+     * @return the size of an ulp of {@code this}
+     * @since 1.5
+     */
+    public BigDecimal ulp() {
+        return BigDecimal.valueOf(1, this.scale(), 1);
+    }
+
+    // Private class to build a string representation for BigDecimal object.
+    // "StringBuilderHelper" is constructed as a thread local variable so it is
+    // thread safe. The StringBuilder field acts as a buffer to hold the temporary
+    // representation of BigDecimal. The cmpCharArray holds all the characters for
+    // the compact representation of BigDecimal (except for '-' sign' if it is
+    // negative) if its intCompact field is not INFLATED. It is shared by all
+    // calls to toString() and its variants in that particular thread.
+    static class StringBuilderHelper {
+        final StringBuilder sb;    // Placeholder for BigDecimal string
+        final char[] cmpCharArray; // character array to place the intCompact
+
+        StringBuilderHelper() {
+            sb = new StringBuilder();
+            // All non negative longs can be made to fit into 19 character array.
+            cmpCharArray = new char[19];
+        }
+
+        // Accessors.
+        StringBuilder getStringBuilder() {
+            sb.setLength(0);
+            return sb;
+        }
+
+        char[] getCompactCharArray() {
+            return cmpCharArray;
+        }
+
+        /**
+         * Places characters representing the intCompact in {@code long} into
+         * cmpCharArray and returns the offset to the array where the
+         * representation starts.
+         *
+         * @param intCompact the number to put into the cmpCharArray.
+         * @return offset to the array where the representation starts.
+         * Note: intCompact must be greater or equal to zero.
+         */
+        int putIntCompact(long intCompact) {
+            assert intCompact >= 0;
+
+            long q;
+            int r;
+            // since we start from the least significant digit, charPos points to
+            // the last character in cmpCharArray.
+            int charPos = cmpCharArray.length;
+
+            // Get 2 digits/iteration using longs until quotient fits into an int
+            while (intCompact > Integer.MAX_VALUE) {
+                q = intCompact / 100;
+                r = (int)(intCompact - q * 100);
+                intCompact = q;
+                cmpCharArray[--charPos] = DIGIT_ONES[r];
+                cmpCharArray[--charPos] = DIGIT_TENS[r];
+            }
+
+            // Get 2 digits/iteration using ints when i2 >= 100
+            int q2;
+            int i2 = (int)intCompact;
+            while (i2 >= 100) {
+                q2 = i2 / 100;
+                r  = i2 - q2 * 100;
+                i2 = q2;
+                cmpCharArray[--charPos] = DIGIT_ONES[r];
+                cmpCharArray[--charPos] = DIGIT_TENS[r];
+            }
+
+            cmpCharArray[--charPos] = DIGIT_ONES[i2];
+            if (i2 >= 10)
+                cmpCharArray[--charPos] = DIGIT_TENS[i2];
+
+            return charPos;
+        }
+
+        final static char[] DIGIT_TENS = {
+            '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+            '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
+            '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
+            '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
+            '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
+            '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
+            '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
+            '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
+            '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
+            '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
+        };
+
+        final static char[] DIGIT_ONES = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        };
+    }
+
+    /**
+     * Lay out this {@code BigDecimal} into a {@code char[]} array.
+     * The Java 1.2 equivalent to this was called {@code getValueString}.
+     *
+     * @param  sci {@code true} for Scientific exponential notation;
+     *          {@code false} for Engineering
+     * @return string with canonical string representation of this
+     *         {@code BigDecimal}
+     */
+    private String layoutChars(boolean sci) {
+        if (scale == 0)                      // zero scale is trivial
+            return (intCompact != INFLATED) ?
+                Long.toString(intCompact):
+                intVal.toString();
+        if (scale == 2  &&
+            intCompact >= 0 && intCompact < Integer.MAX_VALUE) {
+            // currency fast path
+            int lowInt = (int)intCompact % 100;
+            int highInt = (int)intCompact / 100;
+            return (Integer.toString(highInt) + '.' +
+                    StringBuilderHelper.DIGIT_TENS[lowInt] +
+                    StringBuilderHelper.DIGIT_ONES[lowInt]) ;
+        }
+
+        StringBuilderHelper sbHelper = threadLocalStringBuilderHelper.get();
+        char[] coeff;
+        int offset;  // offset is the starting index for coeff array
+        // Get the significand as an absolute value
+        if (intCompact != INFLATED) {
+            offset = sbHelper.putIntCompact(Math.abs(intCompact));
+            coeff  = sbHelper.getCompactCharArray();
+        } else {
+            offset = 0;
+            coeff  = intVal.abs().toString().toCharArray();
+        }
+
+        // Construct a buffer, with sufficient capacity for all cases.
+        // If E-notation is needed, length will be: +1 if negative, +1
+        // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent.
+        // Otherwise it could have +1 if negative, plus leading "0.00000"
+        StringBuilder buf = sbHelper.getStringBuilder();
+        if (signum() < 0)             // prefix '-' if negative
+            buf.append('-');
+        int coeffLen = coeff.length - offset;
+        long adjusted = -(long)scale + (coeffLen -1);
+        if ((scale >= 0) && (adjusted >= -6)) { // plain number
+            int pad = scale - coeffLen;         // count of padding zeros
+            if (pad >= 0) {                     // 0.xxx form
+                buf.append('0');
+                buf.append('.');
+                for (; pad>0; pad--) {
+                    buf.append('0');
+                }
+                buf.append(coeff, offset, coeffLen);
+            } else {                         // xx.xx form
+                buf.append(coeff, offset, -pad);
+                buf.append('.');
+                buf.append(coeff, -pad + offset, scale);
+            }
+        } else { // E-notation is needed
+            if (sci) {                       // Scientific notation
+                buf.append(coeff[offset]);   // first character
+                if (coeffLen > 1) {          // more to come
+                    buf.append('.');
+                    buf.append(coeff, offset + 1, coeffLen - 1);
+                }
+            } else {                         // Engineering notation
+                int sig = (int)(adjusted % 3);
+                if (sig < 0)
+                    sig += 3;                // [adjusted was negative]
+                adjusted -= sig;             // now a multiple of 3
+                sig++;
+                if (signum() == 0) {
+                    switch (sig) {
+                    case 1:
+                        buf.append('0'); // exponent is a multiple of three
+                        break;
+                    case 2:
+                        buf.append("0.00");
+                        adjusted += 3;
+                        break;
+                    case 3:
+                        buf.append("0.0");
+                        adjusted += 3;
+                        break;
+                    default:
+                        throw new AssertionError("Unexpected sig value " + sig);
+                    }
+                } else if (sig >= coeffLen) {   // significand all in integer
+                    buf.append(coeff, offset, coeffLen);
+                    // may need some zeros, too
+                    for (int i = sig - coeffLen; i > 0; i--)
+                        buf.append('0');
+                } else {                     // xx.xxE form
+                    buf.append(coeff, offset, sig);
+                    buf.append('.');
+                    buf.append(coeff, offset + sig, coeffLen - sig);
+                }
+            }
+            if (adjusted != 0) {             // [!sci could have made 0]
+                buf.append('E');
+                if (adjusted > 0)            // force sign for positive
+                    buf.append('+');
+                buf.append(adjusted);
+            }
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Return 10 to the power n, as a {@code BigInteger}.
+     *
+     * @param  n the power of ten to be returned (>=0)
+     * @return a {@code BigInteger} with the value (10<sup>n</sup>)
+     */
+    private static BigInteger bigTenToThe(int n) {
+        if (n < 0)
+            return BigInteger.ZERO;
+
+        if (n < BIG_TEN_POWERS_TABLE_MAX) {
+            BigInteger[] pows = BIG_TEN_POWERS_TABLE;
+            if (n < pows.length)
+                return pows[n];
+            else
+                return expandBigIntegerTenPowers(n);
+        }
+
+        return BigInteger.TEN.pow(n);
+    }
+
+    /**
+     * Expand the BIG_TEN_POWERS_TABLE array to contain at least 10**n.
+     *
+     * @param n the power of ten to be returned (>=0)
+     * @return a {@code BigDecimal} with the value (10<sup>n</sup>) and
+     *         in the meantime, the BIG_TEN_POWERS_TABLE array gets
+     *         expanded to the size greater than n.
+     */
+    private static BigInteger expandBigIntegerTenPowers(int n) {
+        synchronized(BigDecimal.class) {
+            BigInteger[] pows = BIG_TEN_POWERS_TABLE;
+            int curLen = pows.length;
+            // The following comparison and the above synchronized statement is
+            // to prevent multiple threads from expanding the same array.
+            if (curLen <= n) {
+                int newLen = curLen << 1;
+                while (newLen <= n)
+                    newLen <<= 1;
+                pows = Arrays.copyOf(pows, newLen);
+                for (int i = curLen; i < newLen; i++)
+                    pows[i] = pows[i - 1].multiply(BigInteger.TEN);
+                // Based on the following facts:
+                // 1. pows is a private local variable;
+                // 2. the following store is a volatile store.
+                // the newly created array elements can be safely published.
+                BIG_TEN_POWERS_TABLE = pows;
+            }
+            return pows[n];
+        }
+    }
+
+    private static final long[] LONG_TEN_POWERS_TABLE = {
+        1,                     // 0 / 10^0
+        10,                    // 1 / 10^1
+        100,                   // 2 / 10^2
+        1000,                  // 3 / 10^3
+        10000,                 // 4 / 10^4
+        100000,                // 5 / 10^5
+        1000000,               // 6 / 10^6
+        10000000,              // 7 / 10^7
+        100000000,             // 8 / 10^8
+        1000000000,            // 9 / 10^9
+        10000000000L,          // 10 / 10^10
+        100000000000L,         // 11 / 10^11
+        1000000000000L,        // 12 / 10^12
+        10000000000000L,       // 13 / 10^13
+        100000000000000L,      // 14 / 10^14
+        1000000000000000L,     // 15 / 10^15
+        10000000000000000L,    // 16 / 10^16
+        100000000000000000L,   // 17 / 10^17
+        1000000000000000000L   // 18 / 10^18
+    };
+
+    private static volatile BigInteger BIG_TEN_POWERS_TABLE[] = {
+        BigInteger.ONE,
+        BigInteger.valueOf(10),
+        BigInteger.valueOf(100),
+        BigInteger.valueOf(1000),
+        BigInteger.valueOf(10000),
+        BigInteger.valueOf(100000),
+        BigInteger.valueOf(1000000),
+        BigInteger.valueOf(10000000),
+        BigInteger.valueOf(100000000),
+        BigInteger.valueOf(1000000000),
+        BigInteger.valueOf(10000000000L),
+        BigInteger.valueOf(100000000000L),
+        BigInteger.valueOf(1000000000000L),
+        BigInteger.valueOf(10000000000000L),
+        BigInteger.valueOf(100000000000000L),
+        BigInteger.valueOf(1000000000000000L),
+        BigInteger.valueOf(10000000000000000L),
+        BigInteger.valueOf(100000000000000000L),
+        BigInteger.valueOf(1000000000000000000L)
+    };
+
+    private static final int BIG_TEN_POWERS_TABLE_INITLEN =
+        BIG_TEN_POWERS_TABLE.length;
+    private static final int BIG_TEN_POWERS_TABLE_MAX =
+        16 * BIG_TEN_POWERS_TABLE_INITLEN;
+
+    private static final long THRESHOLDS_TABLE[] = {
+        Long.MAX_VALUE,                     // 0
+        Long.MAX_VALUE/10L,                 // 1
+        Long.MAX_VALUE/100L,                // 2
+        Long.MAX_VALUE/1000L,               // 3
+        Long.MAX_VALUE/10000L,              // 4
+        Long.MAX_VALUE/100000L,             // 5
+        Long.MAX_VALUE/1000000L,            // 6
+        Long.MAX_VALUE/10000000L,           // 7
+        Long.MAX_VALUE/100000000L,          // 8
+        Long.MAX_VALUE/1000000000L,         // 9
+        Long.MAX_VALUE/10000000000L,        // 10
+        Long.MAX_VALUE/100000000000L,       // 11
+        Long.MAX_VALUE/1000000000000L,      // 12
+        Long.MAX_VALUE/10000000000000L,     // 13
+        Long.MAX_VALUE/100000000000000L,    // 14
+        Long.MAX_VALUE/1000000000000000L,   // 15
+        Long.MAX_VALUE/10000000000000000L,  // 16
+        Long.MAX_VALUE/100000000000000000L, // 17
+        Long.MAX_VALUE/1000000000000000000L // 18
+    };
+
+    /**
+     * Compute val * 10 ^ n; return this product if it is
+     * representable as a long, INFLATED otherwise.
+     */
+    private static long longMultiplyPowerTen(long val, int n) {
+        if (val == 0 || n <= 0)
+            return val;
+        long[] tab = LONG_TEN_POWERS_TABLE;
+        long[] bounds = THRESHOLDS_TABLE;
+        if (n < tab.length && n < bounds.length) {
+            long tenpower = tab[n];
+            if (val == 1)
+                return tenpower;
+            if (Math.abs(val) <= bounds[n])
+                return val * tenpower;
+        }
+        return INFLATED;
+    }
+
+    /**
+     * Compute this * 10 ^ n.
+     * Needed mainly to allow special casing to trap zero value
+     */
+    private BigInteger bigMultiplyPowerTen(int n) {
+        if (n <= 0)
+            return this.inflated();
+
+        if (intCompact != INFLATED)
+            return bigTenToThe(n).multiply(intCompact);
+        else
+            return intVal.multiply(bigTenToThe(n));
+    }
+
+    /**
+     * Returns appropriate BigInteger from intVal field if intVal is
+     * null, i.e. the compact representation is in use.
+     */
+    private BigInteger inflated() {
+        if (intVal == null) {
+            return BigInteger.valueOf(intCompact);
+        }
+        return intVal;
+    }
+
+    /**
+     * Match the scales of two {@code BigDecimal}s to align their
+     * least significant digits.
+     *
+     * <p>If the scales of val[0] and val[1] differ, rescale
+     * (non-destructively) the lower-scaled {@code BigDecimal} so
+     * they match.  That is, the lower-scaled reference will be
+     * replaced by a reference to a new object with the same scale as
+     * the other {@code BigDecimal}.
+     *
+     * @param  val array of two elements referring to the two
+     *         {@code BigDecimal}s to be aligned.
+     */
+    private static void matchScale(BigDecimal[] val) {
+        if (val[0].scale == val[1].scale) {
+            return;
+        } else if (val[0].scale < val[1].scale) {
+            val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY);
+        } else if (val[1].scale < val[0].scale) {
+            val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY);
+        }
+    }
+
+    private static class UnsafeHolder {
+        private static final sun.misc.Unsafe unsafe;
+        private static final long intCompactOffset;
+        private static final long intValOffset;
+        static {
+            try {
+                unsafe = sun.misc.Unsafe.getUnsafe();
+                intCompactOffset = unsafe.objectFieldOffset
+                    (BigDecimal.class.getDeclaredField("intCompact"));
+                intValOffset = unsafe.objectFieldOffset
+                    (BigDecimal.class.getDeclaredField("intVal"));
+            } catch (Exception ex) {
+                throw new ExceptionInInitializerError(ex);
+            }
+        }
+        static void setIntCompactVolatile(BigDecimal bd, long val) {
+            unsafe.putLongVolatile(bd, intCompactOffset, val);
+        }
+
+        static void setIntValVolatile(BigDecimal bd, BigInteger val) {
+            unsafe.putObjectVolatile(bd, intValOffset, val);
+        }
+    }
+
+    /**
+     * Reconstitute the {@code BigDecimal} instance from a stream (that is,
+     * deserialize it).
+     *
+     * @param s the stream being read.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        // Read in all fields
+        s.defaultReadObject();
+        // validate possibly bad fields
+        if (intVal == null) {
+            String message = "BigDecimal: null intVal in stream";
+            throw new java.io.StreamCorruptedException(message);
+        // [all values of scale are now allowed]
+        }
+        UnsafeHolder.setIntCompactVolatile(this, compactValFor(intVal));
+    }
+
+   /**
+    * Serialize this {@code BigDecimal} to the stream in question
+    *
+    * @param s the stream to serialize to.
+    */
+   private void writeObject(java.io.ObjectOutputStream s)
+       throws java.io.IOException {
+       // Must inflate to maintain compatible serial form.
+       if (this.intVal == null)
+           UnsafeHolder.setIntValVolatile(this, BigInteger.valueOf(this.intCompact));
+       // Could reset intVal back to null if it has to be set.
+       s.defaultWriteObject();
+   }
+
+    /**
+     * Returns the length of the absolute value of a {@code long}, in decimal
+     * digits.
+     *
+     * @param x the {@code long}
+     * @return the length of the unscaled value, in deciaml digits.
+     */
+    static int longDigitLength(long x) {
+        /*
+         * As described in "Bit Twiddling Hacks" by Sean Anderson,
+         * (http://graphics.stanford.edu/~seander/bithacks.html)
+         * integer log 10 of x is within 1 of (1233/4096)* (1 +
+         * integer log 2 of x). The fraction 1233/4096 approximates
+         * log10(2). So we first do a version of log2 (a variant of
+         * Long class with pre-checks and opposite directionality) and
+         * then scale and check against powers table. This is a little
+         * simpler in present context than the version in Hacker's
+         * Delight sec 11-4. Adding one to bit length allows comparing
+         * downward from the LONG_TEN_POWERS_TABLE that we need
+         * anyway.
+         */
+        assert x != BigDecimal.INFLATED;
+        if (x < 0)
+            x = -x;
+        if (x < 10) // must screen for 0, might as well 10
+            return 1;
+        int r = ((64 - Long.numberOfLeadingZeros(x) + 1) * 1233) >>> 12;
+        long[] tab = LONG_TEN_POWERS_TABLE;
+        // if r >= length, must have max possible digits for long
+        return (r >= tab.length || x < tab[r]) ? r : r + 1;
+    }
+
+    /**
+     * Returns the length of the absolute value of a BigInteger, in
+     * decimal digits.
+     *
+     * @param b the BigInteger
+     * @return the length of the unscaled value, in decimal digits
+     */
+    private static int bigDigitLength(BigInteger b) {
+        /*
+         * Same idea as the long version, but we need a better
+         * approximation of log10(2). Using 646456993/2^31
+         * is accurate up to max possible reported bitLength.
+         */
+        if (b.signum == 0)
+            return 1;
+        int r = (int)((((long)b.bitLength() + 1) * 646456993) >>> 31);
+        return b.compareMagnitude(bigTenToThe(r)) < 0? r : r+1;
+    }
+
+    /**
+     * Check a scale for Underflow or Overflow.  If this BigDecimal is
+     * nonzero, throw an exception if the scale is outof range. If this
+     * is zero, saturate the scale to the extreme value of the right
+     * sign if the scale is out of range.
+     *
+     * @param val The new scale.
+     * @throws ArithmeticException (overflow or underflow) if the new
+     *         scale is out of range.
+     * @return validated scale as an int.
+     */
+    private int checkScale(long val) {
+        int asInt = (int)val;
+        if (asInt != val) {
+            asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+            BigInteger b;
+            if (intCompact != 0 &&
+                ((b = intVal) == null || b.signum() != 0))
+                throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
+        }
+        return asInt;
+    }
+
+   /**
+     * Returns the compact value for given {@code BigInteger}, or
+     * INFLATED if too big. Relies on internal representation of
+     * {@code BigInteger}.
+     */
+    private static long compactValFor(BigInteger b) {
+        int[] m = b.mag;
+        int len = m.length;
+        if (len == 0)
+            return 0;
+        int d = m[0];
+        if (len > 2 || (len == 2 && d < 0))
+            return INFLATED;
+
+        long u = (len == 2)?
+            (((long) m[1] & LONG_MASK) + (((long)d) << 32)) :
+            (((long)d)   & LONG_MASK);
+        return (b.signum < 0)? -u : u;
+    }
+
+    private static int longCompareMagnitude(long x, long y) {
+        if (x < 0)
+            x = -x;
+        if (y < 0)
+            y = -y;
+        return (x < y) ? -1 : ((x == y) ? 0 : 1);
+    }
+
+    private static int saturateLong(long s) {
+        int i = (int)s;
+        return (s == i) ? i : (s < 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE);
+    }
+
+    /*
+     * Internal printing routine
+     */
+    private static void print(String name, BigDecimal bd) {
+        System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n",
+                          name,
+                          bd.intCompact,
+                          bd.intVal,
+                          bd.scale,
+                          bd.precision);
+    }
+
+    /**
+     * Check internal invariants of this BigDecimal.  These invariants
+     * include:
+     *
+     * <ul>
+     *
+     * <li>The object must be initialized; either intCompact must not be
+     * INFLATED or intVal is non-null.  Both of these conditions may
+     * be true.
+     *
+     * <li>If both intCompact and intVal and set, their values must be
+     * consistent.
+     *
+     * <li>If precision is nonzero, it must have the right value.
+     * </ul>
+     *
+     * Note: Since this is an audit method, we are not supposed to change the
+     * state of this BigDecimal object.
+     */
+    private BigDecimal audit() {
+        if (intCompact == INFLATED) {
+            if (intVal == null) {
+                print("audit", this);
+                throw new AssertionError("null intVal");
+            }
+            // Check precision
+            if (precision > 0 && precision != bigDigitLength(intVal)) {
+                print("audit", this);
+                throw new AssertionError("precision mismatch");
+            }
+        } else {
+            if (intVal != null) {
+                long val = intVal.longValue();
+                if (val != intCompact) {
+                    print("audit", this);
+                    throw new AssertionError("Inconsistent state, intCompact=" +
+                                             intCompact + "\t intVal=" + val);
+                }
+            }
+            // Check precision
+            if (precision > 0 && precision != longDigitLength(intCompact)) {
+                print("audit", this);
+                throw new AssertionError("precision mismatch");
+            }
+        }
+        return this;
+    }
+
+    /* the same as checkScale where value!=0 */
+    private static int checkScaleNonZero(long val) {
+        int asInt = (int)val;
+        if (asInt != val) {
+            throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
+        }
+        return asInt;
+    }
+
+    private static int checkScale(long intCompact, long val) {
+        int asInt = (int)val;
+        if (asInt != val) {
+            asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+            if (intCompact != 0)
+                throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
+        }
+        return asInt;
+    }
+
+    private static int checkScale(BigInteger intVal, long val) {
+        int asInt = (int)val;
+        if (asInt != val) {
+            asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
+            if (intVal.signum() != 0)
+                throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
+        }
+        return asInt;
+    }
+
+    /**
+     * Returns a {@code BigDecimal} rounded according to the MathContext
+     * settings;
+     * If rounding is needed a new {@code BigDecimal} is created and returned.
+     *
+     * @param val the value to be rounded
+     * @param mc the context to use.
+     * @return a {@code BigDecimal} rounded according to the MathContext
+     *         settings.  May return {@code value}, if no rounding needed.
+     * @throws ArithmeticException if the rounding mode is
+     *         {@code RoundingMode.UNNECESSARY} and the
+     *         result is inexact.
+     */
+    private static BigDecimal doRound(BigDecimal val, MathContext mc) {
+        int mcp = mc.precision;
+        boolean wasDivided = false;
+        if (mcp > 0) {
+            BigInteger intVal = val.intVal;
+            long compactVal = val.intCompact;
+            int scale = val.scale;
+            int prec = val.precision();
+            int mode = mc.roundingMode.oldMode;
+            int drop;
+            if (compactVal == INFLATED) {
+                drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    intVal = divideAndRoundByTenPow(intVal, drop, mode);
+                    wasDivided = true;
+                    compactVal = compactValFor(intVal);
+                    if (compactVal != INFLATED) {
+                        prec = longDigitLength(compactVal);
+                        break;
+                    }
+                    prec = bigDigitLength(intVal);
+                    drop = prec - mcp;
+                }
+            }
+            if (compactVal != INFLATED) {
+                drop = prec - mcp;  // drop can't be more than 18
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                    wasDivided = true;
+                    prec = longDigitLength(compactVal);
+                    drop = prec - mcp;
+                    intVal = null;
+                }
+            }
+            return wasDivided ? new BigDecimal(intVal,compactVal,scale,prec) : val;
+        }
+        return val;
+    }
+
+    /*
+     * Returns a {@code BigDecimal} created from {@code long} value with
+     * given scale rounded according to the MathContext settings
+     */
+    private static BigDecimal doRound(long compactVal, int scale, MathContext mc) {
+        int mcp = mc.precision;
+        if (mcp > 0 && mcp < 19) {
+            int prec = longDigitLength(compactVal);
+            int drop = prec - mcp;  // drop can't be more than 18
+            while (drop > 0) {
+                scale = checkScaleNonZero((long) scale - drop);
+                compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                prec = longDigitLength(compactVal);
+                drop = prec - mcp;
+            }
+            return valueOf(compactVal, scale, prec);
+        }
+        return valueOf(compactVal, scale);
+    }
+
+    /*
+     * Returns a {@code BigDecimal} created from {@code BigInteger} value with
+     * given scale rounded according to the MathContext settings
+     */
+    private static BigDecimal doRound(BigInteger intVal, int scale, MathContext mc) {
+        int mcp = mc.precision;
+        int prec = 0;
+        if (mcp > 0) {
+            long compactVal = compactValFor(intVal);
+            int mode = mc.roundingMode.oldMode;
+            int drop;
+            if (compactVal == INFLATED) {
+                prec = bigDigitLength(intVal);
+                drop = prec - mcp;
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    intVal = divideAndRoundByTenPow(intVal, drop, mode);
+                    compactVal = compactValFor(intVal);
+                    if (compactVal != INFLATED) {
+                        break;
+                    }
+                    prec = bigDigitLength(intVal);
+                    drop = prec - mcp;
+                }
+            }
+            if (compactVal != INFLATED) {
+                prec = longDigitLength(compactVal);
+                drop = prec - mcp;     // drop can't be more than 18
+                while (drop > 0) {
+                    scale = checkScaleNonZero((long) scale - drop);
+                    compactVal = divideAndRound(compactVal, LONG_TEN_POWERS_TABLE[drop], mc.roundingMode.oldMode);
+                    prec = longDigitLength(compactVal);
+                    drop = prec - mcp;
+                }
+                return valueOf(compactVal,scale,prec);
+            }
+        }
+        return new BigDecimal(intVal,INFLATED,scale,prec);
+    }
+
+    /*
+     * Divides {@code BigInteger} value by ten power.
+     */
+    private static BigInteger divideAndRoundByTenPow(BigInteger intVal, int tenPow, int roundingMode) {
+        if (tenPow < LONG_TEN_POWERS_TABLE.length)
+            intVal = divideAndRound(intVal, LONG_TEN_POWERS_TABLE[tenPow], roundingMode);
+        else
+            intVal = divideAndRound(intVal, bigTenToThe(tenPow), roundingMode);
+        return intVal;
+    }
+
+    /**
+     * Internally used for division operation for division {@code long} by
+     * {@code long}.
+     * The returned {@code BigDecimal} object is the quotient whose scale is set
+     * to the passed in scale. If the remainder is not zero, it will be rounded
+     * based on the passed in roundingMode. Also, if the remainder is zero and
+     * the last parameter, i.e. preferredScale is NOT equal to scale, the
+     * trailing zeros of the result is stripped to match the preferredScale.
+     */
+    private static BigDecimal divideAndRound(long ldividend, long ldivisor, int scale, int roundingMode,
+                                             int preferredScale) {
+
+        int qsign; // quotient sign
+        long q = ldividend / ldivisor; // store quotient in long
+        if (roundingMode == ROUND_DOWN && scale == preferredScale)
+            return valueOf(q, scale);
+        long r = ldividend % ldivisor; // store remainder in long
+        qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
+        if (r != 0) {
+            boolean increment = needIncrement(ldivisor, roundingMode, qsign, q, r);
+            return valueOf((increment ? q + qsign : q), scale);
+        } else {
+            if (preferredScale != scale)
+                return createAndStripZerosToMatchScale(q, scale, preferredScale);
+            else
+                return valueOf(q, scale);
+        }
+    }
+
+    /**
+     * Divides {@code long} by {@code long} and do rounding based on the
+     * passed in roundingMode.
+     */
+    private static long divideAndRound(long ldividend, long ldivisor, int roundingMode) {
+        int qsign; // quotient sign
+        long q = ldividend / ldivisor; // store quotient in long
+        if (roundingMode == ROUND_DOWN)
+            return q;
+        long r = ldividend % ldivisor; // store remainder in long
+        qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
+        if (r != 0) {
+            boolean increment = needIncrement(ldivisor, roundingMode, qsign, q,     r);
+            return increment ? q + qsign : q;
+        } else {
+            return q;
+        }
+    }
+
+    /**
+     * Shared logic of need increment computation.
+     */
+    private static boolean commonNeedIncrement(int roundingMode, int qsign,
+                                        int cmpFracHalf, boolean oddQuot) {
+        switch(roundingMode) {
+        case ROUND_UNNECESSARY:
+            throw new ArithmeticException("Rounding necessary");
+
+        case ROUND_UP: // Away from zero
+            return true;
+
+        case ROUND_DOWN: // Towards zero
+            return false;
+
+        case ROUND_CEILING: // Towards +infinity
+            return qsign > 0;
+
+        case ROUND_FLOOR: // Towards -infinity
+            return qsign < 0;
+
+        default: // Some kind of half-way rounding
+            assert roundingMode >= ROUND_HALF_UP &&
+                roundingMode <= ROUND_HALF_EVEN: "Unexpected rounding mode" + RoundingMode.valueOf(roundingMode);
+
+            if (cmpFracHalf < 0 ) // We're closer to higher digit
+                return false;
+            else if (cmpFracHalf > 0 ) // We're closer to lower digit
+                return true;
+            else { // half-way
+                assert cmpFracHalf == 0;
+
+                switch(roundingMode) {
+                case ROUND_HALF_DOWN:
+                    return false;
+
+                case ROUND_HALF_UP:
+                    return true;
+
+                case ROUND_HALF_EVEN:
+                    return oddQuot;
+
+                default:
+                    throw new AssertionError("Unexpected rounding mode" + roundingMode);
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests if quotient has to be incremented according the roundingMode
+     */
+    private static boolean needIncrement(long ldivisor, int roundingMode,
+                                         int qsign, long q, long r) {
+        assert r != 0L;
+
+        int cmpFracHalf;
+        if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
+            cmpFracHalf = 1; // 2 * r can't fit into long
+        } else {
+            cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
+        }
+
+        return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, (q & 1L) != 0L);
+    }
+
+    /**
+     * Divides {@code BigInteger} value by {@code long} value and
+     * do rounding based on the passed in roundingMode.
+     */
+    private static BigInteger divideAndRound(BigInteger bdividend, long ldivisor, int roundingMode) {
+        boolean isRemainderZero; // record remainder is zero or not
+        int qsign; // quotient sign
+        long r = 0; // store quotient & remainder in long
+        MutableBigInteger mq = null; // store quotient
+        // Descend into mutables for faster remainder checks
+        MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
+        mq = new MutableBigInteger();
+        r = mdividend.divide(ldivisor, mq);
+        isRemainderZero = (r == 0);
+        qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
+        if (!isRemainderZero) {
+            if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) {
+                mq.add(MutableBigInteger.ONE);
+            }
+        }
+        return mq.toBigInteger(qsign);
+    }
+
+    /**
+     * Internally used for division operation for division {@code BigInteger}
+     * by {@code long}.
+     * The returned {@code BigDecimal} object is the quotient whose scale is set
+     * to the passed in scale. If the remainder is not zero, it will be rounded
+     * based on the passed in roundingMode. Also, if the remainder is zero and
+     * the last parameter, i.e. preferredScale is NOT equal to scale, the
+     * trailing zeros of the result is stripped to match the preferredScale.
+     */
+    private static BigDecimal divideAndRound(BigInteger bdividend,
+                                             long ldivisor, int scale, int roundingMode, int preferredScale) {
+        boolean isRemainderZero; // record remainder is zero or not
+        int qsign; // quotient sign
+        long r = 0; // store quotient & remainder in long
+        MutableBigInteger mq = null; // store quotient
+        // Descend into mutables for faster remainder checks
+        MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
+        mq = new MutableBigInteger();
+        r = mdividend.divide(ldivisor, mq);
+        isRemainderZero = (r == 0);
+        qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
+        if (!isRemainderZero) {
+            if(needIncrement(ldivisor, roundingMode, qsign, mq, r)) {
+                mq.add(MutableBigInteger.ONE);
+            }
+            return mq.toBigDecimal(qsign, scale);
+        } else {
+            if (preferredScale != scale) {
+                long compactVal = mq.toCompactValue(qsign);
+                if(compactVal!=INFLATED) {
+                    return createAndStripZerosToMatchScale(compactVal, scale, preferredScale);
+                }
+                BigInteger intVal =  mq.toBigInteger(qsign);
+                return createAndStripZerosToMatchScale(intVal,scale, preferredScale);
+            } else {
+                return mq.toBigDecimal(qsign, scale);
+            }
+        }
+    }
+
+    /**
+     * Tests if quotient has to be incremented according the roundingMode
+     */
+    private static boolean needIncrement(long ldivisor, int roundingMode,
+                                         int qsign, MutableBigInteger mq, long r) {
+        assert r != 0L;
+
+        int cmpFracHalf;
+        if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
+            cmpFracHalf = 1; // 2 * r can't fit into long
+        } else {
+            cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
+        }
+
+        return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, mq.isOdd());
+    }
+
+    /**
+     * Divides {@code BigInteger} value by {@code BigInteger} value and
+     * do rounding based on the passed in roundingMode.
+     */
+    private static BigInteger divideAndRound(BigInteger bdividend, BigInteger bdivisor, int roundingMode) {
+        boolean isRemainderZero; // record remainder is zero or not
+        int qsign; // quotient sign
+        // Descend into mutables for faster remainder checks
+        MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
+        MutableBigInteger mq = new MutableBigInteger();
+        MutableBigInteger mdivisor = new MutableBigInteger(bdivisor.mag);
+        MutableBigInteger mr = mdividend.divide(mdivisor, mq);
+        isRemainderZero = mr.isZero();
+        qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
+        if (!isRemainderZero) {
+            if (needIncrement(mdivisor, roundingMode, qsign, mq, mr)) {
+                mq.add(MutableBigInteger.ONE);
+            }
+        }
+        return mq.toBigInteger(qsign);
+    }
+
+    /**
+     * Internally used for division operation for division {@code BigInteger}
+     * by {@code BigInteger}.
+     * The returned {@code BigDecimal} object is the quotient whose scale is set
+     * to the passed in scale. If the remainder is not zero, it will be rounded
+     * based on the passed in roundingMode. Also, if the remainder is zero and
+     * the last parameter, i.e. preferredScale is NOT equal to scale, the
+     * trailing zeros of the result is stripped to match the preferredScale.
+     */
+    private static BigDecimal divideAndRound(BigInteger bdividend, BigInteger bdivisor, int scale, int roundingMode,
+                                             int preferredScale) {
+        boolean isRemainderZero; // record remainder is zero or not
+        int qsign; // quotient sign
+        // Descend into mutables for faster remainder checks
+        MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
+        MutableBigInteger mq = new MutableBigInteger();
+        MutableBigInteger mdivisor = new MutableBigInteger(bdivisor.mag);
+        MutableBigInteger mr = mdividend.divide(mdivisor, mq);
+        isRemainderZero = mr.isZero();
+        qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
+        if (!isRemainderZero) {
+            if (needIncrement(mdivisor, roundingMode, qsign, mq, mr)) {
+                mq.add(MutableBigInteger.ONE);
+            }
+            return mq.toBigDecimal(qsign, scale);
+        } else {
+            if (preferredScale != scale) {
+                long compactVal = mq.toCompactValue(qsign);
+                if (compactVal != INFLATED) {
+                    return createAndStripZerosToMatchScale(compactVal, scale, preferredScale);
+                }
+                BigInteger intVal = mq.toBigInteger(qsign);
+                return createAndStripZerosToMatchScale(intVal, scale, preferredScale);
+            } else {
+                return mq.toBigDecimal(qsign, scale);
+            }
+        }
+    }
+
+    /**
+     * Tests if quotient has to be incremented according the roundingMode
+     */
+    private static boolean needIncrement(MutableBigInteger mdivisor, int roundingMode,
+                                         int qsign, MutableBigInteger mq, MutableBigInteger mr) {
+        assert !mr.isZero();
+        int cmpFracHalf = mr.compareHalf(mdivisor);
+        return commonNeedIncrement(roundingMode, qsign, cmpFracHalf, mq.isOdd());
+    }
+
+    /**
+     * Remove insignificant trailing zeros from this
+     * {@code BigInteger} value until the preferred scale is reached or no
+     * more zeros can be removed.  If the preferred scale is less than
+     * Integer.MIN_VALUE, all the trailing zeros will be removed.
+     *
+     * @return new {@code BigDecimal} with a scale possibly reduced
+     * to be closed to the preferred scale.
+     */
+    private static BigDecimal createAndStripZerosToMatchScale(BigInteger intVal, int scale, long preferredScale) {
+        BigInteger qr[]; // quotient-remainder pair
+        while (intVal.compareMagnitude(BigInteger.TEN) >= 0
+               && scale > preferredScale) {
+            if (intVal.testBit(0))
+                break; // odd number cannot end in 0
+            qr = intVal.divideAndRemainder(BigInteger.TEN);
+            if (qr[1].signum() != 0)
+                break; // non-0 remainder
+            intVal = qr[0];
+            scale = checkScale(intVal,(long) scale - 1); // could Overflow
+        }
+        return valueOf(intVal, scale, 0);
+    }
+
+    /**
+     * Remove insignificant trailing zeros from this
+     * {@code long} value until the preferred scale is reached or no
+     * more zeros can be removed.  If the preferred scale is less than
+     * Integer.MIN_VALUE, all the trailing zeros will be removed.
+     *
+     * @return new {@code BigDecimal} with a scale possibly reduced
+     * to be closed to the preferred scale.
+     */
+    private static BigDecimal createAndStripZerosToMatchScale(long compactVal, int scale, long preferredScale) {
+        while (Math.abs(compactVal) >= 10L && scale > preferredScale) {
+            if ((compactVal & 1L) != 0L)
+                break; // odd number cannot end in 0
+            long r = compactVal % 10L;
+            if (r != 0L)
+                break; // non-0 remainder
+            compactVal /= 10;
+            scale = checkScale(compactVal, (long) scale - 1); // could Overflow
+        }
+        return valueOf(compactVal, scale);
+    }
+
+    private static BigDecimal stripZerosToMatchScale(BigInteger intVal, long intCompact, int scale, int preferredScale) {
+        if(intCompact!=INFLATED) {
+            return createAndStripZerosToMatchScale(intCompact, scale, preferredScale);
+        } else {
+            return createAndStripZerosToMatchScale(intVal==null ? INFLATED_BIGINT : intVal,
+                                                   scale, preferredScale);
+        }
+    }
+
+    /*
+     * returns INFLATED if oveflow
+     */
+    private static long add(long xs, long ys){
+        long sum = xs + ys;
+        // See "Hacker's Delight" section 2-12 for explanation of
+        // the overflow test.
+        if ( (((sum ^ xs) & (sum ^ ys))) >= 0L) { // not overflowed
+            return sum;
+        }
+        return INFLATED;
+    }
+
+    private static BigDecimal add(long xs, long ys, int scale){
+        long sum = add(xs, ys);
+        if (sum!=INFLATED)
+            return BigDecimal.valueOf(sum, scale);
+        return new BigDecimal(BigInteger.valueOf(xs).add(ys), scale);
+    }
+
+    private static BigDecimal add(final long xs, int scale1, final long ys, int scale2) {
+        long sdiff = (long) scale1 - scale2;
+        if (sdiff == 0) {
+            return add(xs, ys, scale1);
+        } else if (sdiff < 0) {
+            int raise = checkScale(xs,-sdiff);
+            long scaledX = longMultiplyPowerTen(xs, raise);
+            if (scaledX != INFLATED) {
+                return add(scaledX, ys, scale2);
+            } else {
+                BigInteger bigsum = bigMultiplyPowerTen(xs,raise).add(ys);
+                return ((xs^ys)>=0) ? // same sign test
+                    new BigDecimal(bigsum, INFLATED, scale2, 0)
+                    : valueOf(bigsum, scale2, 0);
+            }
+        } else {
+            int raise = checkScale(ys,sdiff);
+            long scaledY = longMultiplyPowerTen(ys, raise);
+            if (scaledY != INFLATED) {
+                return add(xs, scaledY, scale1);
+            } else {
+                BigInteger bigsum = bigMultiplyPowerTen(ys,raise).add(xs);
+                return ((xs^ys)>=0) ?
+                    new BigDecimal(bigsum, INFLATED, scale1, 0)
+                    : valueOf(bigsum, scale1, 0);
+            }
+        }
+    }
+
+    private static BigDecimal add(final long xs, int scale1, BigInteger snd, int scale2) {
+        int rscale = scale1;
+        long sdiff = (long)rscale - scale2;
+        boolean sameSigns =  (Long.signum(xs) == snd.signum);
+        BigInteger sum;
+        if (sdiff < 0) {
+            int raise = checkScale(xs,-sdiff);
+            rscale = scale2;
+            long scaledX = longMultiplyPowerTen(xs, raise);
+            if (scaledX == INFLATED) {
+                sum = snd.add(bigMultiplyPowerTen(xs,raise));
+            } else {
+                sum = snd.add(scaledX);
+            }
+        } else { //if (sdiff > 0) {
+            int raise = checkScale(snd,sdiff);
+            snd = bigMultiplyPowerTen(snd,raise);
+            sum = snd.add(xs);
+        }
+        return (sameSigns) ?
+            new BigDecimal(sum, INFLATED, rscale, 0) :
+            valueOf(sum, rscale, 0);
+    }
+
+    private static BigDecimal add(BigInteger fst, int scale1, BigInteger snd, int scale2) {
+        int rscale = scale1;
+        long sdiff = (long)rscale - scale2;
+        if (sdiff != 0) {
+            if (sdiff < 0) {
+                int raise = checkScale(fst,-sdiff);
+                rscale = scale2;
+                fst = bigMultiplyPowerTen(fst,raise);
+            } else {
+                int raise = checkScale(snd,sdiff);
+                snd = bigMultiplyPowerTen(snd,raise);
+            }
+        }
+        BigInteger sum = fst.add(snd);
+        return (fst.signum == snd.signum) ?
+                new BigDecimal(sum, INFLATED, rscale, 0) :
+                valueOf(sum, rscale, 0);
+    }
+
+    private static BigInteger bigMultiplyPowerTen(long value, int n) {
+        if (n <= 0)
+            return BigInteger.valueOf(value);
+        return bigTenToThe(n).multiply(value);
+    }
+
+    private static BigInteger bigMultiplyPowerTen(BigInteger value, int n) {
+        if (n <= 0)
+            return value;
+        if(n<LONG_TEN_POWERS_TABLE.length) {
+                return value.multiply(LONG_TEN_POWERS_TABLE[n]);
+        }
+        return value.multiply(bigTenToThe(n));
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (xs /
+     * ys)}, with rounding according to the context settings.
+     *
+     * Fast path - used only when (xscale <= yscale && yscale < 18
+     *  && mc.presision<18) {
+     */
+    private static BigDecimal divideSmallFastPath(final long xs, int xscale,
+                                                  final long ys, int yscale,
+                                                  long preferredScale, MathContext mc) {
+        int mcp = mc.precision;
+        int roundingMode = mc.roundingMode.oldMode;
+
+        assert (xscale <= yscale) && (yscale < 18) && (mcp < 18);
+        int xraise = yscale - xscale; // xraise >=0
+        long scaledX = (xraise==0) ? xs :
+            longMultiplyPowerTen(xs, xraise); // can't overflow here!
+        BigDecimal quotient;
+
+        int cmp = longCompareMagnitude(scaledX, ys);
+        if(cmp > 0) { // satisfy constraint (b)
+            yscale -= 1; // [that is, divisor *= 10]
+            int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+            if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
+                // assert newScale >= xscale
+                int raise = checkScaleNonZero((long) mcp + yscale - xscale);
+                long scaledXs;
+                if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
+                    quotient = null;
+                    if((mcp-1) >=0 && (mcp-1)<LONG_TEN_POWERS_TABLE.length) {
+                        quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp-1], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+                    }
+                    if(quotient==null) {
+                        BigInteger rb = bigMultiplyPowerTen(scaledX,mcp-1);
+                        quotient = divideAndRound(rb, ys,
+                                                  scl, roundingMode, checkScaleNonZero(preferredScale));
+                    }
+                } else {
+                    quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+                }
+            } else {
+                int newScale = checkScaleNonZero((long) xscale - mcp);
+                // assert newScale >= yscale
+                if (newScale == yscale) { // easy case
+                    quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
+                } else {
+                    int raise = checkScaleNonZero((long) newScale - yscale);
+                    long scaledYs;
+                    if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
+                        BigInteger rb = bigMultiplyPowerTen(ys,raise);
+                        quotient = divideAndRound(BigInteger.valueOf(xs),
+                                                  rb, scl, roundingMode,checkScaleNonZero(preferredScale));
+                    } else {
+                        quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
+                    }
+                }
+            }
+        } else {
+            // abs(scaledX) <= abs(ys)
+            // result is "scaledX * 10^msp / ys"
+            int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+            if(cmp==0) {
+                // abs(scaleX)== abs(ys) => result will be scaled 10^mcp + correct sign
+                quotient = roundedTenPower(((scaledX < 0) == (ys < 0)) ? 1 : -1, mcp, scl, checkScaleNonZero(preferredScale));
+            } else {
+                // abs(scaledX) < abs(ys)
+                long scaledXs;
+                if ((scaledXs = longMultiplyPowerTen(scaledX, mcp)) == INFLATED) {
+                    quotient = null;
+                    if(mcp<LONG_TEN_POWERS_TABLE.length) {
+                        quotient = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[mcp], scaledX, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+                    }
+                    if(quotient==null) {
+                        BigInteger rb = bigMultiplyPowerTen(scaledX,mcp);
+                        quotient = divideAndRound(rb, ys,
+                                                  scl, roundingMode, checkScaleNonZero(preferredScale));
+                    }
+                } else {
+                    quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+                }
+            }
+        }
+        // doRound, here, only affects 1000000000 case.
+        return doRound(quotient,mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (xs /
+     * ys)}, with rounding according to the context settings.
+     */
+    private static BigDecimal divide(final long xs, int xscale, final long ys, int yscale, long preferredScale, MathContext mc) {
+        int mcp = mc.precision;
+        if(xscale <= yscale && yscale < 18 && mcp<18) {
+            return divideSmallFastPath(xs, xscale, ys, yscale, preferredScale, mc);
+        }
+        if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
+            yscale -= 1; // [that is, divisor *= 10]
+        }
+        int roundingMode = mc.roundingMode.oldMode;
+        // In order to find out whether the divide generates the exact result,
+        // we avoid calling the above divide method. 'quotient' holds the
+        // return BigDecimal object whose scale will be set to 'scl'.
+        int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+        BigDecimal quotient;
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
+            int raise = checkScaleNonZero((long) mcp + yscale - xscale);
+            long scaledXs;
+            if ((scaledXs = longMultiplyPowerTen(xs, raise)) == INFLATED) {
+                BigInteger rb = bigMultiplyPowerTen(xs,raise);
+                quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+            } else {
+                quotient = divideAndRound(scaledXs, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+            }
+        } else {
+            int newScale = checkScaleNonZero((long) xscale - mcp);
+            // assert newScale >= yscale
+            if (newScale == yscale) { // easy case
+                quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
+            } else {
+                int raise = checkScaleNonZero((long) newScale - yscale);
+                long scaledYs;
+                if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
+                    BigInteger rb = bigMultiplyPowerTen(ys,raise);
+                    quotient = divideAndRound(BigInteger.valueOf(xs),
+                                              rb, scl, roundingMode,checkScaleNonZero(preferredScale));
+                } else {
+                    quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
+                }
+            }
+        }
+        // doRound, here, only affects 1000000000 case.
+        return doRound(quotient,mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (xs /
+     * ys)}, with rounding according to the context settings.
+     */
+    private static BigDecimal divide(BigInteger xs, int xscale, long ys, int yscale, long preferredScale, MathContext mc) {
+        // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+        if ((-compareMagnitudeNormalized(ys, yscale, xs, xscale)) > 0) {// satisfy constraint (b)
+            yscale -= 1; // [that is, divisor *= 10]
+        }
+        int mcp = mc.precision;
+        int roundingMode = mc.roundingMode.oldMode;
+
+        // In order to find out whether the divide generates the exact result,
+        // we avoid calling the above divide method. 'quotient' holds the
+        // return BigDecimal object whose scale will be set to 'scl'.
+        BigDecimal quotient;
+        int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
+            int raise = checkScaleNonZero((long) mcp + yscale - xscale);
+            BigInteger rb = bigMultiplyPowerTen(xs,raise);
+            quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+        } else {
+            int newScale = checkScaleNonZero((long) xscale - mcp);
+            // assert newScale >= yscale
+            if (newScale == yscale) { // easy case
+                quotient = divideAndRound(xs, ys, scl, roundingMode,checkScaleNonZero(preferredScale));
+            } else {
+                int raise = checkScaleNonZero((long) newScale - yscale);
+                long scaledYs;
+                if ((scaledYs = longMultiplyPowerTen(ys, raise)) == INFLATED) {
+                    BigInteger rb = bigMultiplyPowerTen(ys,raise);
+                    quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
+                } else {
+                    quotient = divideAndRound(xs, scaledYs, scl, roundingMode,checkScaleNonZero(preferredScale));
+                }
+            }
+        }
+        // doRound, here, only affects 1000000000 case.
+        return doRound(quotient, mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (xs /
+     * ys)}, with rounding according to the context settings.
+     */
+    private static BigDecimal divide(long xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
+        // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+        if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
+            yscale -= 1; // [that is, divisor *= 10]
+        }
+        int mcp = mc.precision;
+        int roundingMode = mc.roundingMode.oldMode;
+
+        // In order to find out whether the divide generates the exact result,
+        // we avoid calling the above divide method. 'quotient' holds the
+        // return BigDecimal object whose scale will be set to 'scl'.
+        BigDecimal quotient;
+        int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
+            int raise = checkScaleNonZero((long) mcp + yscale - xscale);
+            BigInteger rb = bigMultiplyPowerTen(xs,raise);
+            quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+        } else {
+            int newScale = checkScaleNonZero((long) xscale - mcp);
+            int raise = checkScaleNonZero((long) newScale - yscale);
+            BigInteger rb = bigMultiplyPowerTen(ys,raise);
+            quotient = divideAndRound(BigInteger.valueOf(xs), rb, scl, roundingMode,checkScaleNonZero(preferredScale));
+        }
+        // doRound, here, only affects 1000000000 case.
+        return doRound(quotient, mc);
+    }
+
+    /**
+     * Returns a {@code BigDecimal} whose value is {@code (xs /
+     * ys)}, with rounding according to the context settings.
+     */
+    private static BigDecimal divide(BigInteger xs, int xscale, BigInteger ys, int yscale, long preferredScale, MathContext mc) {
+        // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+        if (compareMagnitudeNormalized(xs, xscale, ys, yscale) > 0) {// satisfy constraint (b)
+            yscale -= 1; // [that is, divisor *= 10]
+        }
+        int mcp = mc.precision;
+        int roundingMode = mc.roundingMode.oldMode;
+
+        // In order to find out whether the divide generates the exact result,
+        // we avoid calling the above divide method. 'quotient' holds the
+        // return BigDecimal object whose scale will be set to 'scl'.
+        BigDecimal quotient;
+        int scl = checkScaleNonZero(preferredScale + yscale - xscale + mcp);
+        if (checkScaleNonZero((long) mcp + yscale - xscale) > 0) {
+            int raise = checkScaleNonZero((long) mcp + yscale - xscale);
+            BigInteger rb = bigMultiplyPowerTen(xs,raise);
+            quotient = divideAndRound(rb, ys, scl, roundingMode, checkScaleNonZero(preferredScale));
+        } else {
+            int newScale = checkScaleNonZero((long) xscale - mcp);
+            int raise = checkScaleNonZero((long) newScale - yscale);
+            BigInteger rb = bigMultiplyPowerTen(ys,raise);
+            quotient = divideAndRound(xs, rb, scl, roundingMode,checkScaleNonZero(preferredScale));
+        }
+        // doRound, here, only affects 1000000000 case.
+        return doRound(quotient, mc);
+    }
+
+    /*
+     * performs divideAndRound for (dividend0*dividend1, divisor)
+     * returns null if quotient can't fit into long value;
+     */
+    private static BigDecimal multiplyDivideAndRound(long dividend0, long dividend1, long divisor, int scale, int roundingMode,
+                                                     int preferredScale) {
+        int qsign = Long.signum(dividend0)*Long.signum(dividend1)*Long.signum(divisor);
+        dividend0 = Math.abs(dividend0);
+        dividend1 = Math.abs(dividend1);
+        divisor = Math.abs(divisor);
+        // multiply dividend0 * dividend1
+        long d0_hi = dividend0 >>> 32;
+        long d0_lo = dividend0 & LONG_MASK;
+        long d1_hi = dividend1 >>> 32;
+        long d1_lo = dividend1 & LONG_MASK;
+        long product = d0_lo * d1_lo;
+        long d0 = product & LONG_MASK;
+        long d1 = product >>> 32;
+        product = d0_hi * d1_lo + d1;
+        d1 = product & LONG_MASK;
+        long d2 = product >>> 32;
+        product = d0_lo * d1_hi + d1;
+        d1 = product & LONG_MASK;
+        d2 += product >>> 32;
+        long d3 = d2>>>32;
+        d2 &= LONG_MASK;
+        product = d0_hi*d1_hi + d2;
+        d2 = product & LONG_MASK;
+        d3 = ((product>>>32) + d3) & LONG_MASK;
+        final long dividendHi = make64(d3,d2);
+        final long dividendLo = make64(d1,d0);
+        // divide
+        return divideAndRound128(dividendHi, dividendLo, divisor, qsign, scale, roundingMode, preferredScale);
+    }
+
+    private static final long DIV_NUM_BASE = (1L<<32); // Number base (32 bits).
+
+    /*
+     * divideAndRound 128-bit value by long divisor.
+     * returns null if quotient can't fit into long value;
+     * Specialized version of Knuth's division
+     */
+    private static BigDecimal divideAndRound128(final long dividendHi, final long dividendLo, long divisor, int sign,
+                                                int scale, int roundingMode, int preferredScale) {
+        if (dividendHi >= divisor) {
+            return null;
+        }
+
+        final int shift = Long.numberOfLeadingZeros(divisor);
+        divisor <<= shift;
+
+        final long v1 = divisor >>> 32;
+        final long v0 = divisor & LONG_MASK;
+
+        long tmp = dividendLo << shift;
+        long u1 = tmp >>> 32;
+        long u0 = tmp & LONG_MASK;
+
+        tmp = (dividendHi << shift) | (dividendLo >>> 64 - shift);
+        long u2 = tmp & LONG_MASK;
+        long q1, r_tmp;
+        if (v1 == 1) {
+            q1 = tmp;
+            r_tmp = 0;
+        } else if (tmp >= 0) {
+            q1 = tmp / v1;
+            r_tmp = tmp - q1 * v1;
+        } else {
+            long[] rq = divRemNegativeLong(tmp, v1);
+            q1 = rq[1];
+            r_tmp = rq[0];
+        }
+
+        while(q1 >= DIV_NUM_BASE || unsignedLongCompare(q1*v0, make64(r_tmp, u1))) {
+            q1--;
+            r_tmp += v1;
+            if (r_tmp >= DIV_NUM_BASE)
+                break;
+        }
+
+        tmp = mulsub(u2,u1,v1,v0,q1);
+        u1 = tmp & LONG_MASK;
+        long q0;
+        if (v1 == 1) {
+            q0 = tmp;
+            r_tmp = 0;
+        } else if (tmp >= 0) {
+            q0 = tmp / v1;
+            r_tmp = tmp - q0 * v1;
+        } else {
+            long[] rq = divRemNegativeLong(tmp, v1);
+            q0 = rq[1];
+            r_tmp = rq[0];
+        }
+
+        while(q0 >= DIV_NUM_BASE || unsignedLongCompare(q0*v0,make64(r_tmp,u0))) {
+            q0--;
+            r_tmp += v1;
+            if (r_tmp >= DIV_NUM_BASE)
+                break;
+        }
+
+        if((int)q1 < 0) {
+            // result (which is positive and unsigned here)
+            // can't fit into long due to sign bit is used for value
+            MutableBigInteger mq = new MutableBigInteger(new int[]{(int)q1, (int)q0});
+            if (roundingMode == ROUND_DOWN && scale == preferredScale) {
+                return mq.toBigDecimal(sign, scale);
+            }
+            long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
+            if (r != 0) {
+                if(needIncrement(divisor >>> shift, roundingMode, sign, mq, r)){
+                    mq.add(MutableBigInteger.ONE);
+                }
+                return mq.toBigDecimal(sign, scale);
+            } else {
+                if (preferredScale != scale) {
+                    BigInteger intVal =  mq.toBigInteger(sign);
+                    return createAndStripZerosToMatchScale(intVal,scale, preferredScale);
+                } else {
+                    return mq.toBigDecimal(sign, scale);
+                }
+            }
+        }
+
+        long q = make64(q1,q0);
+        q*=sign;
+
+        if (roundingMode == ROUND_DOWN && scale == preferredScale)
+            return valueOf(q, scale);
+
+        long r = mulsub(u1, u0, v1, v0, q0) >>> shift;
+        if (r != 0) {
+            boolean increment = needIncrement(divisor >>> shift, roundingMode, sign, q, r);
+            return valueOf((increment ? q + sign : q), scale);
+        } else {
+            if (preferredScale != scale) {
+                return createAndStripZerosToMatchScale(q, scale, preferredScale);
+            } else {
+                return valueOf(q, scale);
+            }
+        }
+    }
+
+    /*
+     * calculate divideAndRound for ldividend*10^raise / divisor
+     * when abs(dividend)==abs(divisor);
+     */
+    private static BigDecimal roundedTenPower(int qsign, int raise, int scale, int preferredScale) {
+        if (scale > preferredScale) {
+            int diff = scale - preferredScale;
+            if(diff < raise) {
+                return scaledTenPow(raise - diff, qsign, preferredScale);
+            } else {
+                return valueOf(qsign,scale-raise);
+            }
+        } else {
+            return scaledTenPow(raise, qsign, scale);
+        }
+    }
+
+    static BigDecimal scaledTenPow(int n, int sign, int scale) {
+        if (n < LONG_TEN_POWERS_TABLE.length)
+            return valueOf(sign*LONG_TEN_POWERS_TABLE[n],scale);
+        else {
+            BigInteger unscaledVal = bigTenToThe(n);
+            if(sign==-1) {
+                unscaledVal = unscaledVal.negate();
+            }
+            return new BigDecimal(unscaledVal, INFLATED, scale, n+1);
+        }
+    }
+
+    /**
+     * Calculate the quotient and remainder of dividing a negative long by
+     * another long.
+     *
+     * @param n the numerator; must be negative
+     * @param d the denominator; must not be unity
+     * @return a two-element {@long} array with the remainder and quotient in
+     *         the initial and final elements, respectively
+     */
+    private static long[] divRemNegativeLong(long n, long d) {
+        assert n < 0 : "Non-negative numerator " + n;
+        assert d != 1 : "Unity denominator";
+
+        // Approximate the quotient and remainder
+        long q = (n >>> 1) / (d >>> 1);
+        long r = n - q * d;
+
+        // Correct the approximation
+        while (r < 0) {
+            r += d;
+            q--;
+        }
+        while (r >= d) {
+            r -= d;
+            q++;
+        }
+
+        // n - q*d == r && 0 <= r < d, hence we're done.
+        return new long[] {r, q};
+    }
+
+    private static long make64(long hi, long lo) {
+        return hi<<32 | lo;
+    }
+
+    private static long mulsub(long u1, long u0, final long v1, final long v0, long q0) {
+        long tmp = u0 - q0*v0;
+        return make64(u1 + (tmp>>>32) - q0*v1,tmp & LONG_MASK);
+    }
+
+    private static boolean unsignedLongCompare(long one, long two) {
+        return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
+    }
+
+    private static boolean unsignedLongCompareEq(long one, long two) {
+        return (one+Long.MIN_VALUE) >= (two+Long.MIN_VALUE);
+    }
+
+
+    // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+    private static int compareMagnitudeNormalized(long xs, int xscale, long ys, int yscale) {
+        // assert xs!=0 && ys!=0
+        int sdiff = xscale - yscale;
+        if (sdiff != 0) {
+            if (sdiff < 0) {
+                xs = longMultiplyPowerTen(xs, -sdiff);
+            } else { // sdiff > 0
+                ys = longMultiplyPowerTen(ys, sdiff);
+            }
+        }
+        if (xs != INFLATED)
+            return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
+        else
+            return 1;
+    }
+
+    // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+    private static int compareMagnitudeNormalized(long xs, int xscale, BigInteger ys, int yscale) {
+        // assert "ys can't be represented as long"
+        if (xs == 0)
+            return -1;
+        int sdiff = xscale - yscale;
+        if (sdiff < 0) {
+            if (longMultiplyPowerTen(xs, -sdiff) == INFLATED ) {
+                return bigMultiplyPowerTen(xs, -sdiff).compareMagnitude(ys);
+            }
+        }
+        return -1;
+    }
+
+    // Compare Normalize dividend & divisor so that both fall into [0.1, 0.999...]
+    private static int compareMagnitudeNormalized(BigInteger xs, int xscale, BigInteger ys, int yscale) {
+        int sdiff = xscale - yscale;
+        if (sdiff < 0) {
+            return bigMultiplyPowerTen(xs, -sdiff).compareMagnitude(ys);
+        } else { // sdiff >= 0
+            return xs.compareMagnitude(bigMultiplyPowerTen(ys, sdiff));
+        }
+    }
+
+    private static long multiply(long x, long y){
+                long product = x * y;
+        long ax = Math.abs(x);
+        long ay = Math.abs(y);
+        if (((ax | ay) >>> 31 == 0) || (y == 0) || (product / y == x)){
+                        return product;
+                }
+        return INFLATED;
+    }
+
+    private static BigDecimal multiply(long x, long y, int scale) {
+        long product = multiply(x, y);
+        if(product!=INFLATED) {
+            return valueOf(product,scale);
+        }
+        return new BigDecimal(BigInteger.valueOf(x).multiply(y),INFLATED,scale,0);
+    }
+
+    private static BigDecimal multiply(long x, BigInteger y, int scale) {
+        if(x==0) {
+            return zeroValueOf(scale);
+        }
+        return new BigDecimal(y.multiply(x),INFLATED,scale,0);
+    }
+
+    private static BigDecimal multiply(BigInteger x, BigInteger y, int scale) {
+        return new BigDecimal(x.multiply(y),INFLATED,scale,0);
+    }
+
+    /**
+     * Multiplies two long values and rounds according {@code MathContext}
+     */
+    private static BigDecimal multiplyAndRound(long x, long y, int scale, MathContext mc) {
+        long product = multiply(x, y);
+        if(product!=INFLATED) {
+            return doRound(product, scale, mc);
+        }
+        // attempt to do it in 128 bits
+        int rsign = 1;
+        if(x < 0) {
+            x = -x;
+            rsign = -1;
+        }
+        if(y < 0) {
+            y = -y;
+            rsign *= -1;
+        }
+        // multiply dividend0 * dividend1
+        long m0_hi = x >>> 32;
+        long m0_lo = x & LONG_MASK;
+        long m1_hi = y >>> 32;
+        long m1_lo = y & LONG_MASK;
+        product = m0_lo * m1_lo;
+        long m0 = product & LONG_MASK;
+        long m1 = product >>> 32;
+        product = m0_hi * m1_lo + m1;
+        m1 = product & LONG_MASK;
+        long m2 = product >>> 32;
+        product = m0_lo * m1_hi + m1;
+        m1 = product & LONG_MASK;
+        m2 += product >>> 32;
+        long m3 = m2>>>32;
+        m2 &= LONG_MASK;
+        product = m0_hi*m1_hi + m2;
+        m2 = product & LONG_MASK;
+        m3 = ((product>>>32) + m3) & LONG_MASK;
+        final long mHi = make64(m3,m2);
+        final long mLo = make64(m1,m0);
+        BigDecimal res = doRound128(mHi, mLo, rsign, scale, mc);
+        if(res!=null) {
+            return res;
+        }
+        res = new BigDecimal(BigInteger.valueOf(x).multiply(y*rsign), INFLATED, scale, 0);
+        return doRound(res,mc);
+    }
+
+    private static BigDecimal multiplyAndRound(long x, BigInteger y, int scale, MathContext mc) {
+        if(x==0) {
+            return zeroValueOf(scale);
+        }
+        return doRound(y.multiply(x), scale, mc);
+    }
+
+    private static BigDecimal multiplyAndRound(BigInteger x, BigInteger y, int scale, MathContext mc) {
+        return doRound(x.multiply(y), scale, mc);
+    }
+
+    /**
+     * rounds 128-bit value according {@code MathContext}
+     * returns null if result can't be repsented as compact BigDecimal.
+     */
+    private static BigDecimal doRound128(long hi, long lo, int sign, int scale, MathContext mc) {
+        int mcp = mc.precision;
+        int drop;
+        BigDecimal res = null;
+        if(((drop = precision(hi, lo) - mcp) > 0)&&(drop<LONG_TEN_POWERS_TABLE.length)) {
+            scale = checkScaleNonZero((long)scale - drop);
+            res = divideAndRound128(hi, lo, LONG_TEN_POWERS_TABLE[drop], sign, scale, mc.roundingMode.oldMode, scale);
+        }
+        if(res!=null) {
+            return doRound(res,mc);
+        }
+        return null;
+    }
+
+    private static final long[][] LONGLONG_TEN_POWERS_TABLE = {
+        {   0L, 0x8AC7230489E80000L },  //10^19
+        {       0x5L, 0x6bc75e2d63100000L },  //10^20
+        {       0x36L, 0x35c9adc5dea00000L },  //10^21
+        {       0x21eL, 0x19e0c9bab2400000L  },  //10^22
+        {       0x152dL, 0x02c7e14af6800000L  },  //10^23
+        {       0xd3c2L, 0x1bcecceda1000000L  },  //10^24
+        {       0x84595L, 0x161401484a000000L  },  //10^25
+        {       0x52b7d2L, 0xdcc80cd2e4000000L  },  //10^26
+        {       0x33b2e3cL, 0x9fd0803ce8000000L  },  //10^27
+        {       0x204fce5eL, 0x3e25026110000000L  },  //10^28
+        {       0x1431e0faeL, 0x6d7217caa0000000L  },  //10^29
+        {       0xc9f2c9cd0L, 0x4674edea40000000L  },  //10^30
+        {       0x7e37be2022L, 0xc0914b2680000000L  },  //10^31
+        {       0x4ee2d6d415bL, 0x85acef8100000000L  },  //10^32
+        {       0x314dc6448d93L, 0x38c15b0a00000000L  },  //10^33
+        {       0x1ed09bead87c0L, 0x378d8e6400000000L  },  //10^34
+        {       0x13426172c74d82L, 0x2b878fe800000000L  },  //10^35
+        {       0xc097ce7bc90715L, 0xb34b9f1000000000L  },  //10^36
+        {       0x785ee10d5da46d9L, 0x00f436a000000000L  },  //10^37
+        {       0x4b3b4ca85a86c47aL, 0x098a224000000000L  },  //10^38
+    };
+
+    /*
+     * returns precision of 128-bit value
+     */
+    private static int precision(long hi, long lo){
+        if(hi==0) {
+            if(lo>=0) {
+                return longDigitLength(lo);
+            }
+            return (unsignedLongCompareEq(lo, LONGLONG_TEN_POWERS_TABLE[0][1])) ? 20 : 19;
+            // 0x8AC7230489E80000L  = unsigned 2^19
+        }
+        int r = ((128 - Long.numberOfLeadingZeros(hi) + 1) * 1233) >>> 12;
+        int idx = r-19;
+        return (idx >= LONGLONG_TEN_POWERS_TABLE.length || longLongCompareMagnitude(hi, lo,
+                                                                                    LONGLONG_TEN_POWERS_TABLE[idx][0], LONGLONG_TEN_POWERS_TABLE[idx][1])) ? r : r + 1;
+    }
+
+    /*
+     * returns true if 128 bit number <hi0,lo0> is less than <hi1,lo1>
+     * hi0 & hi1 should be non-negative
+     */
+    private static boolean longLongCompareMagnitude(long hi0, long lo0, long hi1, long lo1) {
+        if(hi0!=hi1) {
+            return hi0<hi1;
+        }
+        return (lo0+Long.MIN_VALUE) <(lo1+Long.MIN_VALUE);
+    }
+
+    private static BigDecimal divide(long dividend, int dividendScale, long divisor, int divisorScale, int scale, int roundingMode) {
+        if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
+            int newScale = scale + divisorScale;
+            int raise = newScale - dividendScale;
+            if(raise<LONG_TEN_POWERS_TABLE.length) {
+                long xs = dividend;
+                if ((xs = longMultiplyPowerTen(xs, raise)) != INFLATED) {
+                    return divideAndRound(xs, divisor, scale, roundingMode, scale);
+                }
+                BigDecimal q = multiplyDivideAndRound(LONG_TEN_POWERS_TABLE[raise], dividend, divisor, scale, roundingMode, scale);
+                if(q!=null) {
+                    return q;
+                }
+            }
+            BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
+            return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
+        } else {
+            int newScale = checkScale(divisor,(long)dividendScale - scale);
+            int raise = newScale - divisorScale;
+            if(raise<LONG_TEN_POWERS_TABLE.length) {
+                long ys = divisor;
+                if ((ys = longMultiplyPowerTen(ys, raise)) != INFLATED) {
+                    return divideAndRound(dividend, ys, scale, roundingMode, scale);
+                }
+            }
+            BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
+            return divideAndRound(BigInteger.valueOf(dividend), scaledDivisor, scale, roundingMode, scale);
+        }
+    }
+
+    private static BigDecimal divide(BigInteger dividend, int dividendScale, long divisor, int divisorScale, int scale, int roundingMode) {
+        if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
+            int newScale = scale + divisorScale;
+            int raise = newScale - dividendScale;
+            BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
+            return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
+        } else {
+            int newScale = checkScale(divisor,(long)dividendScale - scale);
+            int raise = newScale - divisorScale;
+            if(raise<LONG_TEN_POWERS_TABLE.length) {
+                long ys = divisor;
+                if ((ys = longMultiplyPowerTen(ys, raise)) != INFLATED) {
+                    return divideAndRound(dividend, ys, scale, roundingMode, scale);
+                }
+            }
+            BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
+            return divideAndRound(dividend, scaledDivisor, scale, roundingMode, scale);
+        }
+    }
+
+    private static BigDecimal divide(long dividend, int dividendScale, BigInteger divisor, int divisorScale, int scale, int roundingMode) {
+        if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
+            int newScale = scale + divisorScale;
+            int raise = newScale - dividendScale;
+            BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
+            return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
+        } else {
+            int newScale = checkScale(divisor,(long)dividendScale - scale);
+            int raise = newScale - divisorScale;
+            BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
+            return divideAndRound(BigInteger.valueOf(dividend), scaledDivisor, scale, roundingMode, scale);
+        }
+    }
+
+    private static BigDecimal divide(BigInteger dividend, int dividendScale, BigInteger divisor, int divisorScale, int scale, int roundingMode) {
+        if (checkScale(dividend,(long)scale + divisorScale) > dividendScale) {
+            int newScale = scale + divisorScale;
+            int raise = newScale - dividendScale;
+            BigInteger scaledDividend = bigMultiplyPowerTen(dividend, raise);
+            return divideAndRound(scaledDividend, divisor, scale, roundingMode, scale);
+        } else {
+            int newScale = checkScale(divisor,(long)dividendScale - scale);
+            int raise = newScale - divisorScale;
+            BigInteger scaledDivisor = bigMultiplyPowerTen(divisor, raise);
+            return divideAndRound(dividend, scaledDivisor, scale, roundingMode, scale);
+        }
+    }
+
+}
diff --git a/ojluni/src/main/java/java/math/BigInteger.java b/ojluni/src/main/java/java/math/BigInteger.java
new file mode 100644
index 0000000..b20c5ec
--- /dev/null
+++ b/ojluni/src/main/java/java/math/BigInteger.java
@@ -0,0 +1,4812 @@
+/*
+ * Copyright (c) 1996, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * Portions Copyright (c) 1995  Colin Plumb.  All rights reserved.
+ */
+
+package java.math;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.util.Arrays;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+import libcore.math.NativeBN;
+import sun.misc.DoubleConsts;
+import sun.misc.FloatConsts;
+import libcore.util.NonNull;
+
+/**
+ * Immutable arbitrary-precision integers.  All operations behave as if
+ * BigIntegers were represented in two's-complement notation (like Java's
+ * primitive integer types).  BigInteger provides analogues to all of Java's
+ * primitive integer operators, and all relevant methods from java.lang.Math.
+ * Additionally, BigInteger provides operations for modular arithmetic, GCD
+ * calculation, primality testing, prime generation, bit manipulation,
+ * and a few other miscellaneous operations.
+ *
+ * <p>Semantics of arithmetic operations exactly mimic those of Java's integer
+ * arithmetic operators, as defined in <i>The Java Language Specification</i>.
+ * For example, division by zero throws an {@code ArithmeticException}, and
+ * division of a negative by a positive yields a negative (or zero) remainder.
+ * All of the details in the Spec concerning overflow are ignored, as
+ * BigIntegers are made as large as necessary to accommodate the results of an
+ * operation.
+ *
+ * <p>Semantics of shift operations extend those of Java's shift operators
+ * to allow for negative shift distances.  A right-shift with a negative
+ * shift distance results in a left shift, and vice-versa.  The unsigned
+ * right shift operator ({@code >>>}) is omitted, as this operation makes
+ * little sense in combination with the "infinite word size" abstraction
+ * provided by this class.
+ *
+ * <p>Semantics of bitwise logical operations exactly mimic those of Java's
+ * bitwise integer operators.  The binary operators ({@code and},
+ * {@code or}, {@code xor}) implicitly perform sign extension on the shorter
+ * of the two operands prior to performing the operation.
+ *
+ * <p>Comparison operations perform signed integer comparisons, analogous to
+ * those performed by Java's relational and equality operators.
+ *
+ * <p>Modular arithmetic operations are provided to compute residues, perform
+ * exponentiation, and compute multiplicative inverses.  These methods always
+ * return a non-negative result, between {@code 0} and {@code (modulus - 1)},
+ * inclusive.
+ *
+ * <p>Bit operations operate on a single bit of the two's-complement
+ * representation of their operand.  If necessary, the operand is sign-
+ * extended so that it contains the designated bit.  None of the single-bit
+ * operations can produce a BigInteger with a different sign from the
+ * BigInteger being operated on, as they affect only a single bit, and the
+ * "infinite word size" abstraction provided by this class ensures that there
+ * are infinitely many "virtual sign bits" preceding each BigInteger.
+ *
+ * <p>For the sake of brevity and clarity, pseudo-code is used throughout the
+ * descriptions of BigInteger methods.  The pseudo-code expression
+ * {@code (i + j)} is shorthand for "a BigInteger whose value is
+ * that of the BigInteger {@code i} plus that of the BigInteger {@code j}."
+ * The pseudo-code expression {@code (i == j)} is shorthand for
+ * "{@code true} if and only if the BigInteger {@code i} represents the same
+ * value as the BigInteger {@code j}."  Other pseudo-code expressions are
+ * interpreted similarly.
+ *
+ * <p>All methods and constructors in this class throw
+ * {@code NullPointerException} when passed
+ * a null object reference for any input parameter.
+ *
+ * BigInteger must support values in the range
+ * -2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive) to
+ * +2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive)
+ * and may support values outside of that range.
+ *
+ * The range of probable prime values is limited and may be less than
+ * the full supported positive range of {@code BigInteger}.
+ * The range must be at least 1 to 2<sup>500000000</sup>.
+ *
+ * @implNote
+ * BigInteger constructors and operations throw {@code ArithmeticException} when
+ * the result is out of the supported range of
+ * -2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive) to
+ * +2<sup>{@code Integer.MAX_VALUE}</sup> (exclusive).
+ *
+ * @see     BigDecimal
+ * @author  Josh Bloch
+ * @author  Michael McCloskey
+ * @author  Alan Eliasen
+ * @author  Timothy Buktu
+ * @since JDK1.1
+ */
+
+public class BigInteger extends Number implements Comparable<BigInteger> {
+    // Android-changed: Added @NonNull annotations.
+
+    /**
+     * The signum of this BigInteger: -1 for negative, 0 for zero, or
+     * 1 for positive.  Note that the BigInteger zero <i>must</i> have
+     * a signum of 0.  This is necessary to ensures that there is exactly one
+     * representation for each BigInteger value.
+     *
+     * @serial
+     */
+    final int signum;
+
+    /**
+     * The magnitude of this BigInteger, in <i>big-endian</i> order: the
+     * zeroth element of this array is the most-significant int of the
+     * magnitude.  The magnitude must be "minimal" in that the most-significant
+     * int ({@code mag[0]}) must be non-zero.  This is necessary to
+     * ensure that there is exactly one representation for each BigInteger
+     * value.  Note that this implies that the BigInteger zero has a
+     * zero-length mag array.
+     */
+    final int[] mag;
+
+    // These "redundant fields" are initialized with recognizable nonsense
+    // values, and cached the first time they are needed (or never, if they
+    // aren't needed).
+
+     /**
+     * One plus the bitCount of this BigInteger. Zeros means uninitialized.
+     *
+     * @serial
+     * @see #bitCount
+     * @deprecated Deprecated since logical value is offset from stored
+     * value and correction factor is applied in accessor method.
+     */
+    @Deprecated
+    private int bitCount;
+
+    /**
+     * One plus the bitLength of this BigInteger. Zeros means uninitialized.
+     * (either value is acceptable).
+     *
+     * @serial
+     * @see #bitLength()
+     * @deprecated Deprecated since logical value is offset from stored
+     * value and correction factor is applied in accessor method.
+     */
+    @Deprecated
+    private int bitLength;
+
+    /**
+     * Two plus the lowest set bit of this BigInteger, as returned by
+     * getLowestSetBit().
+     *
+     * @serial
+     * @see #getLowestSetBit
+     * @deprecated Deprecated since logical value is offset from stored
+     * value and correction factor is applied in accessor method.
+     */
+    @Deprecated
+    private int lowestSetBit;
+
+    /**
+     * Two plus the index of the lowest-order int in the magnitude of this
+     * BigInteger that contains a nonzero int, or -2 (either value is acceptable).
+     * The least significant int has int-number 0, the next int in order of
+     * increasing significance has int-number 1, and so forth.
+     * @deprecated Deprecated since logical value is offset from stored
+     * value and correction factor is applied in accessor method.
+     */
+    @Deprecated
+    private int firstNonzeroIntNum;
+
+    /**
+     * This mask is used to obtain the value of an int as if it were unsigned.
+     */
+    final static long LONG_MASK = 0xffffffffL;
+
+    /**
+     * This constant limits {@code mag.length} of BigIntegers to the supported
+     * range.
+     */
+    private static final int MAX_MAG_LENGTH = Integer.MAX_VALUE / Integer.SIZE + 1; // (1 << 26)
+
+    /**
+     * Bit lengths larger than this constant can cause overflow in searchLen
+     * calculation and in BitSieve.singleSearch method.
+     */
+    private static final  int PRIME_SEARCH_BIT_LENGTH_LIMIT = 500000000;
+
+    /**
+     * The threshold value for using Karatsuba multiplication.  If the number
+     * of ints in both mag arrays are greater than this number, then
+     * Karatsuba multiplication will be used.   This value is found
+     * experimentally to work well.
+     */
+    private static final int KARATSUBA_THRESHOLD = 80;
+
+    /**
+     * The threshold value for using 3-way Toom-Cook multiplication.
+     * If the number of ints in each mag array is greater than the
+     * Karatsuba threshold, and the number of ints in at least one of
+     * the mag arrays is greater than this threshold, then Toom-Cook
+     * multiplication will be used.
+     */
+    private static final int TOOM_COOK_THRESHOLD = 240;
+
+    /**
+     * The threshold value for using Karatsuba squaring.  If the number
+     * of ints in the number are larger than this value,
+     * Karatsuba squaring will be used.   This value is found
+     * experimentally to work well.
+     */
+    private static final int KARATSUBA_SQUARE_THRESHOLD = 128;
+
+    /**
+     * The threshold value for using Toom-Cook squaring.  If the number
+     * of ints in the number are larger than this value,
+     * Toom-Cook squaring will be used.   This value is found
+     * experimentally to work well.
+     */
+    private static final int TOOM_COOK_SQUARE_THRESHOLD = 216;
+
+    /**
+     * The threshold value for using Burnikel-Ziegler division.  If the number
+     * of ints in the divisor are larger than this value, Burnikel-Ziegler
+     * division may be used.  This value is found experimentally to work well.
+     */
+    static final int BURNIKEL_ZIEGLER_THRESHOLD = 80;
+
+    /**
+     * The offset value for using Burnikel-Ziegler division.  If the number
+     * of ints in the divisor exceeds the Burnikel-Ziegler threshold, and the
+     * number of ints in the dividend is greater than the number of ints in the
+     * divisor plus this value, Burnikel-Ziegler division will be used.  This
+     * value is found experimentally to work well.
+     */
+    static final int BURNIKEL_ZIEGLER_OFFSET = 40;
+
+    /**
+     * The threshold value for using Schoenhage recursive base conversion. If
+     * the number of ints in the number are larger than this value,
+     * the Schoenhage algorithm will be used.  In practice, it appears that the
+     * Schoenhage routine is faster for any threshold down to 2, and is
+     * relatively flat for thresholds between 2-25, so this choice may be
+     * varied within this range for very small effect.
+     */
+    private static final int SCHOENHAGE_BASE_CONVERSION_THRESHOLD = 20;
+
+    /**
+     * The threshold value for using squaring code to perform multiplication
+     * of a {@code BigInteger} instance by itself.  If the number of ints in
+     * the number are larger than this value, {@code multiply(this)} will
+     * return {@code square()}.
+     */
+    private static final int MULTIPLY_SQUARE_THRESHOLD = 20;
+
+    /**
+     * The threshold for using an intrinsic version of
+     * implMontgomeryXXX to perform Montgomery multiplication.  If the
+     * number of ints in the number is more than this value we do not
+     * use the intrinsic.
+     */
+    private static final int MONTGOMERY_INTRINSIC_THRESHOLD = 512;
+
+
+    // Constructors
+
+    /**
+     * Translates a byte array containing the two's-complement binary
+     * representation of a BigInteger into a BigInteger.  The input array is
+     * assumed to be in <i>big-endian</i> byte-order: the most significant
+     * byte is in the zeroth element.
+     *
+     * @param  val big-endian two's-complement binary representation of
+     *         BigInteger.
+     * @throws NumberFormatException {@code val} is zero bytes long.
+     */
+    public BigInteger(byte[] val) {
+        if (val.length == 0)
+            throw new NumberFormatException("Zero length BigInteger");
+
+        if (val[0] < 0) {
+            mag = makePositive(val);
+            signum = -1;
+        } else {
+            mag = stripLeadingZeroBytes(val);
+            signum = (mag.length == 0 ? 0 : 1);
+        }
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * This private constructor translates an int array containing the
+     * two's-complement binary representation of a BigInteger into a
+     * BigInteger. The input array is assumed to be in <i>big-endian</i>
+     * int-order: the most significant int is in the zeroth element.
+     */
+    private BigInteger(int[] val) {
+        if (val.length == 0)
+            throw new NumberFormatException("Zero length BigInteger");
+
+        if (val[0] < 0) {
+            mag = makePositive(val);
+            signum = -1;
+        } else {
+            mag = trustedStripLeadingZeroInts(val);
+            signum = (mag.length == 0 ? 0 : 1);
+        }
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * Translates the sign-magnitude representation of a BigInteger into a
+     * BigInteger.  The sign is represented as an integer signum value: -1 for
+     * negative, 0 for zero, or 1 for positive.  The magnitude is a byte array
+     * in <i>big-endian</i> byte-order: the most significant byte is in the
+     * zeroth element.  A zero-length magnitude array is permissible, and will
+     * result in a BigInteger value of 0, whether signum is -1, 0 or 1.
+     *
+     * @param  signum signum of the number (-1 for negative, 0 for zero, 1
+     *         for positive).
+     * @param  magnitude big-endian binary representation of the magnitude of
+     *         the number.
+     * @throws NumberFormatException {@code signum} is not one of the three
+     *         legal values (-1, 0, and 1), or {@code signum} is 0 and
+     *         {@code magnitude} contains one or more non-zero bytes.
+     */
+    public BigInteger(int signum, byte[] magnitude) {
+        this.mag = stripLeadingZeroBytes(magnitude);
+
+        if (signum < -1 || signum > 1)
+            throw(new NumberFormatException("Invalid signum value"));
+
+        if (this.mag.length == 0) {
+            this.signum = 0;
+        } else {
+            if (signum == 0)
+                throw(new NumberFormatException("signum-magnitude mismatch"));
+            this.signum = signum;
+        }
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * A constructor for internal use that translates the sign-magnitude
+     * representation of a BigInteger into a BigInteger. It checks the
+     * arguments and copies the magnitude so this constructor would be
+     * safe for external use.
+     */
+    private BigInteger(int signum, int[] magnitude) {
+        this.mag = stripLeadingZeroInts(magnitude);
+
+        if (signum < -1 || signum > 1)
+            throw(new NumberFormatException("Invalid signum value"));
+
+        if (this.mag.length == 0) {
+            this.signum = 0;
+        } else {
+            if (signum == 0)
+                throw(new NumberFormatException("signum-magnitude mismatch"));
+            this.signum = signum;
+        }
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * Translates the String representation of a BigInteger in the
+     * specified radix into a BigInteger.  The String representation
+     * consists of an optional minus or plus sign followed by a
+     * sequence of one or more digits in the specified radix.  The
+     * character-to-digit mapping is provided by {@code
+     * Character.digit}.  The String may not contain any extraneous
+     * characters (whitespace, for example).
+     *
+     * @param val String representation of BigInteger.
+     * @param radix radix to be used in interpreting {@code val}.
+     * @throws NumberFormatException {@code val} is not a valid representation
+     *         of a BigInteger in the specified radix, or {@code radix} is
+     *         outside the range from {@link Character#MIN_RADIX} to
+     *         {@link Character#MAX_RADIX}, inclusive.
+     * @see    Character#digit
+     */
+    public BigInteger(@NonNull String val, int radix) {
+        int cursor = 0, numDigits;
+        final int len = val.length();
+
+        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+            throw new NumberFormatException("Radix out of range");
+        if (len == 0)
+            throw new NumberFormatException("Zero length BigInteger");
+
+        // Check for at most one leading sign
+        int sign = 1;
+        int index1 = val.lastIndexOf('-');
+        int index2 = val.lastIndexOf('+');
+        if (index1 >= 0) {
+            if (index1 != 0 || index2 >= 0) {
+                throw new NumberFormatException("Illegal embedded sign character");
+            }
+            sign = -1;
+            cursor = 1;
+        } else if (index2 >= 0) {
+            if (index2 != 0) {
+                throw new NumberFormatException("Illegal embedded sign character");
+            }
+            cursor = 1;
+        }
+        if (cursor == len)
+            throw new NumberFormatException("Zero length BigInteger");
+
+        // Skip leading zeros and compute number of digits in magnitude
+        while (cursor < len &&
+               Character.digit(val.charAt(cursor), radix) == 0) {
+            cursor++;
+        }
+
+        if (cursor == len) {
+            signum = 0;
+            mag = ZERO.mag;
+            return;
+        }
+
+        numDigits = len - cursor;
+        signum = sign;
+
+        // Pre-allocate array of expected size. May be too large but can
+        // never be too small. Typically exact.
+        long numBits = ((numDigits * bitsPerDigit[radix]) >>> 10) + 1;
+        if (numBits + 31 >= (1L << 32)) {
+            reportOverflow();
+        }
+        int numWords = (int) (numBits + 31) >>> 5;
+        int[] magnitude = new int[numWords];
+
+        // Process first (potentially short) digit group
+        int firstGroupLen = numDigits % digitsPerInt[radix];
+        if (firstGroupLen == 0)
+            firstGroupLen = digitsPerInt[radix];
+        String group = val.substring(cursor, cursor += firstGroupLen);
+        magnitude[numWords - 1] = Integer.parseInt(group, radix);
+        if (magnitude[numWords - 1] < 0)
+            throw new NumberFormatException("Illegal digit");
+
+        // Process remaining digit groups
+        int superRadix = intRadix[radix];
+        int groupVal = 0;
+        while (cursor < len) {
+            group = val.substring(cursor, cursor += digitsPerInt[radix]);
+            groupVal = Integer.parseInt(group, radix);
+            if (groupVal < 0)
+                throw new NumberFormatException("Illegal digit");
+            destructiveMulAdd(magnitude, superRadix, groupVal);
+        }
+        // Required for cases where the array was overallocated.
+        mag = trustedStripLeadingZeroInts(magnitude);
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /*
+     * Constructs a new BigInteger using a char array with radix=10.
+     * Sign is precalculated outside and not allowed in the val.
+     */
+    BigInteger(char[] val, int sign, int len) {
+        int cursor = 0, numDigits;
+
+        // Skip leading zeros and compute number of digits in magnitude
+        while (cursor < len && Character.digit(val[cursor], 10) == 0) {
+            cursor++;
+        }
+        if (cursor == len) {
+            signum = 0;
+            mag = ZERO.mag;
+            return;
+        }
+
+        numDigits = len - cursor;
+        signum = sign;
+        // Pre-allocate array of expected size
+        int numWords;
+        if (len < 10) {
+            numWords = 1;
+        } else {
+            long numBits = ((numDigits * bitsPerDigit[10]) >>> 10) + 1;
+            if (numBits + 31 >= (1L << 32)) {
+                reportOverflow();
+            }
+            numWords = (int) (numBits + 31) >>> 5;
+        }
+        int[] magnitude = new int[numWords];
+
+        // Process first (potentially short) digit group
+        int firstGroupLen = numDigits % digitsPerInt[10];
+        if (firstGroupLen == 0)
+            firstGroupLen = digitsPerInt[10];
+        magnitude[numWords - 1] = parseInt(val, cursor,  cursor += firstGroupLen);
+
+        // Process remaining digit groups
+        while (cursor < len) {
+            int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]);
+            destructiveMulAdd(magnitude, intRadix[10], groupVal);
+        }
+        mag = trustedStripLeadingZeroInts(magnitude);
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    // Create an integer with the digits between the two indexes
+    // Assumes start < end. The result may be negative, but it
+    // is to be treated as an unsigned value.
+    private int parseInt(char[] source, int start, int end) {
+        int result = Character.digit(source[start++], 10);
+        if (result == -1)
+            throw new NumberFormatException(new String(source));
+
+        for (int index = start; index < end; index++) {
+            int nextVal = Character.digit(source[index], 10);
+            if (nextVal == -1)
+                throw new NumberFormatException(new String(source));
+            result = 10*result + nextVal;
+        }
+
+        return result;
+    }
+
+    // bitsPerDigit in the given radix times 1024
+    // Rounded up to avoid underallocation.
+    private static long bitsPerDigit[] = { 0, 0,
+        1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
+        3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
+        4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
+                                           5253, 5295};
+
+    // Multiply x array times word y in place, and add word z
+    private static void destructiveMulAdd(int[] x, int y, int z) {
+        // Perform the multiplication word by word
+        long ylong = y & LONG_MASK;
+        long zlong = z & LONG_MASK;
+        int len = x.length;
+
+        long product = 0;
+        long carry = 0;
+        for (int i = len-1; i >= 0; i--) {
+            product = ylong * (x[i] & LONG_MASK) + carry;
+            x[i] = (int)product;
+            carry = product >>> 32;
+        }
+
+        // Perform the addition
+        long sum = (x[len-1] & LONG_MASK) + zlong;
+        x[len-1] = (int)sum;
+        carry = sum >>> 32;
+        for (int i = len-2; i >= 0; i--) {
+            sum = (x[i] & LONG_MASK) + carry;
+            x[i] = (int)sum;
+            carry = sum >>> 32;
+        }
+    }
+
+    /**
+     * Translates the decimal String representation of a BigInteger into a
+     * BigInteger.  The String representation consists of an optional minus
+     * sign followed by a sequence of one or more decimal digits.  The
+     * character-to-digit mapping is provided by {@code Character.digit}.
+     * The String may not contain any extraneous characters (whitespace, for
+     * example).
+     *
+     * @param val decimal String representation of BigInteger.
+     * @throws NumberFormatException {@code val} is not a valid representation
+     *         of a BigInteger.
+     * @see    Character#digit
+     */
+    public BigInteger(@NonNull String val) {
+        this(val, 10);
+    }
+
+    /**
+     * Constructs a randomly generated BigInteger, uniformly distributed over
+     * the range 0 to (2<sup>{@code numBits}</sup> - 1), inclusive.
+     * The uniformity of the distribution assumes that a fair source of random
+     * bits is provided in {@code rnd}.  Note that this constructor always
+     * constructs a non-negative BigInteger.
+     *
+     * @param  numBits maximum bitLength of the new BigInteger.
+     * @param  rnd source of randomness to be used in computing the new
+     *         BigInteger.
+     * @throws IllegalArgumentException {@code numBits} is negative.
+     * @see #bitLength()
+     */
+    public BigInteger(int numBits, @NonNull Random rnd) {
+        this(1, randomBits(numBits, rnd));
+    }
+
+    private static byte[] randomBits(int numBits, Random rnd) {
+        if (numBits < 0)
+            throw new IllegalArgumentException("numBits must be non-negative");
+        int numBytes = (int)(((long)numBits+7)/8); // avoid overflow
+        byte[] randomBits = new byte[numBytes];
+
+        // Generate random bytes and mask out any excess bits
+        if (numBytes > 0) {
+            rnd.nextBytes(randomBits);
+            int excessBits = 8*numBytes - numBits;
+            randomBits[0] &= (1 << (8-excessBits)) - 1;
+        }
+        return randomBits;
+    }
+
+    /**
+     * Constructs a randomly generated positive BigInteger that is probably
+     * prime, with the specified bitLength.
+     *
+     * <p>It is recommended that the {@link #probablePrime probablePrime}
+     * method be used in preference to this constructor unless there
+     * is a compelling need to specify a certainty.
+     *
+     * @param  bitLength bitLength of the returned BigInteger.
+     * @param  certainty a measure of the uncertainty that the caller is
+     *         willing to tolerate.  The probability that the new BigInteger
+     *         represents a prime number will exceed
+     *         (1 - 1/2<sup>{@code certainty}</sup>).  The execution time of
+     *         this constructor is proportional to the value of this parameter.
+     * @param  rnd source of random bits used to select candidates to be
+     *         tested for primality.
+     * @throws ArithmeticException {@code bitLength < 2} or {@code bitLength} is too large.
+     * @see    #bitLength()
+     */
+    public BigInteger(int bitLength, int certainty, @NonNull Random rnd) {
+        BigInteger prime;
+
+        if (bitLength < 2)
+            throw new ArithmeticException("bitLength < 2");
+        prime = (bitLength < SMALL_PRIME_THRESHOLD
+                                ? smallPrime(bitLength, certainty, rnd)
+                                : largePrime(bitLength, certainty, rnd));
+        signum = 1;
+        mag = prime.mag;
+    }
+
+    // Minimum size in bits that the requested prime number has
+    // before we use the large prime number generating algorithms.
+    // The cutoff of 95 was chosen empirically for best performance.
+    private static final int SMALL_PRIME_THRESHOLD = 95;
+
+    // Certainty required to meet the spec of probablePrime
+    private static final int DEFAULT_PRIME_CERTAINTY = 100;
+
+    /**
+     * Returns a positive BigInteger that is probably prime, with the
+     * specified bitLength. The probability that a BigInteger returned
+     * by this method is composite does not exceed 2<sup>-100</sup>.
+     *
+     * @param  bitLength bitLength of the returned BigInteger.
+     * @param  rnd source of random bits used to select candidates to be
+     *         tested for primality.
+     * @return a BigInteger of {@code bitLength} bits that is probably prime
+     * @throws ArithmeticException {@code bitLength < 2} or {@code bitLength} is too large.
+     * @see    #bitLength()
+     * @since 1.4
+     */
+    @NonNull public static BigInteger probablePrime(int bitLength, @NonNull Random rnd) {
+        if (bitLength < 2)
+            throw new ArithmeticException("bitLength < 2");
+
+        return (bitLength < SMALL_PRIME_THRESHOLD ?
+                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
+                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
+    }
+
+    /**
+     * Find a random number of the specified bitLength that is probably prime.
+     * This method is used for smaller primes, its performance degrades on
+     * larger bitlengths.
+     *
+     * This method assumes bitLength > 1.
+     */
+    private static BigInteger smallPrime(int bitLength, int certainty, @NonNull Random rnd) {
+        int magLen = (bitLength + 31) >>> 5;
+        int temp[] = new int[magLen];
+        int highBit = 1 << ((bitLength+31) & 0x1f);  // High bit of high int
+        int highMask = (highBit << 1) - 1;  // Bits to keep in high int
+
+        while (true) {
+            // Construct a candidate
+            for (int i=0; i < magLen; i++)
+                temp[i] = rnd.nextInt();
+            temp[0] = (temp[0] & highMask) | highBit;  // Ensure exact length
+            if (bitLength > 2)
+                temp[magLen-1] |= 1;  // Make odd if bitlen > 2
+
+            BigInteger p = new BigInteger(temp, 1);
+
+            // Do cheap "pre-test" if applicable
+            if (bitLength > 6) {
+                long r = p.remainder(SMALL_PRIME_PRODUCT).longValue();
+                if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||
+                    (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
+                    (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0))
+                    continue; // Candidate is composite; try another
+            }
+
+            // All candidates of bitLength 2 and 3 are prime by this point
+            if (bitLength < 4)
+                return p;
+
+            // Do expensive test if we survive pre-test (or it's inapplicable)
+            if (p.primeToCertainty(certainty, rnd))
+                return p;
+        }
+    }
+
+    private static final BigInteger SMALL_PRIME_PRODUCT
+                       = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41);
+
+    /**
+     * Find a random number of the specified bitLength that is probably prime.
+     * This method is more appropriate for larger bitlengths since it uses
+     * a sieve to eliminate most composites before using a more expensive
+     * test.
+     */
+    private static BigInteger largePrime(int bitLength, int certainty, @NonNull Random rnd) {
+        BigInteger p;
+        p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
+        p.mag[p.mag.length-1] &= 0xfffffffe;
+
+        // Use a sieve length likely to contain the next prime number
+        int searchLen = getPrimeSearchLen(bitLength);
+        BitSieve searchSieve = new BitSieve(p, searchLen);
+        BigInteger candidate = searchSieve.retrieve(p, certainty, rnd);
+
+        while ((candidate == null) || (candidate.bitLength() != bitLength)) {
+            p = p.add(BigInteger.valueOf(2*searchLen));
+            if (p.bitLength() != bitLength)
+                p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
+            p.mag[p.mag.length-1] &= 0xfffffffe;
+            searchSieve = new BitSieve(p, searchLen);
+            candidate = searchSieve.retrieve(p, certainty, rnd);
+        }
+        return candidate;
+    }
+
+   /**
+    * Returns the first integer greater than this {@code BigInteger} that
+    * is probably prime.  The probability that the number returned by this
+    * method is composite does not exceed 2<sup>-100</sup>. This method will
+    * never skip over a prime when searching: if it returns {@code p}, there
+    * is no prime {@code q} such that {@code this < q < p}.
+    *
+    * @return the first integer greater than this {@code BigInteger} that
+    *         is probably prime.
+    * @throws ArithmeticException {@code this < 0} or {@code this} is too large.
+    * @since 1.5
+    */
+    @NonNull public BigInteger nextProbablePrime() {
+        if (this.signum < 0)
+            throw new ArithmeticException("start < 0: " + this);
+
+        // Handle trivial cases
+        if ((this.signum == 0) || this.equals(ONE))
+            return TWO;
+
+        BigInteger result = this.add(ONE);
+
+        // Fastpath for small numbers
+        if (result.bitLength() < SMALL_PRIME_THRESHOLD) {
+
+            // Ensure an odd number
+            if (!result.testBit(0))
+                result = result.add(ONE);
+
+            while (true) {
+                // Do cheap "pre-test" if applicable
+                if (result.bitLength() > 6) {
+                    long r = result.remainder(SMALL_PRIME_PRODUCT).longValue();
+                    if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||
+                        (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
+                        (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) {
+                        result = result.add(TWO);
+                        continue; // Candidate is composite; try another
+                    }
+                }
+
+                // All candidates of bitLength 2 and 3 are prime by this point
+                if (result.bitLength() < 4)
+                    return result;
+
+                // The expensive test
+                if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY, null))
+                    return result;
+
+                result = result.add(TWO);
+            }
+        }
+
+        // Start at previous even number
+        if (result.testBit(0))
+            result = result.subtract(ONE);
+
+        // Looking for the next large prime
+        int searchLen = getPrimeSearchLen(result.bitLength());
+
+        while (true) {
+           BitSieve searchSieve = new BitSieve(result, searchLen);
+           BigInteger candidate = searchSieve.retrieve(result,
+                                                 DEFAULT_PRIME_CERTAINTY, null);
+           if (candidate != null)
+               return candidate;
+           result = result.add(BigInteger.valueOf(2 * searchLen));
+        }
+    }
+
+    private static int getPrimeSearchLen(int bitLength) {
+        if (bitLength > PRIME_SEARCH_BIT_LENGTH_LIMIT + 1) {
+            throw new ArithmeticException("Prime search implementation restriction on bitLength");
+        }
+        return bitLength / 20 * 64;
+    }
+
+    /**
+     * Returns {@code true} if this BigInteger is probably prime,
+     * {@code false} if it's definitely composite.
+     *
+     * This method assumes bitLength > 2.
+     *
+     * @param  certainty a measure of the uncertainty that the caller is
+     *         willing to tolerate: if the call returns {@code true}
+     *         the probability that this BigInteger is prime exceeds
+     *         {@code (1 - 1/2<sup>certainty</sup>)}.  The execution time of
+     *         this method is proportional to the value of this parameter.
+     * @return {@code true} if this BigInteger is probably prime,
+     *         {@code false} if it's definitely composite.
+     */
+    boolean primeToCertainty(int certainty, @NonNull Random random) {
+        int rounds = 0;
+        int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;
+
+        // The relationship between the certainty and the number of rounds
+        // we perform is given in the draft standard ANSI X9.80, "PRIME
+        // NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".
+        int sizeInBits = this.bitLength();
+        if (sizeInBits < 100) {
+            rounds = 50;
+            rounds = n < rounds ? n : rounds;
+            return passesMillerRabin(rounds, random);
+        }
+
+        if (sizeInBits < 256) {
+            rounds = 27;
+        } else if (sizeInBits < 512) {
+            rounds = 15;
+        } else if (sizeInBits < 768) {
+            rounds = 8;
+        } else if (sizeInBits < 1024) {
+            rounds = 4;
+        } else {
+            rounds = 2;
+        }
+        rounds = n < rounds ? n : rounds;
+
+        return passesMillerRabin(rounds, random) && passesLucasLehmer();
+    }
+
+    /**
+     * Returns true iff this BigInteger is a Lucas-Lehmer probable prime.
+     *
+     * The following assumptions are made:
+     * This BigInteger is a positive, odd number.
+     */
+    private boolean passesLucasLehmer() {
+        BigInteger thisPlusOne = this.add(ONE);
+
+        // Step 1
+        int d = 5;
+        while (jacobiSymbol(d, this) != -1) {
+            // 5, -7, 9, -11, ...
+            d = (d < 0) ? Math.abs(d)+2 : -(d+2);
+        }
+
+        // Step 2
+        BigInteger u = lucasLehmerSequence(d, thisPlusOne, this);
+
+        // Step 3
+        return u.mod(this).equals(ZERO);
+    }
+
+    /**
+     * Computes Jacobi(p,n).
+     * Assumes n positive, odd, n>=3.
+     */
+    private static int jacobiSymbol(int p, @NonNull BigInteger n) {
+        if (p == 0)
+            return 0;
+
+        // Algorithm and comments adapted from Colin Plumb's C library.
+        int j = 1;
+        int u = n.mag[n.mag.length-1];
+
+        // Make p positive
+        if (p < 0) {
+            p = -p;
+            int n8 = u & 7;
+            if ((n8 == 3) || (n8 == 7))
+                j = -j; // 3 (011) or 7 (111) mod 8
+        }
+
+        // Get rid of factors of 2 in p
+        while ((p & 3) == 0)
+            p >>= 2;
+        if ((p & 1) == 0) {
+            p >>= 1;
+            if (((u ^ (u>>1)) & 2) != 0)
+                j = -j; // 3 (011) or 5 (101) mod 8
+        }
+        if (p == 1)
+            return j;
+        // Then, apply quadratic reciprocity
+        if ((p & u & 2) != 0)   // p = u = 3 (mod 4)?
+            j = -j;
+        // And reduce u mod p
+        u = n.mod(BigInteger.valueOf(p)).intValue();
+
+        // Now compute Jacobi(u,p), u < p
+        while (u != 0) {
+            while ((u & 3) == 0)
+                u >>= 2;
+            if ((u & 1) == 0) {
+                u >>= 1;
+                if (((p ^ (p>>1)) & 2) != 0)
+                    j = -j;     // 3 (011) or 5 (101) mod 8
+            }
+            if (u == 1)
+                return j;
+            // Now both u and p are odd, so use quadratic reciprocity
+            assert (u < p);
+            int t = u; u = p; p = t;
+            if ((u & p & 2) != 0) // u = p = 3 (mod 4)?
+                j = -j;
+            // Now u >= p, so it can be reduced
+            u %= p;
+        }
+        return 0;
+    }
+
+    @NonNull private static BigInteger lucasLehmerSequence(int z, @NonNull BigInteger k, @NonNull BigInteger n) {
+        BigInteger d = BigInteger.valueOf(z);
+        BigInteger u = ONE; BigInteger u2;
+        BigInteger v = ONE; BigInteger v2;
+
+        for (int i=k.bitLength()-2; i >= 0; i--) {
+            u2 = u.multiply(v).mod(n);
+
+            v2 = v.square().add(d.multiply(u.square())).mod(n);
+            if (v2.testBit(0))
+                v2 = v2.subtract(n);
+
+            v2 = v2.shiftRight(1);
+
+            u = u2; v = v2;
+            if (k.testBit(i)) {
+                u2 = u.add(v).mod(n);
+                if (u2.testBit(0))
+                    u2 = u2.subtract(n);
+
+                u2 = u2.shiftRight(1);
+                v2 = v.add(d.multiply(u)).mod(n);
+                if (v2.testBit(0))
+                    v2 = v2.subtract(n);
+                v2 = v2.shiftRight(1);
+
+                u = u2; v = v2;
+            }
+        }
+        return u;
+    }
+
+    /**
+     * Returns true iff this BigInteger passes the specified number of
+     * Miller-Rabin tests. This test is taken from the DSA spec (NIST FIPS
+     * 186-2).
+     *
+     * The following assumptions are made:
+     * This BigInteger is a positive, odd number greater than 2.
+     * iterations<=50.
+     */
+    private boolean passesMillerRabin(int iterations, @NonNull Random rnd) {
+        // Find a and m such that m is odd and this == 1 + 2**a * m
+        BigInteger thisMinusOne = this.subtract(ONE);
+        BigInteger m = thisMinusOne;
+        int a = m.getLowestSetBit();
+        m = m.shiftRight(a);
+
+        // Do the tests
+        if (rnd == null) {
+            rnd = ThreadLocalRandom.current();
+        }
+        for (int i=0; i < iterations; i++) {
+            // Generate a uniform random on (1, this)
+            BigInteger b;
+            do {
+                b = new BigInteger(this.bitLength(), rnd);
+            } while (b.compareTo(ONE) <= 0 || b.compareTo(this) >= 0);
+
+            int j = 0;
+            BigInteger z = b.modPow(m, this);
+            while (!((j == 0 && z.equals(ONE)) || z.equals(thisMinusOne))) {
+                if (j > 0 && z.equals(ONE) || ++j == a)
+                    return false;
+                z = z.modPow(TWO, this);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This internal constructor differs from its public cousin
+     * with the arguments reversed in two ways: it assumes that its
+     * arguments are correct, and it doesn't copy the magnitude array.
+     */
+    BigInteger(int[] magnitude, int signum) {
+        this.signum = (magnitude.length == 0 ? 0 : signum);
+        this.mag = magnitude;
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * This private constructor is for internal use and assumes that its
+     * arguments are correct.
+     */
+    private BigInteger(byte[] magnitude, int signum) {
+        this.signum = (magnitude.length == 0 ? 0 : signum);
+        this.mag = stripLeadingZeroBytes(magnitude);
+        if (mag.length >= MAX_MAG_LENGTH) {
+            checkRange();
+        }
+    }
+
+    /**
+     * Throws an {@code ArithmeticException} if the {@code BigInteger} would be
+     * out of the supported range.
+     *
+     * @throws ArithmeticException if {@code this} exceeds the supported range.
+     */
+    private void checkRange() {
+        if (mag.length > MAX_MAG_LENGTH || mag.length == MAX_MAG_LENGTH && mag[0] < 0) {
+            reportOverflow();
+        }
+    }
+
+    private static void reportOverflow() {
+        throw new ArithmeticException("BigInteger would overflow supported range");
+    }
+
+    //Static Factory Methods
+
+    /**
+     * Returns a BigInteger whose value is equal to that of the
+     * specified {@code long}.  This "static factory method" is
+     * provided in preference to a ({@code long}) constructor
+     * because it allows for reuse of frequently used BigIntegers.
+     *
+     * @param  val value of the BigInteger to return.
+     * @return a BigInteger with the specified value.
+     */
+    @NonNull public static BigInteger valueOf(long val) {
+        // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
+        if (val == 0)
+            return ZERO;
+        if (val > 0 && val <= MAX_CONSTANT)
+            return posConst[(int) val];
+        else if (val < 0 && val >= -MAX_CONSTANT)
+            return negConst[(int) -val];
+
+        return new BigInteger(val);
+    }
+
+    /**
+     * Constructs a BigInteger with the specified value, which may not be zero.
+     */
+    @NonNull private BigInteger(long val) {
+        if (val < 0) {
+            val = -val;
+            signum = -1;
+        } else {
+            signum = 1;
+        }
+
+        int highWord = (int)(val >>> 32);
+        if (highWord == 0) {
+            mag = new int[1];
+            mag[0] = (int)val;
+        } else {
+            mag = new int[2];
+            mag[0] = highWord;
+            mag[1] = (int)val;
+        }
+    }
+
+    /**
+     * Returns a BigInteger with the given two's complement representation.
+     * Assumes that the input array will not be modified (the returned
+     * BigInteger will reference the input array if feasible).
+     */
+    @NonNull private static BigInteger valueOf(int val[]) {
+        return (val[0] > 0 ? new BigInteger(val, 1) : new BigInteger(val));
+    }
+
+    // Constants
+
+    /**
+     * Initialize static constant array when class is loaded.
+     */
+    private final static int MAX_CONSTANT = 16;
+    private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];
+    private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];
+
+    /**
+     * The cache of powers of each radix.  This allows us to not have to
+     * recalculate powers of radix^(2^n) more than once.  This speeds
+     * Schoenhage recursive base conversion significantly.
+     */
+    private static volatile BigInteger[][] powerCache;
+
+    /** The cache of logarithms of radices for base conversion. */
+    private static final double[] logCache;
+
+    /** The natural log of 2.  This is used in computing cache indices. */
+    private static final double LOG_TWO = Math.log(2.0);
+
+    static {
+        assert 0 < KARATSUBA_THRESHOLD
+            && KARATSUBA_THRESHOLD < TOOM_COOK_THRESHOLD
+            && TOOM_COOK_THRESHOLD < Integer.MAX_VALUE
+            && 0 < KARATSUBA_SQUARE_THRESHOLD
+            && KARATSUBA_SQUARE_THRESHOLD < TOOM_COOK_SQUARE_THRESHOLD
+            && TOOM_COOK_SQUARE_THRESHOLD < Integer.MAX_VALUE :
+            "Algorithm thresholds are inconsistent";
+
+        for (int i = 1; i <= MAX_CONSTANT; i++) {
+            int[] magnitude = new int[1];
+            magnitude[0] = i;
+            posConst[i] = new BigInteger(magnitude,  1);
+            negConst[i] = new BigInteger(magnitude, -1);
+        }
+
+        /*
+         * Initialize the cache of radix^(2^x) values used for base conversion
+         * with just the very first value.  Additional values will be created
+         * on demand.
+         */
+        powerCache = new BigInteger[Character.MAX_RADIX+1][];
+        logCache = new double[Character.MAX_RADIX+1];
+
+        for (int i=Character.MIN_RADIX; i <= Character.MAX_RADIX; i++) {
+            powerCache[i] = new BigInteger[] { BigInteger.valueOf(i) };
+            logCache[i] = Math.log(i);
+        }
+    }
+
+    /**
+     * The BigInteger constant zero.
+     *
+     * @since   1.2
+     */
+    @NonNull public static final BigInteger ZERO = new BigInteger(new int[0], 0);
+
+    /**
+     * The BigInteger constant one.
+     *
+     * @since   1.2
+     */
+    @NonNull public static final BigInteger ONE = valueOf(1);
+
+    /**
+     * The BigInteger constant two.  (Not exported.)
+     */
+    @NonNull private static final BigInteger TWO = valueOf(2);
+
+    /**
+     * The BigInteger constant -1.  (Not exported.)
+     */
+    @NonNull private static final BigInteger NEGATIVE_ONE = valueOf(-1);
+
+    /**
+     * The BigInteger constant ten.
+     *
+     * @since   1.5
+     */
+    @NonNull public static final BigInteger TEN = valueOf(10);
+
+    // Arithmetic Operations
+
+    /**
+     * Returns a BigInteger whose value is {@code (this + val)}.
+     *
+     * @param  val value to be added to this BigInteger.
+     * @return {@code this + val}
+     */
+    @NonNull public BigInteger add(@NonNull BigInteger val) {
+        if (val.signum == 0)
+            return this;
+        if (signum == 0)
+            return val;
+        if (val.signum == signum)
+            return new BigInteger(add(mag, val.mag), signum);
+
+        int cmp = compareMagnitude(val);
+        if (cmp == 0)
+            return ZERO;
+        int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
+                           : subtract(val.mag, mag));
+        resultMag = trustedStripLeadingZeroInts(resultMag);
+
+        return new BigInteger(resultMag, cmp == signum ? 1 : -1);
+    }
+
+    /**
+     * Package private methods used by BigDecimal code to add a BigInteger
+     * with a long. Assumes val is not equal to INFLATED.
+     */
+    @NonNull BigInteger add(long val) {
+        if (val == 0)
+            return this;
+        if (signum == 0)
+            return valueOf(val);
+        if (Long.signum(val) == signum)
+            return new BigInteger(add(mag, Math.abs(val)), signum);
+        int cmp = compareMagnitude(val);
+        if (cmp == 0)
+            return ZERO;
+        int[] resultMag = (cmp > 0 ? subtract(mag, Math.abs(val)) : subtract(Math.abs(val), mag));
+        resultMag = trustedStripLeadingZeroInts(resultMag);
+        return new BigInteger(resultMag, cmp == signum ? 1 : -1);
+    }
+
+    /**
+     * Adds the contents of the int array x and long value val. This
+     * method allocates a new int array to hold the answer and returns
+     * a reference to that array.  Assumes x.length &gt; 0 and val is
+     * non-negative
+     */
+    private static int[] add(int[] x, long val) {
+        int[] y;
+        long sum = 0;
+        int xIndex = x.length;
+        int[] result;
+        int highWord = (int)(val >>> 32);
+        if (highWord == 0) {
+            result = new int[xIndex];
+            sum = (x[--xIndex] & LONG_MASK) + val;
+            result[xIndex] = (int)sum;
+        } else {
+            if (xIndex == 1) {
+                result = new int[2];
+                sum = val  + (x[0] & LONG_MASK);
+                result[1] = (int)sum;
+                result[0] = (int)(sum >>> 32);
+                return result;
+            } else {
+                result = new int[xIndex];
+                sum = (x[--xIndex] & LONG_MASK) + (val & LONG_MASK);
+                result[xIndex] = (int)sum;
+                sum = (x[--xIndex] & LONG_MASK) + (highWord & LONG_MASK) + (sum >>> 32);
+                result[xIndex] = (int)sum;
+            }
+        }
+        // Copy remainder of longer number while carry propagation is required
+        boolean carry = (sum >>> 32 != 0);
+        while (xIndex > 0 && carry)
+            carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
+        // Copy remainder of longer number
+        while (xIndex > 0)
+            result[--xIndex] = x[xIndex];
+        // Grow result if necessary
+        if (carry) {
+            int bigger[] = new int[result.length + 1];
+            System.arraycopy(result, 0, bigger, 1, result.length);
+            bigger[0] = 0x01;
+            return bigger;
+        }
+        return result;
+    }
+
+    /**
+     * Adds the contents of the int arrays x and y. This method allocates
+     * a new int array to hold the answer and returns a reference to that
+     * array.
+     */
+    private static int[] add(int[] x, int[] y) {
+        // If x is shorter, swap the two arrays
+        if (x.length < y.length) {
+            int[] tmp = x;
+            x = y;
+            y = tmp;
+        }
+
+        int xIndex = x.length;
+        int yIndex = y.length;
+        int result[] = new int[xIndex];
+        long sum = 0;
+        if (yIndex == 1) {
+            sum = (x[--xIndex] & LONG_MASK) + (y[0] & LONG_MASK) ;
+            result[xIndex] = (int)sum;
+        } else {
+            // Add common parts of both numbers
+            while (yIndex > 0) {
+                sum = (x[--xIndex] & LONG_MASK) +
+                      (y[--yIndex] & LONG_MASK) + (sum >>> 32);
+                result[xIndex] = (int)sum;
+            }
+        }
+        // Copy remainder of longer number while carry propagation is required
+        boolean carry = (sum >>> 32 != 0);
+        while (xIndex > 0 && carry)
+            carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
+
+        // Copy remainder of longer number
+        while (xIndex > 0)
+            result[--xIndex] = x[xIndex];
+
+        // Grow result if necessary
+        if (carry) {
+            int bigger[] = new int[result.length + 1];
+            System.arraycopy(result, 0, bigger, 1, result.length);
+            bigger[0] = 0x01;
+            return bigger;
+        }
+        return result;
+    }
+
+    private static int[] subtract(long val, int[] little) {
+        int highWord = (int)(val >>> 32);
+        if (highWord == 0) {
+            int result[] = new int[1];
+            result[0] = (int)(val - (little[0] & LONG_MASK));
+            return result;
+        } else {
+            int result[] = new int[2];
+            if (little.length == 1) {
+                long difference = ((int)val & LONG_MASK) - (little[0] & LONG_MASK);
+                result[1] = (int)difference;
+                // Subtract remainder of longer number while borrow propagates
+                boolean borrow = (difference >> 32 != 0);
+                if (borrow) {
+                    result[0] = highWord - 1;
+                } else {        // Copy remainder of longer number
+                    result[0] = highWord;
+                }
+                return result;
+            } else { // little.length == 2
+                long difference = ((int)val & LONG_MASK) - (little[1] & LONG_MASK);
+                result[1] = (int)difference;
+                difference = (highWord & LONG_MASK) - (little[0] & LONG_MASK) + (difference >> 32);
+                result[0] = (int)difference;
+                return result;
+            }
+        }
+    }
+
+    /**
+     * Subtracts the contents of the second argument (val) from the
+     * first (big).  The first int array (big) must represent a larger number
+     * than the second.  This method allocates the space necessary to hold the
+     * answer.
+     * assumes val &gt;= 0
+     */
+    private static int[] subtract(int[] big, long val) {
+        int highWord = (int)(val >>> 32);
+        int bigIndex = big.length;
+        int result[] = new int[bigIndex];
+        long difference = 0;
+
+        if (highWord == 0) {
+            difference = (big[--bigIndex] & LONG_MASK) - val;
+            result[bigIndex] = (int)difference;
+        } else {
+            difference = (big[--bigIndex] & LONG_MASK) - (val & LONG_MASK);
+            result[bigIndex] = (int)difference;
+            difference = (big[--bigIndex] & LONG_MASK) - (highWord & LONG_MASK) + (difference >> 32);
+            result[bigIndex] = (int)difference;
+        }
+
+        // Subtract remainder of longer number while borrow propagates
+        boolean borrow = (difference >> 32 != 0);
+        while (bigIndex > 0 && borrow)
+            borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
+
+        // Copy remainder of longer number
+        while (bigIndex > 0)
+            result[--bigIndex] = big[bigIndex];
+
+        return result;
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this - val)}.
+     *
+     * @param  val value to be subtracted from this BigInteger.
+     * @return {@code this - val}
+     */
+    @NonNull public BigInteger subtract(@NonNull BigInteger val) {
+        if (val.signum == 0)
+            return this;
+        if (signum == 0)
+            return val.negate();
+        if (val.signum != signum)
+            return new BigInteger(add(mag, val.mag), signum);
+
+        int cmp = compareMagnitude(val);
+        if (cmp == 0)
+            return ZERO;
+        int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
+                           : subtract(val.mag, mag));
+        resultMag = trustedStripLeadingZeroInts(resultMag);
+        return new BigInteger(resultMag, cmp == signum ? 1 : -1);
+    }
+
+    /**
+     * Subtracts the contents of the second int arrays (little) from the
+     * first (big).  The first int array (big) must represent a larger number
+     * than the second.  This method allocates the space necessary to hold the
+     * answer.
+     */
+    private static int[] subtract(int[] big, int[] little) {
+        int bigIndex = big.length;
+        int result[] = new int[bigIndex];
+        int littleIndex = little.length;
+        long difference = 0;
+
+        // Subtract common parts of both numbers
+        while (littleIndex > 0) {
+            difference = (big[--bigIndex] & LONG_MASK) -
+                         (little[--littleIndex] & LONG_MASK) +
+                         (difference >> 32);
+            result[bigIndex] = (int)difference;
+        }
+
+        // Subtract remainder of longer number while borrow propagates
+        boolean borrow = (difference >> 32 != 0);
+        while (bigIndex > 0 && borrow)
+            borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
+
+        // Copy remainder of longer number
+        while (bigIndex > 0)
+            result[--bigIndex] = big[bigIndex];
+
+        return result;
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this * val)}.
+     *
+     * @implNote An implementation may offer better algorithmic
+     * performance when {@code val == this}.
+     *
+     * @param  val value to be multiplied by this BigInteger.
+     * @return {@code this * val}
+     */
+    @NonNull public BigInteger multiply(@NonNull BigInteger val) {
+        return multiply(val, false);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this * val)}.  If
+     * the invocation is recursive certain overflow checks are skipped.
+     *
+     * @param  val value to be multiplied by this BigInteger.
+     * @param  isRecursion whether this is a recursive invocation
+     * @return {@code this * val}
+     */
+    @NonNull private BigInteger multiply(@NonNull BigInteger val, boolean isRecursion) {
+        if (val.signum == 0 || signum == 0)
+            return ZERO;
+
+        int xlen = mag.length;
+
+        // BEGIN Android-changed: Fall back to the boringssl implementation for
+        // large arguments.
+        int ylen = val.mag.length;
+
+        final int BORINGSSL_MUL_THRESHOLD = 50;
+
+        int resultSign = signum == val.signum ? 1 : -1;
+        if ((xlen < BORINGSSL_MUL_THRESHOLD) || (ylen < BORINGSSL_MUL_THRESHOLD)) {
+            if (val == this && xlen > MULTIPLY_SQUARE_THRESHOLD) {
+                // Helps less than boringssl fallback; prefer that.
+                return square();
+            }
+
+            if (val.mag.length == 1) {
+                return multiplyByInt(mag,val.mag[0], resultSign);
+            }
+            if (mag.length == 1) {
+                return multiplyByInt(val.mag,mag[0], resultSign);
+            }
+            int[] result = multiplyToLen(mag, xlen,
+                                         val.mag, ylen, null);
+            result = trustedStripLeadingZeroInts(result);
+            return new BigInteger(result, resultSign);
+        } else {
+            long xBN = 0, yBN = 0, resultBN = 0;
+            try {
+                xBN = bigEndInts2NewBN(mag, /* neg= */false);
+                yBN = bigEndInts2NewBN(val.mag, /* neg= */false);
+                resultBN = NativeBN.BN_new();
+                NativeBN.BN_mul(resultBN, xBN, yBN);
+                return new BigInteger(resultSign, bn2BigEndInts(resultBN));
+            } finally {
+                NativeBN.BN_free(xBN);
+                NativeBN.BN_free(yBN);
+                NativeBN.BN_free(resultBN);
+            }
+
+            /*
+            if ((xlen < TOOM_COOK_THRESHOLD) && (ylen < TOOM_COOK_THRESHOLD)) {
+                return multiplyKaratsuba(this, val);
+            } else {
+                //
+                // In "Hacker's Delight" section 2-13, p.33, it is explained
+                // that if x and y are unsigned 32-bit quantities and m and n
+                // are their respective numbers of leading zeros within 32 bits,
+                // then the number of leading zeros within their product as a
+                // 64-bit unsigned quantity is either m + n or m + n + 1. If
+                // their product is not to overflow, it cannot exceed 32 bits,
+                // and so the number of leading zeros of the product within 64
+                // bits must be at least 32, i.e., the leftmost set bit is at
+                // zero-relative position 31 or less.
+                //
+                // From the above there are three cases:
+                //
+                //     m + n    leftmost set bit    condition
+                //     -----    ----------------    ---------
+                //     >= 32    x <= 64 - 32 = 32   no overflow
+                //     == 31    x >= 64 - 32 = 32   possible overflow
+                //     <= 30    x >= 64 - 31 = 33   definite overflow
+                //
+                // The "possible overflow" condition cannot be detected by
+                // examning data lengths alone and requires further calculation.
+                //
+                // By analogy, if 'this' and 'val' have m and n as their
+                // respective numbers of leading zeros within 32*MAX_MAG_LENGTH
+                // bits, then:
+                //
+                //     m + n >= 32*MAX_MAG_LENGTH        no overflow
+                //     m + n == 32*MAX_MAG_LENGTH - 1    possible overflow
+                //     m + n <= 32*MAX_MAG_LENGTH - 2    definite overflow
+                //
+                // Note however that if the number of ints in the result
+                // were to be MAX_MAG_LENGTH and mag[0] < 0, then there would
+                // be overflow. As a result the leftmost bit (of mag[0]) cannot
+                // be used and the constraints must be adjusted by one bit to:
+                //
+                //     m + n >  32*MAX_MAG_LENGTH        no overflow
+                //     m + n == 32*MAX_MAG_LENGTH        possible overflow
+                //     m + n <  32*MAX_MAG_LENGTH        definite overflow
+                //
+                // The foregoing leading zero-based discussion is for clarity
+                // only. The actual calculations use the estimated bit length
+                // of the product as this is more natural to the internal
+                // array representation of the magnitude which has no leading
+                // zero elements.
+                //
+                if (!isRecursion) {
+                    // The bitLength() instance method is not used here as we
+                    // are only considering the magnitudes as non-negative. The
+                    // Toom-Cook multiplication algorithm determines the sign
+                    // at its end from the two signum values.
+                    if (bitLength(mag, mag.length) +
+                        bitLength(val.mag, val.mag.length) >
+                        32L*MAX_MAG_LENGTH) {
+                        reportOverflow();
+                    }
+                }
+
+                return multiplyToomCook3(this, val);
+            }
+            */
+        }
+    }
+
+    @NonNull private static BigInteger multiplyByInt(int[] x, int y, int sign) {
+        if (Integer.bitCount(y) == 1) {
+            return new BigInteger(shiftLeft(x,Integer.numberOfTrailingZeros(y)), sign);
+        }
+        int xlen = x.length;
+        int[] rmag =  new int[xlen + 1];
+        long carry = 0;
+        long yl = y & LONG_MASK;
+        int rstart = rmag.length - 1;
+        for (int i = xlen - 1; i >= 0; i--) {
+            long product = (x[i] & LONG_MASK) * yl + carry;
+            rmag[rstart--] = (int)product;
+            carry = product >>> 32;
+        }
+        if (carry == 0L) {
+            rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
+        } else {
+            rmag[rstart] = (int)carry;
+        }
+        return new BigInteger(rmag, sign);
+    }
+
+    /**
+     * Package private methods used by BigDecimal code to multiply a BigInteger
+     * with a long. Assumes v is not equal to INFLATED.
+     */
+    @NonNull BigInteger multiply(long v) {
+        if (v == 0 || signum == 0)
+          return ZERO;
+        if (v == BigDecimal.INFLATED)
+            return multiply(BigInteger.valueOf(v));
+        int rsign = (v > 0 ? signum : -signum);
+        if (v < 0)
+            v = -v;
+        long dh = v >>> 32;      // higher order bits
+        long dl = v & LONG_MASK; // lower order bits
+
+        int xlen = mag.length;
+        int[] value = mag;
+        int[] rmag = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
+        long carry = 0;
+        int rstart = rmag.length - 1;
+        for (int i = xlen - 1; i >= 0; i--) {
+            long product = (value[i] & LONG_MASK) * dl + carry;
+            rmag[rstart--] = (int)product;
+            carry = product >>> 32;
+        }
+        rmag[rstart] = (int)carry;
+        if (dh != 0L) {
+            carry = 0;
+            rstart = rmag.length - 2;
+            for (int i = xlen - 1; i >= 0; i--) {
+                long product = (value[i] & LONG_MASK) * dh +
+                    (rmag[rstart] & LONG_MASK) + carry;
+                rmag[rstart--] = (int)product;
+                carry = product >>> 32;
+            }
+            rmag[0] = (int)carry;
+        }
+        if (carry == 0L)
+            rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
+        return new BigInteger(rmag, rsign);
+    }
+
+    /**
+     * Multiplies int arrays x and y to the specified lengths and places
+     * the result into z. There will be no leading zeros in the resultant array.
+     */
+    private static int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
+        int xstart = xlen - 1;
+        int ystart = ylen - 1;
+
+        if (z == null || z.length < (xlen+ ylen))
+             z = new int[xlen+ylen];
+
+        long carry = 0;
+        for (int j=ystart, k=ystart+1+xstart; j >= 0; j--, k--) {
+            long product = (y[j] & LONG_MASK) *
+                           (x[xstart] & LONG_MASK) + carry;
+            z[k] = (int)product;
+            carry = product >>> 32;
+        }
+        z[xstart] = (int)carry;
+
+        for (int i = xstart-1; i >= 0; i--) {
+            carry = 0;
+            for (int j=ystart, k=ystart+1+i; j >= 0; j--, k--) {
+                long product = (y[j] & LONG_MASK) *
+                               (x[i] & LONG_MASK) +
+                               (z[k] & LONG_MASK) + carry;
+                z[k] = (int)product;
+                carry = product >>> 32;
+            }
+            z[i] = (int)carry;
+        }
+        return z;
+    }
+
+    /**
+     * Multiplies two BigIntegers using the Karatsuba multiplication
+     * algorithm.  This is a recursive divide-and-conquer algorithm which is
+     * more efficient for large numbers than what is commonly called the
+     * "grade-school" algorithm used in multiplyToLen.  If the numbers to be
+     * multiplied have length n, the "grade-school" algorithm has an
+     * asymptotic complexity of O(n^2).  In contrast, the Karatsuba algorithm
+     * has complexity of O(n^(log2(3))), or O(n^1.585).  It achieves this
+     * increased performance by doing 3 multiplies instead of 4 when
+     * evaluating the product.  As it has some overhead, should be used when
+     * both numbers are larger than a certain threshold (found
+     * experimentally).
+     *
+     * See:  http://en.wikipedia.org/wiki/Karatsuba_algorithm
+     */
+    @NonNull private static BigInteger multiplyKaratsuba(@NonNull BigInteger x, @NonNull BigInteger y) {
+        int xlen = x.mag.length;
+        int ylen = y.mag.length;
+
+        // The number of ints in each half of the number.
+        int half = (Math.max(xlen, ylen)+1) / 2;
+
+        // xl and yl are the lower halves of x and y respectively,
+        // xh and yh are the upper halves.
+        BigInteger xl = x.getLower(half);
+        BigInteger xh = x.getUpper(half);
+        BigInteger yl = y.getLower(half);
+        BigInteger yh = y.getUpper(half);
+
+        BigInteger p1 = xh.multiply(yh);  // p1 = xh*yh
+        BigInteger p2 = xl.multiply(yl);  // p2 = xl*yl
+
+        // p3=(xh+xl)*(yh+yl)
+        BigInteger p3 = xh.add(xl).multiply(yh.add(yl));
+
+        // result = p1 * 2^(32*2*half) + (p3 - p1 - p2) * 2^(32*half) + p2
+        BigInteger result = p1.shiftLeft(32*half).add(p3.subtract(p1).subtract(p2)).shiftLeft(32*half).add(p2);
+
+        if (x.signum != y.signum) {
+            return result.negate();
+        } else {
+            return result;
+        }
+    }
+
+    /**
+     * Multiplies two BigIntegers using a 3-way Toom-Cook multiplication
+     * algorithm.  This is a recursive divide-and-conquer algorithm which is
+     * more efficient for large numbers than what is commonly called the
+     * "grade-school" algorithm used in multiplyToLen.  If the numbers to be
+     * multiplied have length n, the "grade-school" algorithm has an
+     * asymptotic complexity of O(n^2).  In contrast, 3-way Toom-Cook has a
+     * complexity of about O(n^1.465).  It achieves this increased asymptotic
+     * performance by breaking each number into three parts and by doing 5
+     * multiplies instead of 9 when evaluating the product.  Due to overhead
+     * (additions, shifts, and one division) in the Toom-Cook algorithm, it
+     * should only be used when both numbers are larger than a certain
+     * threshold (found experimentally).  This threshold is generally larger
+     * than that for Karatsuba multiplication, so this algorithm is generally
+     * only used when numbers become significantly larger.
+     *
+     * The algorithm used is the "optimal" 3-way Toom-Cook algorithm outlined
+     * by Marco Bodrato.
+     *
+     *  See: http://bodrato.it/toom-cook/
+     *       http://bodrato.it/papers/#WAIFI2007
+     *
+     * "Towards Optimal Toom-Cook Multiplication for Univariate and
+     * Multivariate Polynomials in Characteristic 2 and 0." by Marco BODRATO;
+     * In C.Carlet and B.Sunar, Eds., "WAIFI'07 proceedings", p. 116-133,
+     * LNCS #4547. Springer, Madrid, Spain, June 21-22, 2007.
+     *
+     */
+    @NonNull private static BigInteger multiplyToomCook3(@NonNull BigInteger a, @NonNull BigInteger b) {
+        int alen = a.mag.length;
+        int blen = b.mag.length;
+
+        int largest = Math.max(alen, blen);
+
+        // k is the size (in ints) of the lower-order slices.
+        int k = (largest+2)/3;   // Equal to ceil(largest/3)
+
+        // r is the size (in ints) of the highest-order slice.
+        int r = largest - 2*k;
+
+        // Obtain slices of the numbers. a2 and b2 are the most significant
+        // bits of the numbers a and b, and a0 and b0 the least significant.
+        BigInteger a0, a1, a2, b0, b1, b2;
+        a2 = a.getToomSlice(k, r, 0, largest);
+        a1 = a.getToomSlice(k, r, 1, largest);
+        a0 = a.getToomSlice(k, r, 2, largest);
+        b2 = b.getToomSlice(k, r, 0, largest);
+        b1 = b.getToomSlice(k, r, 1, largest);
+        b0 = b.getToomSlice(k, r, 2, largest);
+
+        BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1, db1;
+
+        v0 = a0.multiply(b0, true);
+        da1 = a2.add(a0);
+        db1 = b2.add(b0);
+        vm1 = da1.subtract(a1).multiply(db1.subtract(b1), true);
+        da1 = da1.add(a1);
+        db1 = db1.add(b1);
+        v1 = da1.multiply(db1, true);
+        v2 = da1.add(a2).shiftLeft(1).subtract(a0).multiply(
+             db1.add(b2).shiftLeft(1).subtract(b0), true);
+        vinf = a2.multiply(b2, true);
+
+        // The algorithm requires two divisions by 2 and one by 3.
+        // All divisions are known to be exact, that is, they do not produce
+        // remainders, and all results are positive.  The divisions by 2 are
+        // implemented as right shifts which are relatively efficient, leaving
+        // only an exact division by 3, which is done by a specialized
+        // linear-time algorithm.
+        t2 = v2.subtract(vm1).exactDivideBy3();
+        tm1 = v1.subtract(vm1).shiftRight(1);
+        t1 = v1.subtract(v0);
+        t2 = t2.subtract(t1).shiftRight(1);
+        t1 = t1.subtract(tm1).subtract(vinf);
+        t2 = t2.subtract(vinf.shiftLeft(1));
+        tm1 = tm1.subtract(t2);
+
+        // Number of bits to shift left.
+        int ss = k*32;
+
+        BigInteger result = vinf.shiftLeft(ss).add(t2).shiftLeft(ss).add(t1).shiftLeft(ss).add(tm1).shiftLeft(ss).add(v0);
+
+        if (a.signum != b.signum) {
+            return result.negate();
+        } else {
+            return result;
+        }
+    }
+
+
+    /**
+     * Returns a slice of a BigInteger for use in Toom-Cook multiplication.
+     *
+     * @param lowerSize The size of the lower-order bit slices.
+     * @param upperSize The size of the higher-order bit slices.
+     * @param slice The index of which slice is requested, which must be a
+     * number from 0 to size-1. Slice 0 is the highest-order bits, and slice
+     * size-1 are the lowest-order bits. Slice 0 may be of different size than
+     * the other slices.
+     * @param fullsize The size of the larger integer array, used to align
+     * slices to the appropriate position when multiplying different-sized
+     * numbers.
+     */
+    @NonNull private BigInteger getToomSlice(int lowerSize, int upperSize, int slice,
+                                    int fullsize) {
+        int start, end, sliceSize, len, offset;
+
+        len = mag.length;
+        offset = fullsize - len;
+
+        if (slice == 0) {
+            start = 0 - offset;
+            end = upperSize - 1 - offset;
+        } else {
+            start = upperSize + (slice-1)*lowerSize - offset;
+            end = start + lowerSize - 1;
+        }
+
+        if (start < 0) {
+            start = 0;
+        }
+        if (end < 0) {
+           return ZERO;
+        }
+
+        sliceSize = (end-start) + 1;
+
+        if (sliceSize <= 0) {
+            return ZERO;
+        }
+
+        // While performing Toom-Cook, all slices are positive and
+        // the sign is adjusted when the final number is composed.
+        if (start == 0 && sliceSize >= len) {
+            return this.abs();
+        }
+
+        int intSlice[] = new int[sliceSize];
+        System.arraycopy(mag, start, intSlice, 0, sliceSize);
+
+        return new BigInteger(trustedStripLeadingZeroInts(intSlice), 1);
+    }
+
+    /**
+     * Does an exact division (that is, the remainder is known to be zero)
+     * of the specified number by 3.  This is used in Toom-Cook
+     * multiplication.  This is an efficient algorithm that runs in linear
+     * time.  If the argument is not exactly divisible by 3, results are
+     * undefined.  Note that this is expected to be called with positive
+     * arguments only.
+     */
+    @NonNull private BigInteger exactDivideBy3() {
+        int len = mag.length;
+        int[] result = new int[len];
+        long x, w, q, borrow;
+        borrow = 0L;
+        for (int i=len-1; i >= 0; i--) {
+            x = (mag[i] & LONG_MASK);
+            w = x - borrow;
+            if (borrow > x) {      // Did we make the number go negative?
+                borrow = 1L;
+            } else {
+                borrow = 0L;
+            }
+
+            // 0xAAAAAAAB is the modular inverse of 3 (mod 2^32).  Thus,
+            // the effect of this is to divide by 3 (mod 2^32).
+            // This is much faster than division on most architectures.
+            q = (w * 0xAAAAAAABL) & LONG_MASK;
+            result[i] = (int) q;
+
+            // Now check the borrow. The second check can of course be
+            // eliminated if the first fails.
+            if (q >= 0x55555556L) {
+                borrow++;
+                if (q >= 0xAAAAAAABL)
+                    borrow++;
+            }
+        }
+        result = trustedStripLeadingZeroInts(result);
+        return new BigInteger(result, signum);
+    }
+
+    /**
+     * Returns a new BigInteger representing n lower ints of the number.
+     * This is used by Karatsuba multiplication and Karatsuba squaring.
+     */
+    @NonNull private BigInteger getLower(int n) {
+        int len = mag.length;
+
+        if (len <= n) {
+            return abs();
+        }
+
+        int lowerInts[] = new int[n];
+        System.arraycopy(mag, len-n, lowerInts, 0, n);
+
+        return new BigInteger(trustedStripLeadingZeroInts(lowerInts), 1);
+    }
+
+    /**
+     * Returns a new BigInteger representing mag.length-n upper
+     * ints of the number.  This is used by Karatsuba multiplication and
+     * Karatsuba squaring.
+     */
+    @NonNull private BigInteger getUpper(int n) {
+        int len = mag.length;
+
+        if (len <= n) {
+            return ZERO;
+        }
+
+        int upperLen = len - n;
+        int upperInts[] = new int[upperLen];
+        System.arraycopy(mag, 0, upperInts, 0, upperLen);
+
+        return new BigInteger(trustedStripLeadingZeroInts(upperInts), 1);
+    }
+
+    // Squaring
+
+    /**
+     * Returns a BigInteger whose value is {@code (this<sup>2</sup>)}.
+     *
+     * @return {@code this<sup>2</sup>}
+     */
+    @NonNull private BigInteger square() {
+        return square(false);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this<sup>2</sup>)}. If
+     * the invocation is recursive certain overflow checks are skipped.
+     *
+     * @param isRecursion whether this is a recursive invocation
+     * @return {@code this<sup>2</sup>}
+     */
+    @NonNull private BigInteger square(boolean isRecursion) {
+        if (signum == 0) {
+            return ZERO;
+        }
+        int len = mag.length;
+
+        if (len < KARATSUBA_SQUARE_THRESHOLD) {
+            int[] z = squareToLen(mag, len, null);
+            return new BigInteger(trustedStripLeadingZeroInts(z), 1);
+        } else {
+            if (len < TOOM_COOK_SQUARE_THRESHOLD) {
+                return squareKaratsuba();
+            } else {
+                //
+                // For a discussion of overflow detection see multiply()
+                //
+                if (!isRecursion) {
+                    if (bitLength(mag, mag.length) > 16L*MAX_MAG_LENGTH) {
+                        reportOverflow();
+                    }
+                }
+
+                return squareToomCook3();
+            }
+        }
+    }
+
+    /**
+     * Squares the contents of the int array x. The result is placed into the
+     * int array z.  The contents of x are not changed.
+     */
+    private static final int[] squareToLen(int[] x, int len, int[] z) {
+         int zlen = len << 1;
+         if (z == null || z.length < zlen)
+             z = new int[zlen];
+
+         // Execute checks before calling intrinsified method.
+         implSquareToLenChecks(x, len, z, zlen);
+         return implSquareToLen(x, len, z, zlen);
+     }
+
+     /**
+      * Parameters validation.
+      */
+     private static void implSquareToLenChecks(int[] x, int len, int[] z, int zlen) throws RuntimeException {
+         if (len < 1) {
+             throw new IllegalArgumentException("invalid input length: " + len);
+         }
+         if (len > x.length) {
+             throw new IllegalArgumentException("input length out of bound: " +
+                                        len + " > " + x.length);
+         }
+         if (len * 2 > z.length) {
+             throw new IllegalArgumentException("input length out of bound: " +
+                                        (len * 2) + " > " + z.length);
+         }
+         if (zlen < 1) {
+             throw new IllegalArgumentException("invalid input length: " + zlen);
+         }
+         if (zlen > z.length) {
+             throw new IllegalArgumentException("input length out of bound: " +
+                                        len + " > " + z.length);
+         }
+     }
+
+     /**
+      * Java Runtime may use intrinsic for this method.
+      */
+     private static final int[] implSquareToLen(int[] x, int len, int[] z, int zlen) {
+        /*
+         * The algorithm used here is adapted from Colin Plumb's C library.
+         * Technique: Consider the partial products in the multiplication
+         * of "abcde" by itself:
+         *
+         *               a  b  c  d  e
+         *            *  a  b  c  d  e
+         *          ==================
+         *              ae be ce de ee
+         *           ad bd cd dd de
+         *        ac bc cc cd ce
+         *     ab bb bc bd be
+         *  aa ab ac ad ae
+         *
+         * Note that everything above the main diagonal:
+         *              ae be ce de = (abcd) * e
+         *           ad bd cd       = (abc) * d
+         *        ac bc             = (ab) * c
+         *     ab                   = (a) * b
+         *
+         * is a copy of everything below the main diagonal:
+         *                       de
+         *                 cd ce
+         *           bc bd be
+         *     ab ac ad ae
+         *
+         * Thus, the sum is 2 * (off the diagonal) + diagonal.
+         *
+         * This is accumulated beginning with the diagonal (which
+         * consist of the squares of the digits of the input), which is then
+         * divided by two, the off-diagonal added, and multiplied by two
+         * again.  The low bit is simply a copy of the low bit of the
+         * input, so it doesn't need special care.
+         */
+
+        // Store the squares, right shifted one bit (i.e., divided by 2)
+        int lastProductLowWord = 0;
+        for (int j=0, i=0; j < len; j++) {
+            long piece = (x[j] & LONG_MASK);
+            long product = piece * piece;
+            z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
+            z[i++] = (int)(product >>> 1);
+            lastProductLowWord = (int)product;
+        }
+
+        // Add in off-diagonal sums
+        for (int i=len, offset=1; i > 0; i--, offset+=2) {
+            int t = x[i-1];
+            t = mulAdd(z, x, offset, i-1, t);
+            addOne(z, offset-1, i, t);
+        }
+
+        // Shift back up and set low bit
+        primitiveLeftShift(z, zlen, 1);
+        z[zlen-1] |= x[len-1] & 1;
+
+        return z;
+    }
+
+    /**
+     * Squares a BigInteger using the Karatsuba squaring algorithm.  It should
+     * be used when both numbers are larger than a certain threshold (found
+     * experimentally).  It is a recursive divide-and-conquer algorithm that
+     * has better asymptotic performance than the algorithm used in
+     * squareToLen.
+     */
+    @NonNull private BigInteger squareKaratsuba() {
+        int half = (mag.length+1) / 2;
+
+        BigInteger xl = getLower(half);
+        BigInteger xh = getUpper(half);
+
+        BigInteger xhs = xh.square();  // xhs = xh^2
+        BigInteger xls = xl.square();  // xls = xl^2
+
+        // xh^2 << 64  +  (((xl+xh)^2 - (xh^2 + xl^2)) << 32) + xl^2
+        return xhs.shiftLeft(half*32).add(xl.add(xh).square().subtract(xhs.add(xls))).shiftLeft(half*32).add(xls);
+    }
+
+    /**
+     * Squares a BigInteger using the 3-way Toom-Cook squaring algorithm.  It
+     * should be used when both numbers are larger than a certain threshold
+     * (found experimentally).  It is a recursive divide-and-conquer algorithm
+     * that has better asymptotic performance than the algorithm used in
+     * squareToLen or squareKaratsuba.
+     */
+    @NonNull private BigInteger squareToomCook3() {
+        int len = mag.length;
+
+        // k is the size (in ints) of the lower-order slices.
+        int k = (len+2)/3;   // Equal to ceil(largest/3)
+
+        // r is the size (in ints) of the highest-order slice.
+        int r = len - 2*k;
+
+        // Obtain slices of the numbers. a2 is the most significant
+        // bits of the number, and a0 the least significant.
+        BigInteger a0, a1, a2;
+        a2 = getToomSlice(k, r, 0, len);
+        a1 = getToomSlice(k, r, 1, len);
+        a0 = getToomSlice(k, r, 2, len);
+        BigInteger v0, v1, v2, vm1, vinf, t1, t2, tm1, da1;
+
+        v0 = a0.square(true);
+        da1 = a2.add(a0);
+        vm1 = da1.subtract(a1).square(true);
+        da1 = da1.add(a1);
+        v1 = da1.square(true);
+        vinf = a2.square(true);
+        v2 = da1.add(a2).shiftLeft(1).subtract(a0).square(true);
+
+        // The algorithm requires two divisions by 2 and one by 3.
+        // All divisions are known to be exact, that is, they do not produce
+        // remainders, and all results are positive.  The divisions by 2 are
+        // implemented as right shifts which are relatively efficient, leaving
+        // only a division by 3.
+        // The division by 3 is done by an optimized algorithm for this case.
+        t2 = v2.subtract(vm1).exactDivideBy3();
+        tm1 = v1.subtract(vm1).shiftRight(1);
+        t1 = v1.subtract(v0);
+        t2 = t2.subtract(t1).shiftRight(1);
+        t1 = t1.subtract(tm1).subtract(vinf);
+        t2 = t2.subtract(vinf.shiftLeft(1));
+        tm1 = tm1.subtract(t2);
+
+        // Number of bits to shift left.
+        int ss = k*32;
+
+        return vinf.shiftLeft(ss).add(t2).shiftLeft(ss).add(t1).shiftLeft(ss).add(tm1).shiftLeft(ss).add(v0);
+    }
+
+    // Division
+
+
+    // BEGIN Android-modified: Fall back to boringssl for large problems.
+    private static final int BORINGSSL_DIV_THRESHOLD = 40;
+    private static final int BORINGSSL_DIV_OFFSET = 20;
+
+    /**
+     * Returns a BigInteger whose value is {@code (this / val)}.
+     *
+     * @param  val value by which this BigInteger is to be divided.
+     * @return {@code this / val}
+     * @throws ArithmeticException if {@code val} is zero.
+     */
+    @NonNull public BigInteger divide(@NonNull BigInteger val) {
+        // if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
+        //        mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
+        if (mag.length < BORINGSSL_DIV_THRESHOLD ||
+                mag.length - val.mag.length < BORINGSSL_DIV_OFFSET) {
+            return divideKnuth(val);
+        } else {
+            return divideAndRemainder(val)[0];
+            // return divideBurnikelZiegler(val);
+        }
+    }
+    // END Android-modified: Fall back to boringssl for large problems.
+
+
+    /**
+     * Returns a BigInteger whose value is {@code (this / val)} using an O(n^2) algorithm from Knuth.
+     *
+     * @param  val value by which this BigInteger is to be divided.
+     * @return {@code this / val}
+     * @throws ArithmeticException if {@code val} is zero.
+     * @see MutableBigInteger#divideKnuth(MutableBigInteger, MutableBigInteger, boolean)
+     */
+    @NonNull private BigInteger divideKnuth(@NonNull BigInteger val) {
+        MutableBigInteger q = new MutableBigInteger(),
+                          a = new MutableBigInteger(this.mag),
+                          b = new MutableBigInteger(val.mag);
+
+        a.divideKnuth(b, q, false);
+        return q.toBigInteger(this.signum * val.signum);
+    }
+
+    /**
+     * Returns an array of two BigIntegers containing {@code (this / val)}
+     * followed by {@code (this % val)}.
+     *
+     * @param  val value by which this BigInteger is to be divided, and the
+     *         remainder computed.
+     * @return an array of two BigIntegers: the quotient {@code (this / val)}
+     *         is the initial element, and the remainder {@code (this % val)}
+     *         is the final element.
+     * @throws ArithmeticException if {@code val} is zero.
+     */
+    @NonNull public BigInteger[] divideAndRemainder(@NonNull BigInteger val) {
+        // BEGIN Android-modified: Fall back to boringssl for large problems.
+
+        // if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
+        //        mag.length - val.mag < BURNIKEL_ZIEGLER_OFFSET) {
+        if (val.mag.length < BORINGSSL_DIV_THRESHOLD ||
+                mag.length < BORINGSSL_DIV_OFFSET ||
+                mag.length - val.mag.length < BORINGSSL_DIV_OFFSET) {
+            return divideAndRemainderKnuth(val);
+        } else {
+            int quotSign = signum == val.signum ? 1 : -1;  // 0 divided doesn't get here.
+            long xBN = 0, yBN = 0, quotBN = 0, remBN = 0;
+            try {
+                xBN = bigEndInts2NewBN(mag, /* neg= */false);
+                yBN = bigEndInts2NewBN(val.mag, /* neg= */false);
+                quotBN = NativeBN.BN_new();
+                remBN = NativeBN.BN_new();
+                NativeBN.BN_div(quotBN, remBN, xBN, yBN);
+                BigInteger quotient = new BigInteger(quotSign, bn2BigEndInts(quotBN));
+                        // The sign of a zero quotient is fixed by the constructor.
+                BigInteger remainder = new BigInteger(signum, bn2BigEndInts(remBN));
+                BigInteger[] result = {quotient, remainder};
+                return result;
+            } finally {
+                NativeBN.BN_free(xBN);
+                NativeBN.BN_free(yBN);
+                NativeBN.BN_free(quotBN);
+                NativeBN.BN_free(remBN);
+            }
+            // return divideAndRemainderBurnikelZiegler(val);
+        }
+        // END Android-modified: Fall back to boringssl for large problems.
+    }
+
+    /** Long division */
+    @NonNull private BigInteger[] divideAndRemainderKnuth(@NonNull BigInteger val) {
+        BigInteger[] result = new BigInteger[2];
+        MutableBigInteger q = new MutableBigInteger(),
+                          a = new MutableBigInteger(this.mag),
+                          b = new MutableBigInteger(val.mag);
+        MutableBigInteger r = a.divideKnuth(b, q);
+        result[0] = q.toBigInteger(this.signum == val.signum ? 1 : -1);
+        result[1] = r.toBigInteger(this.signum);
+        return result;
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this % val)}.
+     *
+     * @param  val value by which this BigInteger is to be divided, and the
+     *         remainder computed.
+     * @return {@code this % val}
+     * @throws ArithmeticException if {@code val} is zero.
+     */
+    @NonNull public BigInteger remainder(@NonNull BigInteger val) {
+        // BEGIN Android-modified: Fall back to boringssl for large problems.
+        // if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
+        //        mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
+        if (val.mag.length < BORINGSSL_DIV_THRESHOLD ||
+                mag.length - val.mag.length < BORINGSSL_DIV_THRESHOLD) {
+            return remainderKnuth(val);
+        } else {
+            return divideAndRemainder(val)[1];
+            // return remainderBurnikelZiegler(val);
+        }
+        // END Android-modified: Fall back to boringssl for large problems.
+    }
+
+    /** Long division */
+    @NonNull private BigInteger remainderKnuth(@NonNull BigInteger val) {
+        MutableBigInteger q = new MutableBigInteger(),
+                          a = new MutableBigInteger(this.mag),
+                          b = new MutableBigInteger(val.mag);
+
+        return a.divideKnuth(b, q).toBigInteger(this.signum);
+    }
+
+    /**
+     * Calculates {@code this / val} using the Burnikel-Ziegler algorithm.
+     * @param  val the divisor
+     * @return {@code this / val}
+     */
+    @NonNull private BigInteger divideBurnikelZiegler(@NonNull BigInteger val) {
+        return divideAndRemainderBurnikelZiegler(val)[0];
+    }
+
+    /**
+     * Calculates {@code this % val} using the Burnikel-Ziegler algorithm.
+     * @param val the divisor
+     * @return {@code this % val}
+     */
+    @NonNull private BigInteger remainderBurnikelZiegler(@NonNull BigInteger val) {
+        return divideAndRemainderBurnikelZiegler(val)[1];
+    }
+
+    /**
+     * Computes {@code this / val} and {@code this % val} using the
+     * Burnikel-Ziegler algorithm.
+     * @param val the divisor
+     * @return an array containing the quotient and remainder
+     */
+    @NonNull private BigInteger[] divideAndRemainderBurnikelZiegler(@NonNull BigInteger val) {
+        MutableBigInteger q = new MutableBigInteger();
+        MutableBigInteger r = new MutableBigInteger(this).divideAndRemainderBurnikelZiegler(new MutableBigInteger(val), q);
+        BigInteger qBigInt = q.isZero() ? ZERO : q.toBigInteger(signum*val.signum);
+        BigInteger rBigInt = r.isZero() ? ZERO : r.toBigInteger(signum);
+        return new BigInteger[] {qBigInt, rBigInt};
+    }
+
+    /**
+     * Returns a BigInteger whose value is <tt>(this<sup>exponent</sup>)</tt>.
+     * Note that {@code exponent} is an integer rather than a BigInteger.
+     *
+     * @param  exponent exponent to which this BigInteger is to be raised.
+     * @return <tt>this<sup>exponent</sup></tt>
+     * @throws ArithmeticException {@code exponent} is negative.  (This would
+     *         cause the operation to yield a non-integer value.)
+     */
+    @NonNull public BigInteger pow(int exponent) {
+        if (exponent < 0) {
+            throw new ArithmeticException("Negative exponent");
+        }
+        if (signum == 0) {
+            return (exponent == 0 ? ONE : this);
+        }
+
+        BigInteger partToSquare = this.abs();
+
+        // Factor out powers of two from the base, as the exponentiation of
+        // these can be done by left shifts only.
+        // The remaining part can then be exponentiated faster.  The
+        // powers of two will be multiplied back at the end.
+        int powersOfTwo = partToSquare.getLowestSetBit();
+        long bitsToShiftLong = (long)powersOfTwo * exponent;
+        if (bitsToShiftLong > Integer.MAX_VALUE) {
+            reportOverflow();
+        }
+        int bitsToShift = (int)bitsToShiftLong;
+
+        int remainingBits;
+
+        // Factor the powers of two out quickly by shifting right, if needed.
+        if (powersOfTwo > 0) {
+            partToSquare = partToSquare.shiftRight(powersOfTwo);
+            remainingBits = partToSquare.bitLength();
+            if (remainingBits == 1) {  // Nothing left but +/- 1?
+                if (signum < 0 && (exponent&1) == 1) {
+                    return NEGATIVE_ONE.shiftLeft(bitsToShift);
+                } else {
+                    return ONE.shiftLeft(bitsToShift);
+                }
+            }
+        } else {
+            remainingBits = partToSquare.bitLength();
+            if (remainingBits == 1) { // Nothing left but +/- 1?
+                if (signum < 0  && (exponent&1) == 1) {
+                    return NEGATIVE_ONE;
+                } else {
+                    return ONE;
+                }
+            }
+        }
+
+        // This is a quick way to approximate the size of the result,
+        // similar to doing log2[n] * exponent.  This will give an upper bound
+        // of how big the result can be, and which algorithm to use.
+        long scaleFactor = (long)remainingBits * exponent;
+
+        // Use slightly different algorithms for small and large operands.
+        // See if the result will safely fit into a long. (Largest 2^63-1)
+        if (partToSquare.mag.length == 1 && scaleFactor <= 62) {
+            // Small number algorithm.  Everything fits into a long.
+            int newSign = (signum <0  && (exponent&1) == 1 ? -1 : 1);
+            long result = 1;
+            long baseToPow2 = partToSquare.mag[0] & LONG_MASK;
+
+            int workingExponent = exponent;
+
+            // Perform exponentiation using repeated squaring trick
+            while (workingExponent != 0) {
+                if ((workingExponent & 1) == 1) {
+                    result = result * baseToPow2;
+                }
+
+                if ((workingExponent >>>= 1) != 0) {
+                    baseToPow2 = baseToPow2 * baseToPow2;
+                }
+            }
+
+            // Multiply back the powers of two (quickly, by shifting left)
+            if (powersOfTwo > 0) {
+                if (bitsToShift + scaleFactor <= 62) { // Fits in long?
+                    return valueOf((result << bitsToShift) * newSign);
+                } else {
+                    return valueOf(result*newSign).shiftLeft(bitsToShift);
+                }
+            } else {
+                return valueOf(result*newSign);
+            }
+        } else {
+            if ((long)bitLength() * exponent / Integer.SIZE > MAX_MAG_LENGTH) {
+                reportOverflow();
+            }
+
+            // Large number algorithm.  This is basically identical to
+            // the algorithm above, but calls multiply() and square()
+            // which may use more efficient algorithms for large numbers.
+            BigInteger answer = ONE;
+
+            int workingExponent = exponent;
+            // Perform exponentiation using repeated squaring trick
+            while (workingExponent != 0) {
+                if ((workingExponent & 1) == 1) {
+                    answer = answer.multiply(partToSquare);
+                }
+
+                if ((workingExponent >>>= 1) != 0) {
+                    partToSquare = partToSquare.square();
+                }
+            }
+            // Multiply back the (exponentiated) powers of two (quickly,
+            // by shifting left)
+            if (powersOfTwo > 0) {
+                answer = answer.shiftLeft(bitsToShift);
+            }
+
+            if (signum < 0 && (exponent&1) == 1) {
+                return answer.negate();
+            } else {
+                return answer;
+            }
+        }
+    }
+
+    /**
+     * Returns a BigInteger whose value is the greatest common divisor of
+     * {@code abs(this)} and {@code abs(val)}.  Returns 0 if
+     * {@code this == 0 && val == 0}.
+     *
+     * @param  val value with which the GCD is to be computed.
+     * @return {@code GCD(abs(this), abs(val))}
+     */
+    @NonNull public BigInteger gcd(@NonNull BigInteger val) {
+        if (val.signum == 0)
+            return this.abs();
+        else if (this.signum == 0)
+            return val.abs();
+
+        MutableBigInteger a = new MutableBigInteger(this);
+        MutableBigInteger b = new MutableBigInteger(val);
+
+        MutableBigInteger result = a.hybridGCD(b);
+
+        return result.toBigInteger(1);
+    }
+
+    /**
+     * Package private method to return bit length for an integer.
+     */
+    static int bitLengthForInt(int n) {
+        return 32 - Integer.numberOfLeadingZeros(n);
+    }
+
+    /**
+     * Left shift int array a up to len by n bits. Returns the array that
+     * results from the shift since space may have to be reallocated.
+     */
+    private static int[] leftShift(int[] a, int len, int n) {
+        int nInts = n >>> 5;
+        int nBits = n&0x1F;
+        int bitsInHighWord = bitLengthForInt(a[0]);
+
+        // If shift can be done without recopy, do so
+        if (n <= (32-bitsInHighWord)) {
+            primitiveLeftShift(a, len, nBits);
+            return a;
+        } else { // Array must be resized
+            if (nBits <= (32-bitsInHighWord)) {
+                int result[] = new int[nInts+len];
+                System.arraycopy(a, 0, result, 0, len);
+                primitiveLeftShift(result, result.length, nBits);
+                return result;
+            } else {
+                int result[] = new int[nInts+len+1];
+                System.arraycopy(a, 0, result, 0, len);
+                primitiveRightShift(result, result.length, 32 - nBits);
+                return result;
+            }
+        }
+    }
+
+    // shifts a up to len right n bits assumes no leading zeros, 0<n<32
+    static void primitiveRightShift(int[] a, int len, int n) {
+        int n2 = 32 - n;
+        for (int i=len-1, c=a[i]; i > 0; i--) {
+            int b = c;
+            c = a[i-1];
+            a[i] = (c << n2) | (b >>> n);
+        }
+        a[0] >>>= n;
+    }
+
+    // shifts a up to len left n bits assumes no leading zeros, 0<=n<32
+    static void primitiveLeftShift(int[] a, int len, int n) {
+        if (len == 0 || n == 0)
+            return;
+
+        int n2 = 32 - n;
+        for (int i=0, c=a[i], m=i+len-1; i < m; i++) {
+            int b = c;
+            c = a[i+1];
+            a[i] = (b << n) | (c >>> n2);
+        }
+        a[len-1] <<= n;
+    }
+
+    /**
+     * Calculate bitlength of contents of the first len elements an int array,
+     * assuming there are no leading zero ints.
+     */
+    private static int bitLength(int[] val, int len) {
+        if (len == 0)
+            return 0;
+        return ((len - 1) << 5) + bitLengthForInt(val[0]);
+    }
+
+    /**
+     * Returns a BigInteger whose value is the absolute value of this
+     * BigInteger.
+     *
+     * @return {@code abs(this)}
+     */
+    @NonNull public BigInteger abs() {
+        return (signum >= 0 ? this : this.negate());
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (-this)}.
+     *
+     * @return {@code -this}
+     */
+    @NonNull public BigInteger negate() {
+        return new BigInteger(this.mag, -this.signum);
+    }
+
+    /**
+     * Returns the signum function of this BigInteger.
+     *
+     * @return -1, 0 or 1 as the value of this BigInteger is negative, zero or
+     *         positive.
+     */
+    public int signum() {
+        return this.signum;
+    }
+
+    // Modular Arithmetic Operations
+
+    /**
+     * Returns a BigInteger whose value is {@code (this mod m}).  This method
+     * differs from {@code remainder} in that it always returns a
+     * <i>non-negative</i> BigInteger.
+     *
+     * @param  m the modulus.
+     * @return {@code this mod m}
+     * @throws ArithmeticException {@code m} &le; 0
+     * @see    #remainder
+     */
+    @NonNull public BigInteger mod(@NonNull BigInteger m) {
+        if (m.signum <= 0)
+            throw new ArithmeticException("BigInteger: modulus not positive");
+
+        BigInteger result = this.remainder(m);
+        return (result.signum >= 0 ? result : result.add(m));
+    }
+
+    // BEGIN Android-added: Support fallback to boringssl where it makes sense.
+    // The conversion itself takes linear time, so this only makes sense for largish superlinear
+    // operations.
+
+    private static int[] reverse(int[] arg) {
+      int len = arg.length;
+      int[] result = new int[len];
+      for (int i = 0; i < len; ++i) {
+        result[i] = arg[len - i - 1];
+      }
+      return result;
+    }
+
+    private static long /* BN */ bigEndInts2NewBN(int[] beArray, boolean neg) {
+      // The input is an array of ints arranged in big-endian order, i.e. most significant int
+      // first. BN deals with big-endian or little-endian byte arrays, so we need to reverse order.
+      int[] leArray = reverse(beArray);
+      long resultBN = NativeBN.BN_new();
+      NativeBN.litEndInts2bn(leArray, leArray.length, neg, resultBN);
+      return resultBN;
+    }
+
+    private int[] bn2BigEndInts(long bn) {
+      return reverse(NativeBN.bn2litEndInts(bn));
+    }
+
+    // END Android-added: Support fallback to boringssl.
+
+
+    /**
+     * Returns a BigInteger whose value is
+     * <tt>(this<sup>exponent</sup> mod m)</tt>.  (Unlike {@code pow}, this
+     * method permits negative exponents.)
+     *
+     * @param  exponent the exponent.
+     * @param  m the modulus.
+     * @return <tt>this<sup>exponent</sup> mod m</tt>
+     * @throws ArithmeticException {@code m} &le; 0 or the exponent is
+     *         negative and this BigInteger is not <i>relatively
+     *         prime</i> to {@code m}.
+     * @see    #modInverse
+     */
+    @NonNull public BigInteger modPow(@NonNull BigInteger exponent, @NonNull BigInteger m) {
+        if (m.signum <= 0)
+            throw new ArithmeticException("BigInteger: modulus not positive");
+
+        // Trivial cases
+        if (exponent.signum == 0)
+            return (m.equals(ONE) ? ZERO : ONE);
+
+        if (this.equals(ONE))
+            return (m.equals(ONE) ? ZERO : ONE);
+
+        if (this.equals(ZERO) && exponent.signum >= 0)
+            return ZERO;
+
+        if (this.equals(negConst[1]) && (!exponent.testBit(0)))
+            return (m.equals(ONE) ? ZERO : ONE);
+
+        boolean invertResult;
+        if ((invertResult = (exponent.signum < 0)))
+            exponent = exponent.negate();
+
+        BigInteger base = (this.signum < 0 || this.compareTo(m) >= 0
+                           ? this.mod(m) : this);
+        BigInteger result;
+        // BEGIN Android-added: Fall back to the boringssl implementation, which
+        // is usually faster.
+        final int BORINGSSL_MOD_EXP_THRESHOLD = 3;
+        if (m.mag.length >= BORINGSSL_MOD_EXP_THRESHOLD) {
+            long baseBN = 0, expBN = 0, modBN = 0, resultBN = 0;
+            try {
+                baseBN = bigEndInts2NewBN(base.mag, /* neg= */false);
+                expBN = bigEndInts2NewBN(exponent.mag, /* neg= */false);
+                modBN = bigEndInts2NewBN(m.mag, /* neg= */false);
+                resultBN = NativeBN.BN_new();
+                NativeBN.BN_mod_exp(resultBN, baseBN, expBN, modBN);
+                result = new BigInteger(1, bn2BigEndInts(resultBN));
+                        // The sign of a zero result is fixed by the constructor.
+                return (invertResult ? result.modInverse(m) : result);
+            } finally {
+                NativeBN.BN_free(baseBN);
+                NativeBN.BN_free(expBN);
+                NativeBN.BN_free(modBN);
+                NativeBN.BN_free(resultBN);
+            }
+        }
+        // END Android-added: Fall back to the boringssl implementation.
+        if (m.testBit(0)) { // odd modulus
+            result = base.oddModPow(exponent, m);
+        } else {
+            /*
+             * Even modulus.  Tear it into an "odd part" (m1) and power of two
+             * (m2), exponentiate mod m1, manually exponentiate mod m2, and
+             * use Chinese Remainder Theorem to combine results.
+             */
+
+            // Tear m apart into odd part (m1) and power of 2 (m2)
+            int p = m.getLowestSetBit();   // Max pow of 2 that divides m
+
+            BigInteger m1 = m.shiftRight(p);  // m/2**p
+            BigInteger m2 = ONE.shiftLeft(p); // 2**p
+
+            // Calculate new base from m1
+            BigInteger base2 = (this.signum < 0 || this.compareTo(m1) >= 0
+                                ? this.mod(m1) : this);
+
+            // Calculate (base ** exponent) mod m1.
+            BigInteger a1 = (m1.equals(ONE) ? ZERO :
+                             base2.oddModPow(exponent, m1));
+
+            // Calculate (this ** exponent) mod m2
+            BigInteger a2 = base.modPow2(exponent, p);
+
+            // Combine results using Chinese Remainder Theorem
+            BigInteger y1 = m2.modInverse(m1);
+            BigInteger y2 = m1.modInverse(m2);
+
+            if (m.mag.length < MAX_MAG_LENGTH / 2) {
+                result = a1.multiply(m2).multiply(y1).add(a2.multiply(m1).multiply(y2)).mod(m);
+            } else {
+                MutableBigInteger t1 = new MutableBigInteger();
+                new MutableBigInteger(a1.multiply(m2)).multiply(new MutableBigInteger(y1), t1);
+                MutableBigInteger t2 = new MutableBigInteger();
+                new MutableBigInteger(a2.multiply(m1)).multiply(new MutableBigInteger(y2), t2);
+                t1.add(t2);
+                MutableBigInteger q = new MutableBigInteger();
+                result = t1.divide(new MutableBigInteger(m), q).toBigInteger();
+            }
+        }
+
+        return (invertResult ? result.modInverse(m) : result);
+    }
+
+    // Montgomery multiplication.  These are wrappers for
+    // implMontgomeryXX routines which are expected to be replaced by
+    // virtual machine intrinsics.  We don't use the intrinsics for
+    // very large operands: MONTGOMERY_INTRINSIC_THRESHOLD should be
+    // larger than any reasonable crypto key.
+    private static int[] montgomeryMultiply(int[] a, int[] b, int[] n, int len, long inv,
+                                            int[] product) {
+        implMontgomeryMultiplyChecks(a, b, n, len, product);
+        if (len > MONTGOMERY_INTRINSIC_THRESHOLD) {
+            // Very long argument: do not use an intrinsic
+            product = multiplyToLen(a, len, b, len, product);
+            return montReduce(product, n, len, (int)inv);
+        } else {
+            return implMontgomeryMultiply(a, b, n, len, inv, materialize(product, len));
+        }
+    }
+    private static int[] montgomerySquare(int[] a, int[] n, int len, long inv,
+                                          int[] product) {
+        implMontgomeryMultiplyChecks(a, a, n, len, product);
+        if (len > MONTGOMERY_INTRINSIC_THRESHOLD) {
+            // Very long argument: do not use an intrinsic
+            product = squareToLen(a, len, product);
+            return montReduce(product, n, len, (int)inv);
+        } else {
+            return implMontgomerySquare(a, n, len, inv, materialize(product, len));
+        }
+    }
+
+    // Range-check everything.
+    private static void implMontgomeryMultiplyChecks
+        (int[] a, int[] b, int[] n, int len, int[] product) throws RuntimeException {
+        if (len % 2 != 0) {
+            throw new IllegalArgumentException("input array length must be even: " + len);
+        }
+
+        if (len < 1) {
+            throw new IllegalArgumentException("invalid input length: " + len);
+        }
+
+        if (len > a.length ||
+            len > b.length ||
+            len > n.length ||
+            (product != null && len > product.length)) {
+            throw new IllegalArgumentException("input array length out of bound: " + len);
+        }
+    }
+
+    // Make sure that the int array z (which is expected to contain
+    // the result of a Montgomery multiplication) is present and
+    // sufficiently large.
+    private static int[] materialize(int[] z, int len) {
+         if (z == null || z.length < len)
+             z = new int[len];
+         return z;
+    }
+
+    // These methods are intended to be be replaced by virtual machine
+    // intrinsics.
+    private static int[] implMontgomeryMultiply(int[] a, int[] b, int[] n, int len,
+                                         long inv, int[] product) {
+        product = multiplyToLen(a, len, b, len, product);
+        return montReduce(product, n, len, (int)inv);
+    }
+    private static int[] implMontgomerySquare(int[] a, int[] n, int len,
+                                       long inv, int[] product) {
+        product = squareToLen(a, len, product);
+        return montReduce(product, n, len, (int)inv);
+    }
+
+    static int[] bnExpModThreshTable = {7, 25, 81, 241, 673, 1793,
+                                                Integer.MAX_VALUE}; // Sentinel
+
+    /**
+     * Returns a BigInteger whose value is x to the power of y mod z.
+     * Assumes: z is odd && x < z.
+     */
+    @NonNull private BigInteger oddModPow(@NonNull BigInteger y, @NonNull BigInteger z) {
+    /*
+     * The algorithm is adapted from Colin Plumb's C library.
+     *
+     * The window algorithm:
+     * The idea is to keep a running product of b1 = n^(high-order bits of exp)
+     * and then keep appending exponent bits to it.  The following patterns
+     * apply to a 3-bit window (k = 3):
+     * To append   0: square
+     * To append   1: square, multiply by n^1
+     * To append  10: square, multiply by n^1, square
+     * To append  11: square, square, multiply by n^3
+     * To append 100: square, multiply by n^1, square, square
+     * To append 101: square, square, square, multiply by n^5
+     * To append 110: square, square, multiply by n^3, square
+     * To append 111: square, square, square, multiply by n^7
+     *
+     * Since each pattern involves only one multiply, the longer the pattern
+     * the better, except that a 0 (no multiplies) can be appended directly.
+     * We precompute a table of odd powers of n, up to 2^k, and can then
+     * multiply k bits of exponent at a time.  Actually, assuming random
+     * exponents, there is on average one zero bit between needs to
+     * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
+     * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
+     * you have to do one multiply per k+1 bits of exponent.
+     *
+     * The loop walks down the exponent, squaring the result buffer as
+     * it goes.  There is a wbits+1 bit lookahead buffer, buf, that is
+     * filled with the upcoming exponent bits.  (What is read after the
+     * end of the exponent is unimportant, but it is filled with zero here.)
+     * When the most-significant bit of this buffer becomes set, i.e.
+     * (buf & tblmask) != 0, we have to decide what pattern to multiply
+     * by, and when to do it.  We decide, remember to do it in future
+     * after a suitable number of squarings have passed (e.g. a pattern
+     * of "100" in the buffer requires that we multiply by n^1 immediately;
+     * a pattern of "110" calls for multiplying by n^3 after one more
+     * squaring), clear the buffer, and continue.
+     *
+     * When we start, there is one more optimization: the result buffer
+     * is implcitly one, so squaring it or multiplying by it can be
+     * optimized away.  Further, if we start with a pattern like "100"
+     * in the lookahead window, rather than placing n into the buffer
+     * and then starting to square it, we have already computed n^2
+     * to compute the odd-powers table, so we can place that into
+     * the buffer and save a squaring.
+     *
+     * This means that if you have a k-bit window, to compute n^z,
+     * where z is the high k bits of the exponent, 1/2 of the time
+     * it requires no squarings.  1/4 of the time, it requires 1
+     * squaring, ... 1/2^(k-1) of the time, it requires k-2 squarings.
+     * And the remaining 1/2^(k-1) of the time, the top k bits are a
+     * 1 followed by k-1 0 bits, so it again only requires k-2
+     * squarings, not k-1.  The average of these is 1.  Add that
+     * to the one squaring we have to do to compute the table,
+     * and you'll see that a k-bit window saves k-2 squarings
+     * as well as reducing the multiplies.  (It actually doesn't
+     * hurt in the case k = 1, either.)
+     */
+        // Special case for exponent of one
+        if (y.equals(ONE))
+            return this;
+
+        // Special case for base of zero
+        if (signum == 0)
+            return ZERO;
+
+        int[] base = mag.clone();
+        int[] exp = y.mag;
+        int[] mod = z.mag;
+        int modLen = mod.length;
+
+        // Make modLen even. It is conventional to use a cryptographic
+        // modulus that is 512, 768, 1024, or 2048 bits, so this code
+        // will not normally be executed. However, it is necessary for
+        // the correct functioning of the HotSpot intrinsics.
+        if ((modLen & 1) != 0) {
+            int[] x = new int[modLen + 1];
+            System.arraycopy(mod, 0, x, 1, modLen);
+            mod = x;
+            modLen++;
+        }
+
+        // Select an appropriate window size
+        int wbits = 0;
+        int ebits = bitLength(exp, exp.length);
+        // if exponent is 65537 (0x10001), use minimum window size
+        if ((ebits != 17) || (exp[0] != 65537)) {
+            while (ebits > bnExpModThreshTable[wbits]) {
+                wbits++;
+            }
+        }
+
+        // Calculate appropriate table size
+        int tblmask = 1 << wbits;
+
+        // Allocate table for precomputed odd powers of base in Montgomery form
+        int[][] table = new int[tblmask][];
+        for (int i=0; i < tblmask; i++)
+            table[i] = new int[modLen];
+
+        // Compute the modular inverse of the least significant 64-bit
+        // digit of the modulus
+        long n0 = (mod[modLen-1] & LONG_MASK) + ((mod[modLen-2] & LONG_MASK) << 32);
+        long inv = -MutableBigInteger.inverseMod64(n0);
+
+        // Convert base to Montgomery form
+        int[] a = leftShift(base, base.length, modLen << 5);
+
+        MutableBigInteger q = new MutableBigInteger(),
+                          a2 = new MutableBigInteger(a),
+                          b2 = new MutableBigInteger(mod);
+        b2.normalize(); // MutableBigInteger.divide() assumes that its
+                        // divisor is in normal form.
+
+        MutableBigInteger r= a2.divide(b2, q);
+        table[0] = r.toIntArray();
+
+        // Pad table[0] with leading zeros so its length is at least modLen
+        if (table[0].length < modLen) {
+           int offset = modLen - table[0].length;
+           int[] t2 = new int[modLen];
+           System.arraycopy(table[0], 0, t2, offset, table[0].length);
+           table[0] = t2;
+        }
+
+        // Set b to the square of the base
+        int[] b = montgomerySquare(table[0], mod, modLen, inv, null);
+
+        // Set t to high half of b
+        int[] t = Arrays.copyOf(b, modLen);
+
+        // Fill in the table with odd powers of the base
+        for (int i=1; i < tblmask; i++) {
+            table[i] = montgomeryMultiply(t, table[i-1], mod, modLen, inv, null);
+        }
+
+        // Pre load the window that slides over the exponent
+        int bitpos = 1 << ((ebits-1) & (32-1));
+
+        int buf = 0;
+        int elen = exp.length;
+        int eIndex = 0;
+        for (int i = 0; i <= wbits; i++) {
+            buf = (buf << 1) | (((exp[eIndex] & bitpos) != 0)?1:0);
+            bitpos >>>= 1;
+            if (bitpos == 0) {
+                eIndex++;
+                bitpos = 1 << (32-1);
+                elen--;
+            }
+        }
+
+        int multpos = ebits;
+
+        // The first iteration, which is hoisted out of the main loop
+        ebits--;
+        boolean isone = true;
+
+        multpos = ebits - wbits;
+        while ((buf & 1) == 0) {
+            buf >>>= 1;
+            multpos++;
+        }
+
+        int[] mult = table[buf >>> 1];
+
+        buf = 0;
+        if (multpos == ebits)
+            isone = false;
+
+        // The main loop
+        while (true) {
+            ebits--;
+            // Advance the window
+            buf <<= 1;
+
+            if (elen != 0) {
+                buf |= ((exp[eIndex] & bitpos) != 0) ? 1 : 0;
+                bitpos >>>= 1;
+                if (bitpos == 0) {
+                    eIndex++;
+                    bitpos = 1 << (32-1);
+                    elen--;
+                }
+            }
+
+            // Examine the window for pending multiplies
+            if ((buf & tblmask) != 0) {
+                multpos = ebits - wbits;
+                while ((buf & 1) == 0) {
+                    buf >>>= 1;
+                    multpos++;
+                }
+                mult = table[buf >>> 1];
+                buf = 0;
+            }
+
+            // Perform multiply
+            if (ebits == multpos) {
+                if (isone) {
+                    b = mult.clone();
+                    isone = false;
+                } else {
+                    t = b;
+                    a = montgomeryMultiply(t, mult, mod, modLen, inv, a);
+                    t = a; a = b; b = t;
+                }
+            }
+
+            // Check if done
+            if (ebits == 0)
+                break;
+
+            // Square the input
+            if (!isone) {
+                t = b;
+                a = montgomerySquare(t, mod, modLen, inv, a);
+                t = a; a = b; b = t;
+            }
+        }
+
+        // Convert result out of Montgomery form and return
+        int[] t2 = new int[2*modLen];
+        System.arraycopy(b, 0, t2, modLen, modLen);
+
+        b = montReduce(t2, mod, modLen, (int)inv);
+
+        t2 = Arrays.copyOf(b, modLen);
+
+        return new BigInteger(1, t2);
+    }
+
+    /**
+     * Montgomery reduce n, modulo mod.  This reduces modulo mod and divides
+     * by 2^(32*mlen). Adapted from Colin Plumb's C library.
+     */
+    private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) {
+        int c=0;
+        int len = mlen;
+        int offset=0;
+
+        do {
+            int nEnd = n[n.length-1-offset];
+            int carry = mulAdd(n, mod, offset, mlen, inv * nEnd);
+            c += addOne(n, offset, mlen, carry);
+            offset++;
+        } while (--len > 0);
+
+        while (c > 0)
+            c += subN(n, mod, mlen);
+
+        while (intArrayCmpToLen(n, mod, mlen) >= 0)
+            subN(n, mod, mlen);
+
+        return n;
+    }
+
+
+    /*
+     * Returns -1, 0 or +1 as big-endian unsigned int array arg1 is less than,
+     * equal to, or greater than arg2 up to length len.
+     */
+    private static int intArrayCmpToLen(int[] arg1, int[] arg2, int len) {
+        for (int i=0; i < len; i++) {
+            long b1 = arg1[i] & LONG_MASK;
+            long b2 = arg2[i] & LONG_MASK;
+            if (b1 < b2)
+                return -1;
+            if (b1 > b2)
+                return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Subtracts two numbers of same length, returning borrow.
+     */
+    private static int subN(int[] a, int[] b, int len) {
+        long sum = 0;
+
+        while (--len >= 0) {
+            sum = (a[len] & LONG_MASK) -
+                 (b[len] & LONG_MASK) + (sum >> 32);
+            a[len] = (int)sum;
+        }
+
+        return (int)(sum >> 32);
+    }
+
+    /**
+     * Multiply an array by one word k and add to result, return the carry
+     */
+    static int mulAdd(int[] out, int[] in, int offset, int len, int k) {
+        implMulAddCheck(out, in, offset, len, k);
+        return implMulAdd(out, in, offset, len, k);
+    }
+
+    /**
+     * Parameters validation.
+     */
+    private static void implMulAddCheck(int[] out, int[] in, int offset, int len, int k) {
+        if (len > in.length) {
+            throw new IllegalArgumentException("input length is out of bound: " + len + " > " + in.length);
+        }
+        if (offset < 0) {
+            throw new IllegalArgumentException("input offset is invalid: " + offset);
+        }
+        if (offset > (out.length - 1)) {
+            throw new IllegalArgumentException("input offset is out of bound: " + offset + " > " + (out.length - 1));
+        }
+        if (len > (out.length - offset)) {
+            throw new IllegalArgumentException("input len is out of bound: " + len + " > " + (out.length - offset));
+        }
+    }
+
+    /**
+     * Java Runtime may use intrinsic for this method.
+     */
+    private static int implMulAdd(int[] out, int[] in, int offset, int len, int k) {
+        long kLong = k & LONG_MASK;
+        long carry = 0;
+
+        offset = out.length-offset - 1;
+        for (int j=len-1; j >= 0; j--) {
+            long product = (in[j] & LONG_MASK) * kLong +
+                           (out[offset] & LONG_MASK) + carry;
+            out[offset--] = (int)product;
+            carry = product >>> 32;
+        }
+        return (int)carry;
+    }
+
+    /**
+     * Add one word to the number a mlen words into a. Return the resulting
+     * carry.
+     */
+    static int addOne(int[] a, int offset, int mlen, int carry) {
+        offset = a.length-1-mlen-offset;
+        long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);
+
+        a[offset] = (int)t;
+        if ((t >>> 32) == 0)
+            return 0;
+        while (--mlen >= 0) {
+            if (--offset < 0) { // Carry out of number
+                return 1;
+            } else {
+                a[offset]++;
+                if (a[offset] != 0)
+                    return 0;
+            }
+        }
+        return 1;
+    }
+
+    /**
+     * Returns a BigInteger whose value is (this ** exponent) mod (2**p)
+     */
+    @NonNull private BigInteger modPow2(@NonNull BigInteger exponent, int p) {
+        /*
+         * Perform exponentiation using repeated squaring trick, chopping off
+         * high order bits as indicated by modulus.
+         */
+        BigInteger result = ONE;
+        BigInteger baseToPow2 = this.mod2(p);
+        int expOffset = 0;
+
+        int limit = exponent.bitLength();
+
+        if (this.testBit(0))
+           limit = (p-1) < limit ? (p-1) : limit;
+
+        while (expOffset < limit) {
+            if (exponent.testBit(expOffset))
+                result = result.multiply(baseToPow2).mod2(p);
+            expOffset++;
+            if (expOffset < limit)
+                baseToPow2 = baseToPow2.square().mod2(p);
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns a BigInteger whose value is this mod(2**p).
+     * Assumes that this {@code BigInteger >= 0} and {@code p > 0}.
+     */
+    @NonNull private BigInteger mod2(int p) {
+        if (bitLength() <= p)
+            return this;
+
+        // Copy remaining ints of mag
+        int numInts = (p + 31) >>> 5;
+        int[] mag = new int[numInts];
+        System.arraycopy(this.mag, (this.mag.length - numInts), mag, 0, numInts);
+
+        // Mask out any excess bits
+        int excessBits = (numInts << 5) - p;
+        mag[0] &= (1L << (32-excessBits)) - 1;
+
+        return (mag[0] == 0 ? new BigInteger(1, mag) : new BigInteger(mag, 1));
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this}<sup>-1</sup> {@code mod m)}.
+     *
+     * @param  m the modulus.
+     * @return {@code this}<sup>-1</sup> {@code mod m}.
+     * @throws ArithmeticException {@code  m} &le; 0, or this BigInteger
+     *         has no multiplicative inverse mod m (that is, this BigInteger
+     *         is not <i>relatively prime</i> to m).
+     */
+    @NonNull public BigInteger modInverse(@NonNull BigInteger m) {
+        if (m.signum != 1)
+            throw new ArithmeticException("BigInteger: modulus not positive");
+
+        if (m.equals(ONE))
+            return ZERO;
+
+        // Calculate (this mod m)
+        BigInteger modVal = this;
+        if (signum < 0 || (this.compareMagnitude(m) >= 0))
+            modVal = this.mod(m);
+
+        if (modVal.equals(ONE))
+            return ONE;
+
+        MutableBigInteger a = new MutableBigInteger(modVal);
+        MutableBigInteger b = new MutableBigInteger(m);
+
+        MutableBigInteger result = a.mutableModInverse(b);
+        return result.toBigInteger(1);
+    }
+
+    // Shift Operations
+
+    /**
+     * Returns a BigInteger whose value is {@code (this << n)}.
+     * The shift distance, {@code n}, may be negative, in which case
+     * this method performs a right shift.
+     * (Computes <tt>floor(this * 2<sup>n</sup>)</tt>.)
+     *
+     * @param  n shift distance, in bits.
+     * @return {@code this << n}
+     * @see #shiftRight
+     */
+    @NonNull public BigInteger shiftLeft(int n) {
+        if (signum == 0)
+            return ZERO;
+        if (n > 0) {
+            return new BigInteger(shiftLeft(mag, n), signum);
+        } else if (n == 0) {
+            return this;
+        } else {
+            // Possible int overflow in (-n) is not a trouble,
+            // because shiftRightImpl considers its argument unsigned
+            return shiftRightImpl(-n);
+        }
+    }
+
+    /**
+     * Returns a magnitude array whose value is {@code (mag << n)}.
+     * The shift distance, {@code n}, is considered unnsigned.
+     * (Computes <tt>this * 2<sup>n</sup></tt>.)
+     *
+     * @param mag magnitude, the most-significant int ({@code mag[0]}) must be non-zero.
+     * @param  n unsigned shift distance, in bits.
+     * @return {@code mag << n}
+     */
+    private static int[] shiftLeft(int[] mag, int n) {
+        int nInts = n >>> 5;
+        int nBits = n & 0x1f;
+        int magLen = mag.length;
+        int newMag[] = null;
+
+        if (nBits == 0) {
+            newMag = new int[magLen + nInts];
+            System.arraycopy(mag, 0, newMag, 0, magLen);
+        } else {
+            int i = 0;
+            int nBits2 = 32 - nBits;
+            int highBits = mag[0] >>> nBits2;
+            if (highBits != 0) {
+                newMag = new int[magLen + nInts + 1];
+                newMag[i++] = highBits;
+            } else {
+                newMag = new int[magLen + nInts];
+            }
+            int j=0;
+            while (j < magLen-1)
+                newMag[i++] = mag[j++] << nBits | mag[j] >>> nBits2;
+            newMag[i] = mag[j] << nBits;
+        }
+        return newMag;
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this >> n)}.  Sign
+     * extension is performed.  The shift distance, {@code n}, may be
+     * negative, in which case this method performs a left shift.
+     * (Computes <tt>floor(this / 2<sup>n</sup>)</tt>.)
+     *
+     * @param  n shift distance, in bits.
+     * @return {@code this >> n}
+     * @see #shiftLeft
+     */
+    @NonNull public BigInteger shiftRight(int n) {
+        if (signum == 0)
+            return ZERO;
+        if (n > 0) {
+            return shiftRightImpl(n);
+        } else if (n == 0) {
+            return this;
+        } else {
+            // Possible int overflow in {@code -n} is not a trouble,
+            // because shiftLeft considers its argument unsigned
+            return new BigInteger(shiftLeft(mag, -n), signum);
+        }
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this >> n)}. The shift
+     * distance, {@code n}, is considered unsigned.
+     * (Computes <tt>floor(this * 2<sup>-n</sup>)</tt>.)
+     *
+     * @param  n unsigned shift distance, in bits.
+     * @return {@code this >> n}
+     */
+    @NonNull private BigInteger shiftRightImpl(int n) {
+        int nInts = n >>> 5;
+        int nBits = n & 0x1f;
+        int magLen = mag.length;
+        int newMag[] = null;
+
+        // Special case: entire contents shifted off the end
+        if (nInts >= magLen)
+            return (signum >= 0 ? ZERO : negConst[1]);
+
+        if (nBits == 0) {
+            int newMagLen = magLen - nInts;
+            newMag = Arrays.copyOf(mag, newMagLen);
+        } else {
+            int i = 0;
+            int highBits = mag[0] >>> nBits;
+            if (highBits != 0) {
+                newMag = new int[magLen - nInts];
+                newMag[i++] = highBits;
+            } else {
+                newMag = new int[magLen - nInts -1];
+            }
+
+            int nBits2 = 32 - nBits;
+            int j=0;
+            while (j < magLen - nInts - 1)
+                newMag[i++] = (mag[j++] << nBits2) | (mag[j] >>> nBits);
+        }
+
+        if (signum < 0) {
+            // Find out whether any one-bits were shifted off the end.
+            boolean onesLost = false;
+            for (int i=magLen-1, j=magLen-nInts; i >= j && !onesLost; i--)
+                onesLost = (mag[i] != 0);
+            if (!onesLost && nBits != 0)
+                onesLost = (mag[magLen - nInts - 1] << (32 - nBits) != 0);
+
+            if (onesLost)
+                newMag = javaIncrement(newMag);
+        }
+
+        return new BigInteger(newMag, signum);
+    }
+
+    int[] javaIncrement(int[] val) {
+        int lastSum = 0;
+        for (int i=val.length-1;  i >= 0 && lastSum == 0; i--)
+            lastSum = (val[i] += 1);
+        if (lastSum == 0) {
+            val = new int[val.length+1];
+            val[0] = 1;
+        }
+        return val;
+    }
+
+    // Bitwise Operations
+
+    /**
+     * Returns a BigInteger whose value is {@code (this & val)}.  (This
+     * method returns a negative BigInteger if and only if this and val are
+     * both negative.)
+     *
+     * @param val value to be AND'ed with this BigInteger.
+     * @return {@code this & val}
+     */
+    @NonNull public BigInteger and(@NonNull BigInteger val) {
+        int[] result = new int[Math.max(intLength(), val.intLength())];
+        for (int i=0; i < result.length; i++)
+            result[i] = (getInt(result.length-i-1)
+                         & val.getInt(result.length-i-1));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this | val)}.  (This method
+     * returns a negative BigInteger if and only if either this or val is
+     * negative.)
+     *
+     * @param val value to be OR'ed with this BigInteger.
+     * @return {@code this | val}
+     */
+    @NonNull public BigInteger or(@NonNull BigInteger val) {
+        int[] result = new int[Math.max(intLength(), val.intLength())];
+        for (int i=0; i < result.length; i++)
+            result[i] = (getInt(result.length-i-1)
+                         | val.getInt(result.length-i-1));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this ^ val)}.  (This method
+     * returns a negative BigInteger if and only if exactly one of this and
+     * val are negative.)
+     *
+     * @param val value to be XOR'ed with this BigInteger.
+     * @return {@code this ^ val}
+     */
+    @NonNull public BigInteger xor(@NonNull BigInteger val) {
+        int[] result = new int[Math.max(intLength(), val.intLength())];
+        for (int i=0; i < result.length; i++)
+            result[i] = (getInt(result.length-i-1)
+                         ^ val.getInt(result.length-i-1));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (~this)}.  (This method
+     * returns a negative value if and only if this BigInteger is
+     * non-negative.)
+     *
+     * @return {@code ~this}
+     */
+    @NonNull public BigInteger not() {
+        int[] result = new int[intLength()];
+        for (int i=0; i < result.length; i++)
+            result[i] = ~getInt(result.length-i-1);
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is {@code (this & ~val)}.  This
+     * method, which is equivalent to {@code and(val.not())}, is provided as
+     * a convenience for masking operations.  (This method returns a negative
+     * BigInteger if and only if {@code this} is negative and {@code val} is
+     * positive.)
+     *
+     * @param val value to be complemented and AND'ed with this BigInteger.
+     * @return {@code this & ~val}
+     */
+    @NonNull public BigInteger andNot(@NonNull BigInteger val) {
+        int[] result = new int[Math.max(intLength(), val.intLength())];
+        for (int i=0; i < result.length; i++)
+            result[i] = (getInt(result.length-i-1)
+                         & ~val.getInt(result.length-i-1));
+
+        return valueOf(result);
+    }
+
+
+    // Single Bit Operations
+
+    /**
+     * Returns {@code true} if and only if the designated bit is set.
+     * (Computes {@code ((this & (1<<n)) != 0)}.)
+     *
+     * @param  n index of bit to test.
+     * @return {@code true} if and only if the designated bit is set.
+     * @throws ArithmeticException {@code n} is negative.
+     */
+    public boolean testBit(int n) {
+        if (n < 0)
+            throw new ArithmeticException("Negative bit address");
+
+        return (getInt(n >>> 5) & (1 << (n & 31))) != 0;
+    }
+
+    /**
+     * Returns a BigInteger whose value is equivalent to this BigInteger
+     * with the designated bit set.  (Computes {@code (this | (1<<n))}.)
+     *
+     * @param  n index of bit to set.
+     * @return {@code this | (1<<n)}
+     * @throws ArithmeticException {@code n} is negative.
+     */
+    @NonNull public BigInteger setBit(int n) {
+        if (n < 0)
+            throw new ArithmeticException("Negative bit address");
+
+        int intNum = n >>> 5;
+        int[] result = new int[Math.max(intLength(), intNum+2)];
+
+        for (int i=0; i < result.length; i++)
+            result[result.length-i-1] = getInt(i);
+
+        result[result.length-intNum-1] |= (1 << (n & 31));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is equivalent to this BigInteger
+     * with the designated bit cleared.
+     * (Computes {@code (this & ~(1<<n))}.)
+     *
+     * @param  n index of bit to clear.
+     * @return {@code this & ~(1<<n)}
+     * @throws ArithmeticException {@code n} is negative.
+     */
+    @NonNull public BigInteger clearBit(int n) {
+        if (n < 0)
+            throw new ArithmeticException("Negative bit address");
+
+        int intNum = n >>> 5;
+        int[] result = new int[Math.max(intLength(), ((n + 1) >>> 5) + 1)];
+
+        for (int i=0; i < result.length; i++)
+            result[result.length-i-1] = getInt(i);
+
+        result[result.length-intNum-1] &= ~(1 << (n & 31));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns a BigInteger whose value is equivalent to this BigInteger
+     * with the designated bit flipped.
+     * (Computes {@code (this ^ (1<<n))}.)
+     *
+     * @param  n index of bit to flip.
+     * @return {@code this ^ (1<<n)}
+     * @throws ArithmeticException {@code n} is negative.
+     */
+    @NonNull public BigInteger flipBit(int n) {
+        if (n < 0)
+            throw new ArithmeticException("Negative bit address");
+
+        int intNum = n >>> 5;
+        int[] result = new int[Math.max(intLength(), intNum+2)];
+
+        for (int i=0; i < result.length; i++)
+            result[result.length-i-1] = getInt(i);
+
+        result[result.length-intNum-1] ^= (1 << (n & 31));
+
+        return valueOf(result);
+    }
+
+    /**
+     * Returns the index of the rightmost (lowest-order) one bit in this
+     * BigInteger (the number of zero bits to the right of the rightmost
+     * one bit).  Returns -1 if this BigInteger contains no one bits.
+     * (Computes {@code (this == 0? -1 : log2(this & -this))}.)
+     *
+     * @return index of the rightmost one bit in this BigInteger.
+     */
+    public int getLowestSetBit() {
+        @SuppressWarnings("deprecation") int lsb = lowestSetBit - 2;
+        if (lsb == -2) {  // lowestSetBit not initialized yet
+            lsb = 0;
+            if (signum == 0) {
+                lsb -= 1;
+            } else {
+                // Search for lowest order nonzero int
+                int i,b;
+                for (i=0; (b = getInt(i)) == 0; i++)
+                    ;
+                lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
+            }
+            lowestSetBit = lsb + 2;
+        }
+        return lsb;
+    }
+
+
+    // Miscellaneous Bit Operations
+
+    /**
+     * Returns the number of bits in the minimal two's-complement
+     * representation of this BigInteger, <i>excluding</i> a sign bit.
+     * For positive BigIntegers, this is equivalent to the number of bits in
+     * the ordinary binary representation.  (Computes
+     * {@code (ceil(log2(this < 0 ? -this : this+1)))}.)
+     *
+     * @return number of bits in the minimal two's-complement
+     *         representation of this BigInteger, <i>excluding</i> a sign bit.
+     */
+    public int bitLength() {
+        @SuppressWarnings("deprecation") int n = bitLength - 1;
+        if (n == -1) { // bitLength not initialized yet
+            int[] m = mag;
+            int len = m.length;
+            if (len == 0) {
+                n = 0; // offset by one to initialize
+            }  else {
+                // Calculate the bit length of the magnitude
+                int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]);
+                 if (signum < 0) {
+                     // Check if magnitude is a power of two
+                     boolean pow2 = (Integer.bitCount(mag[0]) == 1);
+                     for (int i=1; i< len && pow2; i++)
+                         pow2 = (mag[i] == 0);
+
+                     n = (pow2 ? magBitLength - 1 : magBitLength);
+                 } else {
+                     n = magBitLength;
+                 }
+            }
+            bitLength = n + 1;
+        }
+        return n;
+    }
+
+    /**
+     * Returns the number of bits in the two's complement representation
+     * of this BigInteger that differ from its sign bit.  This method is
+     * useful when implementing bit-vector style sets atop BigIntegers.
+     *
+     * @return number of bits in the two's complement representation
+     *         of this BigInteger that differ from its sign bit.
+     */
+    public int bitCount() {
+        @SuppressWarnings("deprecation") int bc = bitCount - 1;
+        if (bc == -1) {  // bitCount not initialized yet
+            bc = 0;      // offset by one to initialize
+            // Count the bits in the magnitude
+            for (int i=0; i < mag.length; i++)
+                bc += Integer.bitCount(mag[i]);
+            if (signum < 0) {
+                // Count the trailing zeros in the magnitude
+                int magTrailingZeroCount = 0, j;
+                for (j=mag.length-1; mag[j] == 0; j--)
+                    magTrailingZeroCount += 32;
+                magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
+                bc += magTrailingZeroCount - 1;
+            }
+            bitCount = bc + 1;
+        }
+        return bc;
+    }
+
+    // Primality Testing
+
+    /**
+     * Returns {@code true} if this BigInteger is probably prime,
+     * {@code false} if it's definitely composite.  If
+     * {@code certainty} is &le; 0, {@code true} is
+     * returned.
+     *
+     * @param  certainty a measure of the uncertainty that the caller is
+     *         willing to tolerate: if the call returns {@code true}
+     *         the probability that this BigInteger is prime exceeds
+     *         (1 - 1/2<sup>{@code certainty}</sup>).  The execution time of
+     *         this method is proportional to the value of this parameter.
+     * @return {@code true} if this BigInteger is probably prime,
+     *         {@code false} if it's definitely composite.
+     */
+    public boolean isProbablePrime(int certainty) {
+        if (certainty <= 0)
+            return true;
+        BigInteger w = this.abs();
+        if (w.equals(TWO))
+            return true;
+        if (!w.testBit(0) || w.equals(ONE))
+            return false;
+
+        return w.primeToCertainty(certainty, null);
+    }
+
+    // Comparison Operations
+
+    /**
+     * Compares this BigInteger with the specified BigInteger.  This
+     * method is provided in preference to individual methods for each
+     * of the six boolean comparison operators ({@literal <}, ==,
+     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The suggested
+     * idiom for performing these comparisons is: {@code
+     * (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
+     * &lt;<i>op</i>&gt; is one of the six comparison operators.
+     *
+     * @param  val BigInteger to which this BigInteger is to be compared.
+     * @return -1, 0 or 1 as this BigInteger is numerically less than, equal
+     *         to, or greater than {@code val}.
+     */
+    public int compareTo(@NonNull BigInteger val) {
+        if (signum == val.signum) {
+            switch (signum) {
+            case 1:
+                return compareMagnitude(val);
+            case -1:
+                return val.compareMagnitude(this);
+            default:
+                return 0;
+            }
+        }
+        return signum > val.signum ? 1 : -1;
+    }
+
+    /**
+     * Compares the magnitude array of this BigInteger with the specified
+     * BigInteger's. This is the version of compareTo ignoring sign.
+     *
+     * @param val BigInteger whose magnitude array to be compared.
+     * @return -1, 0 or 1 as this magnitude array is less than, equal to or
+     *         greater than the magnitude aray for the specified BigInteger's.
+     */
+    final int compareMagnitude(@NonNull BigInteger val) {
+        int[] m1 = mag;
+        int len1 = m1.length;
+        int[] m2 = val.mag;
+        int len2 = m2.length;
+        if (len1 < len2)
+            return -1;
+        if (len1 > len2)
+            return 1;
+        for (int i = 0; i < len1; i++) {
+            int a = m1[i];
+            int b = m2[i];
+            if (a != b)
+                return ((a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Version of compareMagnitude that compares magnitude with long value.
+     * val can't be Long.MIN_VALUE.
+     */
+    final int compareMagnitude(long val) {
+        assert val != Long.MIN_VALUE;
+        int[] m1 = mag;
+        int len = m1.length;
+        if (len > 2) {
+            return 1;
+        }
+        if (val < 0) {
+            val = -val;
+        }
+        int highWord = (int)(val >>> 32);
+        if (highWord == 0) {
+            if (len < 1)
+                return -1;
+            if (len > 1)
+                return 1;
+            int a = m1[0];
+            int b = (int)val;
+            if (a != b) {
+                return ((a & LONG_MASK) < (b & LONG_MASK))? -1 : 1;
+            }
+            return 0;
+        } else {
+            if (len < 2)
+                return -1;
+            int a = m1[0];
+            int b = highWord;
+            if (a != b) {
+                return ((a & LONG_MASK) < (b & LONG_MASK))? -1 : 1;
+            }
+            a = m1[1];
+            b = (int)val;
+            if (a != b) {
+                return ((a & LONG_MASK) < (b & LONG_MASK))? -1 : 1;
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * Compares this BigInteger with the specified Object for equality.
+     *
+     * @param  x Object to which this BigInteger is to be compared.
+     * @return {@code true} if and only if the specified Object is a
+     *         BigInteger whose value is numerically equal to this BigInteger.
+     */
+    public boolean equals(@NonNull Object x) {
+        // This test is just an optimization, which may or may not help
+        if (x == this)
+            return true;
+
+        if (!(x instanceof BigInteger))
+            return false;
+
+        BigInteger xInt = (BigInteger) x;
+        if (xInt.signum != signum)
+            return false;
+
+        int[] m = mag;
+        int len = m.length;
+        int[] xm = xInt.mag;
+        if (len != xm.length)
+            return false;
+
+        for (int i = 0; i < len; i++)
+            if (xm[i] != m[i])
+                return false;
+
+        return true;
+    }
+
+    /**
+     * Returns the minimum of this BigInteger and {@code val}.
+     *
+     * @param  val value with which the minimum is to be computed.
+     * @return the BigInteger whose value is the lesser of this BigInteger and
+     *         {@code val}.  If they are equal, either may be returned.
+     */
+    @NonNull public BigInteger min(@NonNull BigInteger val) {
+        return (compareTo(val) < 0 ? this : val);
+    }
+
+    /**
+     * Returns the maximum of this BigInteger and {@code val}.
+     *
+     * @param  val value with which the maximum is to be computed.
+     * @return the BigInteger whose value is the greater of this and
+     *         {@code val}.  If they are equal, either may be returned.
+     */
+    @NonNull public BigInteger max(@NonNull BigInteger val) {
+        return (compareTo(val) > 0 ? this : val);
+    }
+
+
+    // Hash Function
+
+    /**
+     * Returns the hash code for this BigInteger.
+     *
+     * @return hash code for this BigInteger.
+     */
+    public int hashCode() {
+        int hashCode = 0;
+
+        for (int i=0; i < mag.length; i++)
+            hashCode = (int)(31*hashCode + (mag[i] & LONG_MASK));
+
+        return hashCode * signum;
+    }
+
+    /**
+     * Returns the String representation of this BigInteger in the
+     * given radix.  If the radix is outside the range from {@link
+     * Character#MIN_RADIX} to {@link Character#MAX_RADIX} inclusive,
+     * it will default to 10 (as is the case for
+     * {@code Integer.toString}).  The digit-to-character mapping
+     * provided by {@code Character.forDigit} is used, and a minus
+     * sign is prepended if appropriate.  (This representation is
+     * compatible with the {@link #BigInteger(String, int) (String,
+     * int)} constructor.)
+     *
+     * @param  radix  radix of the String representation.
+     * @return String representation of this BigInteger in the given radix.
+     * @see    Integer#toString
+     * @see    Character#forDigit
+     * @see    #BigInteger(java.lang.String, int)
+     */
+    @NonNull public String toString(int radix) {
+        if (signum == 0)
+            return "0";
+        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
+            radix = 10;
+
+        // If it's small enough, use smallToString.
+        if (mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD)
+           return smallToString(radix);
+
+        // Otherwise use recursive toString, which requires positive arguments.
+        // The results will be concatenated into this StringBuilder
+        StringBuilder sb = new StringBuilder();
+        if (signum < 0) {
+            toString(this.negate(), sb, radix, 0);
+            sb.insert(0, '-');
+        }
+        else
+            toString(this, sb, radix, 0);
+
+        return sb.toString();
+    }
+
+    /** This method is used to perform toString when arguments are small. */
+    @NonNull private String smallToString(int radix) {
+        if (signum == 0) {
+            return "0";
+        }
+
+        // Compute upper bound on number of digit groups and allocate space
+        int maxNumDigitGroups = (4*mag.length + 6)/7;
+        String digitGroup[] = new String[maxNumDigitGroups];
+
+        // Translate number to string, a digit group at a time
+        BigInteger tmp = this.abs();
+        int numGroups = 0;
+        while (tmp.signum != 0) {
+            BigInteger d = longRadix[radix];
+
+            MutableBigInteger q = new MutableBigInteger(),
+                              a = new MutableBigInteger(tmp.mag),
+                              b = new MutableBigInteger(d.mag);
+            MutableBigInteger r = a.divide(b, q);
+            BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
+            BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
+
+            digitGroup[numGroups++] = Long.toString(r2.longValue(), radix);
+            tmp = q2;
+        }
+
+        // Put sign (if any) and first digit group into result buffer
+        StringBuilder buf = new StringBuilder(numGroups*digitsPerLong[radix]+1);
+        if (signum < 0) {
+            buf.append('-');
+        }
+        buf.append(digitGroup[numGroups-1]);
+
+        // Append remaining digit groups padded with leading zeros
+        for (int i=numGroups-2; i >= 0; i--) {
+            // Prepend (any) leading zeros for this digit group
+            int numLeadingZeros = digitsPerLong[radix]-digitGroup[i].length();
+            if (numLeadingZeros != 0) {
+                buf.append(zeros[numLeadingZeros]);
+            }
+            buf.append(digitGroup[i]);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Converts the specified BigInteger to a string and appends to
+     * {@code sb}.  This implements the recursive Schoenhage algorithm
+     * for base conversions.
+     * <p/>
+     * See Knuth, Donald,  _The Art of Computer Programming_, Vol. 2,
+     * Answers to Exercises (4.4) Question 14.
+     *
+     * @param u      The number to convert to a string.
+     * @param sb     The StringBuilder that will be appended to in place.
+     * @param radix  The base to convert to.
+     * @param digits The minimum number of digits to pad to.
+     */
+    private static void toString(@NonNull BigInteger u, StringBuilder sb, int radix,
+                                 int digits) {
+        /* If we're smaller than a certain threshold, use the smallToString
+           method, padding with leading zeroes when necessary. */
+        if (u.mag.length <= SCHOENHAGE_BASE_CONVERSION_THRESHOLD) {
+            String s = u.smallToString(radix);
+
+            // Pad with internal zeros if necessary.
+            // Don't pad if we're at the beginning of the string.
+            if ((s.length() < digits) && (sb.length() > 0)) {
+                for (int i=s.length(); i < digits; i++) { // May be a faster way to
+                    sb.append('0');                    // do this?
+                }
+            }
+
+            sb.append(s);
+            return;
+        }
+
+        int b, n;
+        b = u.bitLength();
+
+        // Calculate a value for n in the equation radix^(2^n) = u
+        // and subtract 1 from that value.  This is used to find the
+        // cache index that contains the best value to divide u.
+        n = (int) Math.round(Math.log(b * LOG_TWO / logCache[radix]) / LOG_TWO - 1.0);
+        BigInteger v = getRadixConversionCache(radix, n);
+        BigInteger[] results;
+        results = u.divideAndRemainder(v);
+
+        int expectedDigits = 1 << n;
+
+        // Now recursively build the two halves of each number.
+        toString(results[0], sb, radix, digits-expectedDigits);
+        toString(results[1], sb, radix, expectedDigits);
+    }
+
+    /**
+     * Returns the value radix^(2^exponent) from the cache.
+     * If this value doesn't already exist in the cache, it is added.
+     * <p/>
+     * This could be changed to a more complicated caching method using
+     * {@code Future}.
+     */
+    @NonNull private static BigInteger getRadixConversionCache(int radix, int exponent) {
+        BigInteger[] cacheLine = powerCache[radix]; // volatile read
+        if (exponent < cacheLine.length) {
+            return cacheLine[exponent];
+        }
+
+        int oldLength = cacheLine.length;
+        cacheLine = Arrays.copyOf(cacheLine, exponent + 1);
+        for (int i = oldLength; i <= exponent; i++) {
+            cacheLine[i] = cacheLine[i - 1].pow(2);
+        }
+
+        BigInteger[][] pc = powerCache; // volatile read again
+        if (exponent >= pc[radix].length) {
+            pc = pc.clone();
+            pc[radix] = cacheLine;
+            powerCache = pc; // volatile write, publish
+        }
+        return cacheLine[exponent];
+    }
+
+    /* zero[i] is a string of i consecutive zeros. */
+    private static String zeros[] = new String[64];
+    static {
+        zeros[63] =
+            "000000000000000000000000000000000000000000000000000000000000000";
+        for (int i=0; i < 63; i++)
+            zeros[i] = zeros[63].substring(0, i);
+    }
+
+    /**
+     * Returns the decimal String representation of this BigInteger.
+     * The digit-to-character mapping provided by
+     * {@code Character.forDigit} is used, and a minus sign is
+     * prepended if appropriate.  (This representation is compatible
+     * with the {@link #BigInteger(String) (String)} constructor, and
+     * allows for String concatenation with Java's + operator.)
+     *
+     * @return decimal String representation of this BigInteger.
+     * @see    Character#forDigit
+     * @see    #BigInteger(java.lang.String)
+     */
+    @NonNull public String toString() {
+        return toString(10);
+    }
+
+    /**
+     * Returns a byte array containing the two's-complement
+     * representation of this BigInteger.  The byte array will be in
+     * <i>big-endian</i> byte-order: the most significant byte is in
+     * the zeroth element.  The array will contain the minimum number
+     * of bytes required to represent this BigInteger, including at
+     * least one sign bit, which is {@code (ceil((this.bitLength() +
+     * 1)/8))}.  (This representation is compatible with the
+     * {@link #BigInteger(byte[]) (byte[])} constructor.)
+     *
+     * @return a byte array containing the two's-complement representation of
+     *         this BigInteger.
+     * @see    #BigInteger(byte[])
+     */
+    public byte[] toByteArray() {
+        int byteLen = bitLength()/8 + 1;
+        byte[] byteArray = new byte[byteLen];
+
+        for (int i=byteLen-1, bytesCopied=4, nextInt=0, intIndex=0; i >= 0; i--) {
+            if (bytesCopied == 4) {
+                nextInt = getInt(intIndex++);
+                bytesCopied = 1;
+            } else {
+                nextInt >>>= 8;
+                bytesCopied++;
+            }
+            byteArray[i] = (byte)nextInt;
+        }
+        return byteArray;
+    }
+
+    /**
+     * Converts this BigInteger to an {@code int}.  This
+     * conversion is analogous to a
+     * <i>narrowing primitive conversion</i> from {@code long} to
+     * {@code int} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this BigInteger is too big to fit in an
+     * {@code int}, only the low-order 32 bits are returned.
+     * Note that this conversion can lose information about the
+     * overall magnitude of the BigInteger value as well as return a
+     * result with the opposite sign.
+     *
+     * @return this BigInteger converted to an {@code int}.
+     * @see #intValueExact()
+     */
+    public int intValue() {
+        int result = 0;
+        result = getInt(0);
+        return result;
+    }
+
+    /**
+     * Converts this BigInteger to a {@code long}.  This
+     * conversion is analogous to a
+     * <i>narrowing primitive conversion</i> from {@code long} to
+     * {@code int} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this BigInteger is too big to fit in a
+     * {@code long}, only the low-order 64 bits are returned.
+     * Note that this conversion can lose information about the
+     * overall magnitude of the BigInteger value as well as return a
+     * result with the opposite sign.
+     *
+     * @return this BigInteger converted to a {@code long}.
+     * @see #longValueExact()
+     */
+    public long longValue() {
+        long result = 0;
+
+        for (int i=1; i >= 0; i--)
+            result = (result << 32) + (getInt(i) & LONG_MASK);
+        return result;
+    }
+
+    /**
+     * Converts this BigInteger to a {@code float}.  This
+     * conversion is similar to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code float} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this BigInteger has too great a magnitude
+     * to represent as a {@code float}, it will be converted to
+     * {@link Float#NEGATIVE_INFINITY} or {@link
+     * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
+     * the return value is finite, this conversion can lose
+     * information about the precision of the BigInteger value.
+     *
+     * @return this BigInteger converted to a {@code float}.
+     */
+    public float floatValue() {
+        if (signum == 0) {
+            return 0.0f;
+        }
+
+        int exponent = ((mag.length - 1) << 5) + bitLengthForInt(mag[0]) - 1;
+
+        // exponent == floor(log2(abs(this)))
+        if (exponent < Long.SIZE - 1) {
+            return longValue();
+        } else if (exponent > Float.MAX_EXPONENT) {
+            return signum > 0 ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
+        }
+
+        /*
+         * We need the top SIGNIFICAND_WIDTH bits, including the "implicit"
+         * one bit. To make rounding easier, we pick out the top
+         * SIGNIFICAND_WIDTH + 1 bits, so we have one to help us round up or
+         * down. twiceSignifFloor will contain the top SIGNIFICAND_WIDTH + 1
+         * bits, and signifFloor the top SIGNIFICAND_WIDTH.
+         *
+         * It helps to consider the real number signif = abs(this) *
+         * 2^(SIGNIFICAND_WIDTH - 1 - exponent).
+         */
+        int shift = exponent - FloatConsts.SIGNIFICAND_WIDTH;
+
+        int twiceSignifFloor;
+        // twiceSignifFloor will be == abs().shiftRight(shift).intValue()
+        // We do the shift into an int directly to improve performance.
+
+        int nBits = shift & 0x1f;
+        int nBits2 = 32 - nBits;
+
+        if (nBits == 0) {
+            twiceSignifFloor = mag[0];
+        } else {
+            twiceSignifFloor = mag[0] >>> nBits;
+            if (twiceSignifFloor == 0) {
+                twiceSignifFloor = (mag[0] << nBits2) | (mag[1] >>> nBits);
+            }
+        }
+
+        int signifFloor = twiceSignifFloor >> 1;
+        signifFloor &= FloatConsts.SIGNIF_BIT_MASK; // remove the implied bit
+
+        /*
+         * We round up if either the fractional part of signif is strictly
+         * greater than 0.5 (which is true if the 0.5 bit is set and any lower
+         * bit is set), or if the fractional part of signif is >= 0.5 and
+         * signifFloor is odd (which is true if both the 0.5 bit and the 1 bit
+         * are set). This is equivalent to the desired HALF_EVEN rounding.
+         */
+        boolean increment = (twiceSignifFloor & 1) != 0
+                && ((signifFloor & 1) != 0 || abs().getLowestSetBit() < shift);
+        int signifRounded = increment ? signifFloor + 1 : signifFloor;
+        int bits = ((exponent + FloatConsts.EXP_BIAS))
+                << (FloatConsts.SIGNIFICAND_WIDTH - 1);
+        bits += signifRounded;
+        /*
+         * If signifRounded == 2^24, we'd need to set all of the significand
+         * bits to zero and add 1 to the exponent. This is exactly the behavior
+         * we get from just adding signifRounded to bits directly. If the
+         * exponent is Float.MAX_EXPONENT, we round up (correctly) to
+         * Float.POSITIVE_INFINITY.
+         */
+        bits |= signum & FloatConsts.SIGN_BIT_MASK;
+        return Float.intBitsToFloat(bits);
+    }
+
+    /**
+     * Converts this BigInteger to a {@code double}.  This
+     * conversion is similar to the
+     * <i>narrowing primitive conversion</i> from {@code double} to
+     * {@code float} as defined in section 5.1.3 of
+     * <cite>The Java&trade; Language Specification</cite>:
+     * if this BigInteger has too great a magnitude
+     * to represent as a {@code double}, it will be converted to
+     * {@link Double#NEGATIVE_INFINITY} or {@link
+     * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
+     * the return value is finite, this conversion can lose
+     * information about the precision of the BigInteger value.
+     *
+     * @return this BigInteger converted to a {@code double}.
+     */
+    public double doubleValue() {
+        if (signum == 0) {
+            return 0.0;
+        }
+
+        int exponent = ((mag.length - 1) << 5) + bitLengthForInt(mag[0]) - 1;
+
+        // exponent == floor(log2(abs(this))Double)
+        if (exponent < Long.SIZE - 1) {
+            return longValue();
+        } else if (exponent > Double.MAX_EXPONENT) {
+            return signum > 0 ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
+        }
+
+        /*
+         * We need the top SIGNIFICAND_WIDTH bits, including the "implicit"
+         * one bit. To make rounding easier, we pick out the top
+         * SIGNIFICAND_WIDTH + 1 bits, so we have one to help us round up or
+         * down. twiceSignifFloor will contain the top SIGNIFICAND_WIDTH + 1
+         * bits, and signifFloor the top SIGNIFICAND_WIDTH.
+         *
+         * It helps to consider the real number signif = abs(this) *
+         * 2^(SIGNIFICAND_WIDTH - 1 - exponent).
+         */
+        int shift = exponent - DoubleConsts.SIGNIFICAND_WIDTH;
+
+        long twiceSignifFloor;
+        // twiceSignifFloor will be == abs().shiftRight(shift).longValue()
+        // We do the shift into a long directly to improve performance.
+
+        int nBits = shift & 0x1f;
+        int nBits2 = 32 - nBits;
+
+        int highBits;
+        int lowBits;
+        if (nBits == 0) {
+            highBits = mag[0];
+            lowBits = mag[1];
+        } else {
+            highBits = mag[0] >>> nBits;
+            lowBits = (mag[0] << nBits2) | (mag[1] >>> nBits);
+            if (highBits == 0) {
+                highBits = lowBits;
+                lowBits = (mag[1] << nBits2) | (mag[2] >>> nBits);
+            }
+        }
+
+        twiceSignifFloor = ((highBits & LONG_MASK) << 32)
+                | (lowBits & LONG_MASK);
+
+        long signifFloor = twiceSignifFloor >> 1;
+        signifFloor &= DoubleConsts.SIGNIF_BIT_MASK; // remove the implied bit
+
+        /*
+         * We round up if either the fractional part of signif is strictly
+         * greater than 0.5 (which is true if the 0.5 bit is set and any lower
+         * bit is set), or if the fractional part of signif is >= 0.5 and
+         * signifFloor is odd (which is true if both the 0.5 bit and the 1 bit
+         * are set). This is equivalent to the desired HALF_EVEN rounding.
+         */
+        boolean increment = (twiceSignifFloor & 1) != 0
+                && ((signifFloor & 1) != 0 || abs().getLowestSetBit() < shift);
+        long signifRounded = increment ? signifFloor + 1 : signifFloor;
+        long bits = (long) ((exponent + DoubleConsts.EXP_BIAS))
+                << (DoubleConsts.SIGNIFICAND_WIDTH - 1);
+        bits += signifRounded;
+        /*
+         * If signifRounded == 2^53, we'd need to set all of the significand
+         * bits to zero and add 1 to the exponent. This is exactly the behavior
+         * we get from just adding signifRounded to bits directly. If the
+         * exponent is Double.MAX_EXPONENT, we round up (correctly) to
+         * Double.POSITIVE_INFINITY.
+         */
+        bits |= signum & DoubleConsts.SIGN_BIT_MASK;
+        return Double.longBitsToDouble(bits);
+    }
+
+    /**
+     * Returns a copy of the input array stripped of any leading zero bytes.
+     */
+    private static int[] stripLeadingZeroInts(int val[]) {
+        int vlen = val.length;
+        int keep;
+
+        // Find first nonzero byte
+        for (keep = 0; keep < vlen && val[keep] == 0; keep++)
+            ;
+        return java.util.Arrays.copyOfRange(val, keep, vlen);
+    }
+
+    /**
+     * Returns the input array stripped of any leading zero bytes.
+     * Since the source is trusted the copying may be skipped.
+     */
+    private static int[] trustedStripLeadingZeroInts(int val[]) {
+        int vlen = val.length;
+        int keep;
+
+        // Find first nonzero byte
+        for (keep = 0; keep < vlen && val[keep] == 0; keep++)
+            ;
+        return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen);
+    }
+
+    /**
+     * Returns a copy of the input array stripped of any leading zero bytes.
+     */
+    private static int[] stripLeadingZeroBytes(byte a[]) {
+        int byteLength = a.length;
+        int keep;
+
+        // Find first nonzero byte
+        for (keep = 0; keep < byteLength && a[keep] == 0; keep++)
+            ;
+
+        // Allocate new array and copy relevant part of input array
+        int intLength = ((byteLength - keep) + 3) >>> 2;
+        int[] result = new int[intLength];
+        int b = byteLength - 1;
+        for (int i = intLength-1; i >= 0; i--) {
+            result[i] = a[b--] & 0xff;
+            int bytesRemaining = b - keep + 1;
+            int bytesToTransfer = Math.min(3, bytesRemaining);
+            for (int j=8; j <= (bytesToTransfer << 3); j += 8)
+                result[i] |= ((a[b--] & 0xff) << j);
+        }
+        return result;
+    }
+
+    /**
+     * Takes an array a representing a negative 2's-complement number and
+     * returns the minimal (no leading zero bytes) unsigned whose value is -a.
+     */
+    private static int[] makePositive(byte a[]) {
+        int keep, k;
+        int byteLength = a.length;
+
+        // Find first non-sign (0xff) byte of input
+        for (keep=0; keep < byteLength && a[keep] == -1; keep++)
+            ;
+
+
+        /* Allocate output array.  If all non-sign bytes are 0x00, we must
+         * allocate space for one extra output byte. */
+        for (k=keep; k < byteLength && a[k] == 0; k++)
+            ;
+
+        int extraByte = (k == byteLength) ? 1 : 0;
+        int intLength = ((byteLength - keep + extraByte) + 3) >>> 2;
+        int result[] = new int[intLength];
+
+        /* Copy one's complement of input into output, leaving extra
+         * byte (if it exists) == 0x00 */
+        int b = byteLength - 1;
+        for (int i = intLength-1; i >= 0; i--) {
+            result[i] = a[b--] & 0xff;
+            int numBytesToTransfer = Math.min(3, b-keep+1);
+            if (numBytesToTransfer < 0)
+                numBytesToTransfer = 0;
+            for (int j=8; j <= 8*numBytesToTransfer; j += 8)
+                result[i] |= ((a[b--] & 0xff) << j);
+
+            // Mask indicates which bits must be complemented
+            int mask = -1 >>> (8*(3-numBytesToTransfer));
+            result[i] = ~result[i] & mask;
+        }
+
+        // Add one to one's complement to generate two's complement
+        for (int i=result.length-1; i >= 0; i--) {
+            result[i] = (int)((result[i] & LONG_MASK) + 1);
+            if (result[i] != 0)
+                break;
+        }
+
+        return result;
+    }
+
+    /**
+     * Takes an array a representing a negative 2's-complement number and
+     * returns the minimal (no leading zero ints) unsigned whose value is -a.
+     */
+    private static int[] makePositive(int a[]) {
+        int keep, j;
+
+        // Find first non-sign (0xffffffff) int of input
+        for (keep=0; keep < a.length && a[keep] == -1; keep++)
+            ;
+
+        /* Allocate output array.  If all non-sign ints are 0x00, we must
+         * allocate space for one extra output int. */
+        for (j=keep; j < a.length && a[j] == 0; j++)
+            ;
+        int extraInt = (j == a.length ? 1 : 0);
+        int result[] = new int[a.length - keep + extraInt];
+
+        /* Copy one's complement of input into output, leaving extra
+         * int (if it exists) == 0x00 */
+        for (int i = keep; i < a.length; i++)
+            result[i - keep + extraInt] = ~a[i];
+
+        // Add one to one's complement to generate two's complement
+        for (int i=result.length-1; ++result[i] == 0; i--)
+            ;
+
+        return result;
+    }
+
+    /*
+     * The following two arrays are used for fast String conversions.  Both
+     * are indexed by radix.  The first is the number of digits of the given
+     * radix that can fit in a Java long without "going negative", i.e., the
+     * highest integer n such that radix**n < 2**63.  The second is the
+     * "long radix" that tears each number into "long digits", each of which
+     * consists of the number of digits in the corresponding element in
+     * digitsPerLong (longRadix[i] = i**digitPerLong[i]).  Both arrays have
+     * nonsense values in their 0 and 1 elements, as radixes 0 and 1 are not
+     * used.
+     */
+    private static int digitsPerLong[] = {0, 0,
+        62, 39, 31, 27, 24, 22, 20, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14,
+        14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12};
+
+    private static BigInteger longRadix[] = {null, null,
+        valueOf(0x4000000000000000L), valueOf(0x383d9170b85ff80bL),
+        valueOf(0x4000000000000000L), valueOf(0x6765c793fa10079dL),
+        valueOf(0x41c21cb8e1000000L), valueOf(0x3642798750226111L),
+        valueOf(0x1000000000000000L), valueOf(0x12bf307ae81ffd59L),
+        valueOf( 0xde0b6b3a7640000L), valueOf(0x4d28cb56c33fa539L),
+        valueOf(0x1eca170c00000000L), valueOf(0x780c7372621bd74dL),
+        valueOf(0x1e39a5057d810000L), valueOf(0x5b27ac993df97701L),
+        valueOf(0x1000000000000000L), valueOf(0x27b95e997e21d9f1L),
+        valueOf(0x5da0e1e53c5c8000L), valueOf( 0xb16a458ef403f19L),
+        valueOf(0x16bcc41e90000000L), valueOf(0x2d04b7fdd9c0ef49L),
+        valueOf(0x5658597bcaa24000L), valueOf( 0x6feb266931a75b7L),
+        valueOf( 0xc29e98000000000L), valueOf(0x14adf4b7320334b9L),
+        valueOf(0x226ed36478bfa000L), valueOf(0x383d9170b85ff80bL),
+        valueOf(0x5a3c23e39c000000L), valueOf( 0x4e900abb53e6b71L),
+        valueOf( 0x7600ec618141000L), valueOf( 0xaee5720ee830681L),
+        valueOf(0x1000000000000000L), valueOf(0x172588ad4f5f0981L),
+        valueOf(0x211e44f7d02c1000L), valueOf(0x2ee56725f06e5c71L),
+        valueOf(0x41c21cb8e1000000L)};
+
+    /*
+     * These two arrays are the integer analogue of above.
+     */
+    private static int digitsPerInt[] = {0, 0, 30, 19, 15, 13, 11,
+        11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
+        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
+
+    private static int intRadix[] = {0, 0,
+        0x40000000, 0x4546b3db, 0x40000000, 0x48c27395, 0x159fd800,
+        0x75db9c97, 0x40000000, 0x17179149, 0x3b9aca00, 0xcc6db61,
+        0x19a10000, 0x309f1021, 0x57f6c100, 0xa2f1b6f,  0x10000000,
+        0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d,
+        0x6c20a40,  0x8d2d931,  0xb640000,  0xe8d4a51,  0x1269ae40,
+        0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
+        0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x39aa400
+    };
+
+    /**
+     * These routines provide access to the two's complement representation
+     * of BigIntegers.
+     */
+
+    /**
+     * Returns the length of the two's complement representation in ints,
+     * including space for at least one sign bit.
+     */
+    private int intLength() {
+        return (bitLength() >>> 5) + 1;
+    }
+
+    /* Returns sign bit */
+    private int signBit() {
+        return signum < 0 ? 1 : 0;
+    }
+
+    /* Returns an int of sign bits */
+    private int signInt() {
+        return signum < 0 ? -1 : 0;
+    }
+
+    /**
+     * Returns the specified int of the little-endian two's complement
+     * representation (int 0 is the least significant).  The int number can
+     * be arbitrarily high (values are logically preceded by infinitely many
+     * sign ints).
+     */
+    private int getInt(int n) {
+        if (n < 0)
+            return 0;
+        if (n >= mag.length)
+            return signInt();
+
+        int magInt = mag[mag.length-n-1];
+
+        return (signum >= 0 ? magInt :
+                (n <= firstNonzeroIntNum() ? -magInt : ~magInt));
+    }
+
+    /**
+     * Returns the index of the int that contains the first nonzero int in the
+     * little-endian binary representation of the magnitude (int 0 is the
+     * least significant). If the magnitude is zero, return value is undefined.
+     */
+    private int firstNonzeroIntNum() {
+        int fn = firstNonzeroIntNum - 2;
+        if (fn == -2) { // firstNonzeroIntNum not initialized yet
+            fn = 0;
+
+            // Search for the first nonzero int
+            int i;
+            int mlen = mag.length;
+            for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
+                ;
+            fn = mlen - i - 1;
+            firstNonzeroIntNum = fn + 2; // offset by two to initialize
+        }
+        return fn;
+    }
+
+    /** use serialVersionUID from JDK 1.1. for interoperability */
+    private static final long serialVersionUID = -8287574255936472291L;
+
+    /**
+     * Serializable fields for BigInteger.
+     *
+     * @serialField signum  int
+     *              signum of this BigInteger.
+     * @serialField magnitude int[]
+     *              magnitude array of this BigInteger.
+     * @serialField bitCount  int
+     *              number of bits in this BigInteger
+     * @serialField bitLength int
+     *              the number of bits in the minimal two's-complement
+     *              representation of this BigInteger
+     * @serialField lowestSetBit int
+     *              lowest set bit in the twos complement representation
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("signum", Integer.TYPE),
+        new ObjectStreamField("magnitude", byte[].class),
+        new ObjectStreamField("bitCount", Integer.TYPE),
+        new ObjectStreamField("bitLength", Integer.TYPE),
+        new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
+        new ObjectStreamField("lowestSetBit", Integer.TYPE)
+        };
+
+    /**
+     * Reconstitute the {@code BigInteger} instance from a stream (that is,
+     * deserialize it). The magnitude is read in as an array of bytes
+     * for historical reasons, but it is converted to an array of ints
+     * and the byte array is discarded.
+     * Note:
+     * The current convention is to initialize the cache fields, bitCount,
+     * bitLength and lowestSetBit, to 0 rather than some other marker value.
+     * Therefore, no explicit action to set these fields needs to be taken in
+     * readObject because those fields already have a 0 value be default since
+     * defaultReadObject is not being used.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        /*
+         * In order to maintain compatibility with previous serialized forms,
+         * the magnitude of a BigInteger is serialized as an array of bytes.
+         * The magnitude field is used as a temporary store for the byte array
+         * that is deserialized. The cached computation fields should be
+         * transient but are serialized for compatibility reasons.
+         */
+
+        // prepare to read the alternate persistent fields
+        ObjectInputStream.GetField fields = s.readFields();
+
+        // Read the alternate persistent fields that we care about
+        int sign = fields.get("signum", -2);
+        byte[] magnitude = (byte[])fields.get("magnitude", null);
+
+        // Validate signum
+        if (sign < -1 || sign > 1) {
+            String message = "BigInteger: Invalid signum value";
+            if (fields.defaulted("signum"))
+                message = "BigInteger: Signum not present in stream";
+            throw new java.io.StreamCorruptedException(message);
+        }
+        int[] mag = stripLeadingZeroBytes(magnitude);
+        if ((mag.length == 0) != (sign == 0)) {
+            String message = "BigInteger: signum-magnitude mismatch";
+            if (fields.defaulted("magnitude"))
+                message = "BigInteger: Magnitude not present in stream";
+            throw new java.io.StreamCorruptedException(message);
+        }
+
+        // Commit final fields via Unsafe
+        UnsafeHolder.putSign(this, sign);
+
+        // Calculate mag field from magnitude and discard magnitude
+        UnsafeHolder.putMag(this, mag);
+        if (mag.length >= MAX_MAG_LENGTH) {
+            try {
+                checkRange();
+            } catch (ArithmeticException e) {
+                throw new java.io.StreamCorruptedException("BigInteger: Out of the supported range");
+            }
+        }
+    }
+
+    // Support for resetting final fields while deserializing
+    private static class UnsafeHolder {
+        private static final sun.misc.Unsafe unsafe;
+        private static final long signumOffset;
+        private static final long magOffset;
+        static {
+            try {
+                unsafe = sun.misc.Unsafe.getUnsafe();
+                signumOffset = unsafe.objectFieldOffset
+                    (BigInteger.class.getDeclaredField("signum"));
+                magOffset = unsafe.objectFieldOffset
+                    (BigInteger.class.getDeclaredField("mag"));
+            } catch (Exception ex) {
+                throw new ExceptionInInitializerError(ex);
+            }
+        }
+
+        static void putSign(BigInteger bi, int sign) {
+            unsafe.putIntVolatile(bi, signumOffset, sign);
+        }
+
+        static void putMag(BigInteger bi, int[] magnitude) {
+            unsafe.putObjectVolatile(bi, magOffset, magnitude);
+        }
+    }
+
+    /**
+     * Save the {@code BigInteger} instance to a stream.
+     * The magnitude of a BigInteger is serialized as a byte array for
+     * historical reasons.
+     *
+     * @serialData two necessary fields are written as well as obsolete
+     *             fields for compatibility with older versions.
+     */
+    private void writeObject(ObjectOutputStream s) throws IOException {
+        // set the values of the Serializable fields
+        ObjectOutputStream.PutField fields = s.putFields();
+        fields.put("signum", signum);
+        fields.put("magnitude", magSerializedForm());
+        // The values written for cached fields are compatible with older
+        // versions, but are ignored in readObject so don't otherwise matter.
+        // BEGIN Android-changed: Don't include the following fields.
+        // fields.put("bitCount", -1);
+        // fields.put("bitLength", -1);
+        // fields.put("lowestSetBit", -2);
+        // fields.put("firstNonzeroByteNum", -2);
+        // END Android-changed
+
+        // save them
+        s.writeFields();
+}
+
+    /**
+     * Returns the mag array as an array of bytes.
+     */
+    private byte[] magSerializedForm() {
+        int len = mag.length;
+
+        int bitLen = (len == 0 ? 0 : ((len - 1) << 5) + bitLengthForInt(mag[0]));
+        int byteLen = (bitLen + 7) >>> 3;
+        byte[] result = new byte[byteLen];
+
+        for (int i = byteLen - 1, bytesCopied = 4, intIndex = len - 1, nextInt = 0;
+             i >= 0; i--) {
+            if (bytesCopied == 4) {
+                nextInt = mag[intIndex--];
+                bytesCopied = 1;
+            } else {
+                nextInt >>>= 8;
+                bytesCopied++;
+            }
+            result[i] = (byte)nextInt;
+        }
+        return result;
+    }
+
+    /**
+     * Converts this {@code BigInteger} to a {@code long}, checking
+     * for lost information.  If the value of this {@code BigInteger}
+     * is out of the range of the {@code long} type, then an
+     * {@code ArithmeticException} is thrown.
+     *
+     * @return this {@code BigInteger} converted to a {@code long}.
+     * @throws ArithmeticException if the value of {@code this} will
+     * not exactly fit in a {@code long}.
+     * @see BigInteger#longValue
+     * @since  1.8
+     */
+    public long longValueExact() {
+        if (mag.length <= 2 && bitLength() <= 63)
+            return longValue();
+        else
+            throw new ArithmeticException("BigInteger out of long range");
+    }
+
+    /**
+     * Converts this {@code BigInteger} to an {@code int}, checking
+     * for lost information.  If the value of this {@code BigInteger}
+     * is out of the range of the {@code int} type, then an
+     * {@code ArithmeticException} is thrown.
+     *
+     * @return this {@code BigInteger} converted to an {@code int}.
+     * @throws ArithmeticException if the value of {@code this} will
+     * not exactly fit in a {@code int}.
+     * @see BigInteger#intValue
+     * @since  1.8
+     */
+    public int intValueExact() {
+        if (mag.length <= 1 && bitLength() <= 31)
+            return intValue();
+        else
+            throw new ArithmeticException("BigInteger out of int range");
+    }
+
+    /**
+     * Converts this {@code BigInteger} to a {@code short}, checking
+     * for lost information.  If the value of this {@code BigInteger}
+     * is out of the range of the {@code short} type, then an
+     * {@code ArithmeticException} is thrown.
+     *
+     * @return this {@code BigInteger} converted to a {@code short}.
+     * @throws ArithmeticException if the value of {@code this} will
+     * not exactly fit in a {@code short}.
+     * @see BigInteger#shortValue
+     * @since  1.8
+     */
+    public short shortValueExact() {
+        if (mag.length <= 1 && bitLength() <= 31) {
+            int value = intValue();
+            if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE)
+                return shortValue();
+        }
+        throw new ArithmeticException("BigInteger out of short range");
+    }
+
+    /**
+     * Converts this {@code BigInteger} to a {@code byte}, checking
+     * for lost information.  If the value of this {@code BigInteger}
+     * is out of the range of the {@code byte} type, then an
+     * {@code ArithmeticException} is thrown.
+     *
+     * @return this {@code BigInteger} converted to a {@code byte}.
+     * @throws ArithmeticException if the value of {@code this} will
+     * not exactly fit in a {@code byte}.
+     * @see BigInteger#byteValue
+     * @since  1.8
+     */
+    public byte byteValueExact() {
+        if (mag.length <= 1 && bitLength() <= 31) {
+            int value = intValue();
+            if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
+                return byteValue();
+        }
+        throw new ArithmeticException("BigInteger out of byte range");
+    }
+}
diff --git a/ojluni/src/main/java/java/math/BitSieve.java b/ojluni/src/main/java/java/math/BitSieve.java
new file mode 100644
index 0000000..8d0d370
--- /dev/null
+++ b/ojluni/src/main/java/java/math/BitSieve.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 1999, 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 java.math;
+
+/**
+ * A simple bit sieve used for finding prime number candidates. Allows setting
+ * and clearing of bits in a storage array. The size of the sieve is assumed to
+ * be constant to reduce overhead. All the bits of a new bitSieve are zero, and
+ * bits are removed from it by setting them.
+ *
+ * To reduce storage space and increase efficiency, no even numbers are
+ * represented in the sieve (each bit in the sieve represents an odd number).
+ * The relationship between the index of a bit and the number it represents is
+ * given by
+ * N = offset + (2*index + 1);
+ * Where N is the integer represented by a bit in the sieve, offset is some
+ * even integer offset indicating where the sieve begins, and index is the
+ * index of a bit in the sieve array.
+ *
+ * @see     BigInteger
+ * @author  Michael McCloskey
+ * @since   1.3
+ */
+class BitSieve {
+    /**
+     * Stores the bits in this bitSieve.
+     */
+    private long bits[];
+
+    /**
+     * Length is how many bits this sieve holds.
+     */
+    private int length;
+
+    /**
+     * A small sieve used to filter out multiples of small primes in a search
+     * sieve.
+     */
+    private static BitSieve smallSieve = new BitSieve();
+
+    /**
+     * Construct a "small sieve" with a base of 0.  This constructor is
+     * used internally to generate the set of "small primes" whose multiples
+     * are excluded from sieves generated by the main (package private)
+     * constructor, BitSieve(BigInteger base, int searchLen).  The length
+     * of the sieve generated by this constructor was chosen for performance;
+     * it controls a tradeoff between how much time is spent constructing
+     * other sieves, and how much time is wasted testing composite candidates
+     * for primality.  The length was chosen experimentally to yield good
+     * performance.
+     */
+    private BitSieve() {
+        length = 150 * 64;
+        bits = new long[(unitIndex(length - 1) + 1)];
+
+        // Mark 1 as composite
+        set(0);
+        int nextIndex = 1;
+        int nextPrime = 3;
+
+        // Find primes and remove their multiples from sieve
+        do {
+            sieveSingle(length, nextIndex + nextPrime, nextPrime);
+            nextIndex = sieveSearch(length, nextIndex + 1);
+            nextPrime = 2*nextIndex + 1;
+        } while((nextIndex > 0) && (nextPrime < length));
+    }
+
+    /**
+     * Construct a bit sieve of searchLen bits used for finding prime number
+     * candidates. The new sieve begins at the specified base, which must
+     * be even.
+     */
+    BitSieve(BigInteger base, int searchLen) {
+        /*
+         * Candidates are indicated by clear bits in the sieve. As a candidates
+         * nonprimality is calculated, a bit is set in the sieve to eliminate
+         * it. To reduce storage space and increase efficiency, no even numbers
+         * are represented in the sieve (each bit in the sieve represents an
+         * odd number).
+         */
+        bits = new long[(unitIndex(searchLen-1) + 1)];
+        length = searchLen;
+        int start = 0;
+
+        int step = smallSieve.sieveSearch(smallSieve.length, start);
+        int convertedStep = (step *2) + 1;
+
+        // Construct the large sieve at an even offset specified by base
+        MutableBigInteger b = new MutableBigInteger(base);
+        MutableBigInteger q = new MutableBigInteger();
+        do {
+            // Calculate base mod convertedStep
+            start = b.divideOneWord(convertedStep, q);
+
+            // Take each multiple of step out of sieve
+            start = convertedStep - start;
+            if (start%2 == 0)
+                start += convertedStep;
+            sieveSingle(searchLen, (start-1)/2, convertedStep);
+
+            // Find next prime from small sieve
+            step = smallSieve.sieveSearch(smallSieve.length, step+1);
+            convertedStep = (step *2) + 1;
+        } while (step > 0);
+    }
+
+    /**
+     * Given a bit index return unit index containing it.
+     */
+    private static int unitIndex(int bitIndex) {
+        return bitIndex >>> 6;
+    }
+
+    /**
+     * Return a unit that masks the specified bit in its unit.
+     */
+    private static long bit(int bitIndex) {
+        return 1L << (bitIndex & ((1<<6) - 1));
+    }
+
+    /**
+     * Get the value of the bit at the specified index.
+     */
+    private boolean get(int bitIndex) {
+        int unitIndex = unitIndex(bitIndex);
+        return ((bits[unitIndex] & bit(bitIndex)) != 0);
+    }
+
+    /**
+     * Set the bit at the specified index.
+     */
+    private void set(int bitIndex) {
+        int unitIndex = unitIndex(bitIndex);
+        bits[unitIndex] |= bit(bitIndex);
+    }
+
+    /**
+     * This method returns the index of the first clear bit in the search
+     * array that occurs at or after start. It will not search past the
+     * specified limit. It returns -1 if there is no such clear bit.
+     */
+    private int sieveSearch(int limit, int start) {
+        if (start >= limit)
+            return -1;
+
+        int index = start;
+        do {
+            if (!get(index))
+                return index;
+            index++;
+        } while(index < limit-1);
+        return -1;
+    }
+
+    /**
+     * Sieve a single set of multiples out of the sieve. Begin to remove
+     * multiples of the specified step starting at the specified start index,
+     * up to the specified limit.
+     */
+    private void sieveSingle(int limit, int start, int step) {
+        while(start < limit) {
+            set(start);
+            start += step;
+        }
+    }
+
+    /**
+     * Test probable primes in the sieve and return successful candidates.
+     */
+    BigInteger retrieve(BigInteger initValue, int certainty, java.util.Random random) {
+        // Examine the sieve one long at a time to find possible primes
+        int offset = 1;
+        for (int i=0; i<bits.length; i++) {
+            long nextLong = ~bits[i];
+            for (int j=0; j<64; j++) {
+                if ((nextLong & 1) == 1) {
+                    BigInteger candidate = initValue.add(
+                                           BigInteger.valueOf(offset));
+                    if (candidate.primeToCertainty(certainty, random))
+                        return candidate;
+                }
+                nextLong >>>= 1;
+                offset+=2;
+            }
+        }
+        return null;
+    }
+}
diff --git a/ojluni/src/main/java/java/math/MathContext.java b/ojluni/src/main/java/java/math/MathContext.java
new file mode 100644
index 0000000..f9947d3
--- /dev/null
+++ b/ojluni/src/main/java/java/math/MathContext.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/*
+ * Portions Copyright IBM Corporation, 1997, 2001. All Rights Reserved.
+ */
+
+package java.math;
+import java.io.*;
+
+/**
+ * Immutable objects which encapsulate the context settings which
+ * describe certain rules for numerical operators, such as those
+ * implemented by the {@link BigDecimal} class.
+ *
+ * <p>The base-independent settings are:
+ * <ol>
+ * <li>{@code precision}:
+ * the number of digits to be used for an operation; results are
+ * rounded to this precision
+ *
+ * <li>{@code roundingMode}:
+ * a {@link RoundingMode} object which specifies the algorithm to be
+ * used for rounding.
+ * </ol>
+ *
+ * @see     BigDecimal
+ * @see     RoundingMode
+ * @author  Mike Cowlishaw
+ * @author  Joseph D. Darcy
+ * @since 1.5
+ */
+
+public final class MathContext implements Serializable {
+
+    /* ----- Constants ----- */
+
+    // defaults for constructors
+    private static final int DEFAULT_DIGITS = 9;
+    private static final RoundingMode DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP;
+    // Smallest values for digits (Maximum is Integer.MAX_VALUE)
+    private static final int MIN_DIGITS = 0;
+
+    // Serialization version
+    private static final long serialVersionUID = 5579720004786848255L;
+
+    /* ----- Public Properties ----- */
+    /**
+     *  A {@code MathContext} object whose settings have the values
+     *  required for unlimited precision arithmetic.
+     *  The values of the settings are:
+     *  <code>
+     *  precision=0 roundingMode=HALF_UP
+     *  </code>
+     */
+    public static final MathContext UNLIMITED =
+        new MathContext(0, RoundingMode.HALF_UP);
+
+    /**
+     *  A {@code MathContext} object with a precision setting
+     *  matching the IEEE 754R Decimal32 format, 7 digits, and a
+     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
+     *  IEEE 754R default.
+     */
+    public static final MathContext DECIMAL32 =
+        new MathContext(7, RoundingMode.HALF_EVEN);
+
+    /**
+     *  A {@code MathContext} object with a precision setting
+     *  matching the IEEE 754R Decimal64 format, 16 digits, and a
+     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
+     *  IEEE 754R default.
+     */
+    public static final MathContext DECIMAL64 =
+        new MathContext(16, RoundingMode.HALF_EVEN);
+
+    /**
+     *  A {@code MathContext} object with a precision setting
+     *  matching the IEEE 754R Decimal128 format, 34 digits, and a
+     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
+     *  IEEE 754R default.
+     */
+    public static final MathContext DECIMAL128 =
+        new MathContext(34, RoundingMode.HALF_EVEN);
+
+    /* ----- Shared Properties ----- */
+    /**
+     * The number of digits to be used for an operation.  A value of 0
+     * indicates that unlimited precision (as many digits as are
+     * required) will be used.  Note that leading zeros (in the
+     * coefficient of a number) are never significant.
+     *
+     * <p>{@code precision} will always be non-negative.
+     *
+     * @serial
+     */
+    final int precision;
+
+    /**
+     * The rounding algorithm to be used for an operation.
+     *
+     * @see RoundingMode
+     * @serial
+     */
+    final RoundingMode roundingMode;
+
+    /* ----- Constructors ----- */
+
+    /**
+     * Constructs a new {@code MathContext} with the specified
+     * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding
+     * mode.
+     *
+     * @param setPrecision The non-negative {@code int} precision setting.
+     * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
+     *         than zero.
+     */
+    public MathContext(int setPrecision) {
+        this(setPrecision, DEFAULT_ROUNDINGMODE);
+        return;
+    }
+
+    /**
+     * Constructs a new {@code MathContext} with a specified
+     * precision and rounding mode.
+     *
+     * @param setPrecision The non-negative {@code int} precision setting.
+     * @param setRoundingMode The rounding mode to use.
+     * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
+     *         than zero.
+     * @throws NullPointerException if the rounding mode argument is {@code null}
+     */
+    public MathContext(int setPrecision,
+                       RoundingMode setRoundingMode) {
+        if (setPrecision < MIN_DIGITS)
+            throw new IllegalArgumentException("Digits < 0");
+        if (setRoundingMode == null)
+            throw new NullPointerException("null RoundingMode");
+
+        precision = setPrecision;
+        roundingMode = setRoundingMode;
+        return;
+    }
+
+    /**
+     * Constructs a new {@code MathContext} from a string.
+     *
+     * The string must be in the same format as that produced by the
+     * {@link #toString} method.
+     *
+     * <p>An {@code IllegalArgumentException} is thrown if the precision
+     * section of the string is out of range ({@code < 0}) or the string is
+     * not in the format created by the {@link #toString} method.
+     *
+     * @param val The string to be parsed
+     * @throws IllegalArgumentException if the precision section is out of range
+     * or of incorrect format
+     * @throws NullPointerException if the argument is {@code null}
+     */
+    public MathContext(String val) {
+        boolean bad = false;
+        int setPrecision;
+        if (val == null)
+            throw new NullPointerException("null String");
+        try { // any error here is a string format problem
+            if (!val.startsWith("precision=")) throw new RuntimeException();
+            int fence = val.indexOf(' ');    // could be -1
+            int off = 10;                     // where value starts
+            setPrecision = Integer.parseInt(val.substring(10, fence));
+
+            if (!val.startsWith("roundingMode=", fence+1))
+                throw new RuntimeException();
+            off = fence + 1 + 13;
+            String str = val.substring(off, val.length());
+            roundingMode = RoundingMode.valueOf(str);
+        } catch (RuntimeException re) {
+            throw new IllegalArgumentException("bad string format");
+        }
+
+        if (setPrecision < MIN_DIGITS)
+            throw new IllegalArgumentException("Digits < 0");
+        // the other parameters cannot be invalid if we got here
+        precision = setPrecision;
+    }
+
+    /**
+     * Returns the {@code precision} setting.
+     * This value is always non-negative.
+     *
+     * @return an {@code int} which is the value of the {@code precision}
+     *         setting
+     */
+    public int getPrecision() {
+        return precision;
+    }
+
+    /**
+     * Returns the roundingMode setting.
+     * This will be one of
+     * {@link  RoundingMode#CEILING},
+     * {@link  RoundingMode#DOWN},
+     * {@link  RoundingMode#FLOOR},
+     * {@link  RoundingMode#HALF_DOWN},
+     * {@link  RoundingMode#HALF_EVEN},
+     * {@link  RoundingMode#HALF_UP},
+     * {@link  RoundingMode#UNNECESSARY}, or
+     * {@link  RoundingMode#UP}.
+     *
+     * @return a {@code RoundingMode} object which is the value of the
+     *         {@code roundingMode} setting
+     */
+
+    public RoundingMode getRoundingMode() {
+        return roundingMode;
+    }
+
+    /**
+     * Compares this {@code MathContext} with the specified
+     * {@code Object} for equality.
+     *
+     * @param  x {@code Object} to which this {@code MathContext} is to
+     *         be compared.
+     * @return {@code true} if and only if the specified {@code Object} is
+     *         a {@code MathContext} object which has exactly the same
+     *         settings as this object
+     */
+    public boolean equals(Object x){
+        MathContext mc;
+        if (!(x instanceof MathContext))
+            return false;
+        mc = (MathContext) x;
+        return mc.precision == this.precision
+            && mc.roundingMode == this.roundingMode; // no need for .equals()
+    }
+
+    /**
+     * Returns the hash code for this {@code MathContext}.
+     *
+     * @return hash code for this {@code MathContext}
+     */
+    public int hashCode() {
+        return this.precision + roundingMode.hashCode() * 59;
+    }
+
+    /**
+     * Returns the string representation of this {@code MathContext}.
+     * The {@code String} returned represents the settings of the
+     * {@code MathContext} object as two space-delimited words
+     * (separated by a single space character, <tt>'&#92;u0020'</tt>,
+     * and with no leading or trailing white space), as follows:
+     * <ol>
+     * <li>
+     * The string {@code "precision="}, immediately followed
+     * by the value of the precision setting as a numeric string as if
+     * generated by the {@link Integer#toString(int) Integer.toString}
+     * method.
+     *
+     * <li>
+     * The string {@code "roundingMode="}, immediately
+     * followed by the value of the {@code roundingMode} setting as a
+     * word.  This word will be the same as the name of the
+     * corresponding public constant in the {@link RoundingMode}
+     * enum.
+     * </ol>
+     * <p>
+     * For example:
+     * <pre>
+     * precision=9 roundingMode=HALF_UP
+     * </pre>
+     *
+     * Additional words may be appended to the result of
+     * {@code toString} in the future if more properties are added to
+     * this class.
+     *
+     * @return a {@code String} representing the context settings
+     */
+    public java.lang.String toString() {
+        return "precision=" +           precision + " " +
+               "roundingMode=" +        roundingMode.toString();
+    }
+
+    // Private methods
+
+    /**
+     * Reconstitute the {@code MathContext} instance from a stream (that is,
+     * deserialize it).
+     *
+     * @param s the stream being read.
+     */
+    private void readObject(java.io.ObjectInputStream s)
+        throws java.io.IOException, ClassNotFoundException {
+        s.defaultReadObject();     // read in all fields
+        // validate possibly bad fields
+        if (precision < MIN_DIGITS) {
+            String message = "MathContext: invalid digits in stream";
+            throw new java.io.StreamCorruptedException(message);
+        }
+        if (roundingMode == null) {
+            String message = "MathContext: null roundingMode in stream";
+            throw new java.io.StreamCorruptedException(message);
+        }
+    }
+
+}
diff --git a/ojluni/src/main/java/java/math/MutableBigInteger.java b/ojluni/src/main/java/java/math/MutableBigInteger.java
new file mode 100644
index 0000000..b9cb0fb
--- /dev/null
+++ b/ojluni/src/main/java/java/math/MutableBigInteger.java
@@ -0,0 +1,2263 @@
+/*
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact 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.math;
+
+/**
+ * A class used to represent multiprecision integers that makes efficient
+ * use of allocated space by allowing a number to occupy only part of
+ * an array so that the arrays do not have to be reallocated as often.
+ * When performing an operation with many iterations the array used to
+ * hold a number is only reallocated when necessary and does not have to
+ * be the same size as the number it represents. A mutable number allows
+ * calculations to occur on the same number without having to create
+ * a new number for every step of the calculation as occurs with
+ * BigIntegers.
+ *
+ * @see     BigInteger
+ * @author  Michael McCloskey
+ * @author  Timothy Buktu
+ * @since   1.3
+ */
+
+import static java.math.BigDecimal.INFLATED;
+import static java.math.BigInteger.LONG_MASK;
+import java.util.Arrays;
+
+class MutableBigInteger {
+    /**
+     * Holds the magnitude of this MutableBigInteger in big endian order.
+     * The magnitude may start at an offset into the value array, and it may
+     * end before the length of the value array.
+     */
+    int[] value;
+
+    /**
+     * The number of ints of the value array that are currently used
+     * to hold the magnitude of this MutableBigInteger. The magnitude starts
+     * at an offset and offset + intLen may be less than value.length.
+     */
+    int intLen;
+
+    /**
+     * The offset into the value array where the magnitude of this
+     * MutableBigInteger begins.
+     */
+    int offset = 0;
+
+    // Constants
+    /**
+     * MutableBigInteger with one element value array with the value 1. Used by
+     * BigDecimal divideAndRound to increment the quotient. Use this constant
+     * only when the method is not going to modify this object.
+     */
+    static final MutableBigInteger ONE = new MutableBigInteger(1);
+
+    /**
+     * The minimum {@code intLen} for cancelling powers of two before
+     * dividing.
+     * If the number of ints is less than this threshold,
+     * {@code divideKnuth} does not eliminate common powers of two from
+     * the dividend and divisor.
+     */
+    static final int KNUTH_POW2_THRESH_LEN = 6;
+
+    /**
+     * The minimum number of trailing zero ints for cancelling powers of two
+     * before dividing.
+     * If the dividend and divisor don't share at least this many zero ints
+     * at the end, {@code divideKnuth} does not eliminate common powers
+     * of two from the dividend and divisor.
+     */
+    static final int KNUTH_POW2_THRESH_ZEROS = 3;
+
+    // Constructors
+
+    /**
+     * The default constructor. An empty MutableBigInteger is created with
+     * a one word capacity.
+     */
+    MutableBigInteger() {
+        value = new int[1];
+        intLen = 0;
+    }
+
+    /**
+     * Construct a new MutableBigInteger with a magnitude specified by
+     * the int val.
+     */
+    MutableBigInteger(int val) {
+        value = new int[1];
+        intLen = 1;
+        value[0] = val;
+    }
+
+    /**
+     * Construct a new MutableBigInteger with the specified value array
+     * up to the length of the array supplied.
+     */
+    MutableBigInteger(int[] val) {
+        value = val;
+        intLen = val.length;
+    }
+
+    /**
+     * Construct a new MutableBigInteger with a magnitude equal to the
+     * specified BigInteger.
+     */
+    MutableBigInteger(BigInteger b) {
+        intLen = b.mag.length;
+        value = Arrays.copyOf(b.mag, intLen);
+    }
+
+    /**
+     * Construct a new MutableBigInteger with a magnitude equal to the
+     * specified MutableBigInteger.
+     */
+    MutableBigInteger(MutableBigInteger val) {
+        intLen = val.intLen;
+        value = Arrays.copyOfRange(val.value, val.offset, val.offset + intLen);
+    }
+
+    /**
+     * Makes this number an {@code n}-int number all of whose bits are ones.
+     * Used by Burnikel-Ziegler division.
+     * @param n number of ints in the {@code value} array
+     * @return a number equal to {@code ((1<<(32*n)))-1}
+     */
+    private void ones(int n) {
+        if (n > value.length)
+            value = new int[n];
+        Arrays.fill(value, -1);
+        offset = 0;
+        intLen = n;
+    }
+
+    /**
+     * Internal helper method to return the magnitude array. The caller is not
+     * supposed to modify the returned array.
+     */
+    private int[] getMagnitudeArray() {
+        if (offset > 0 || value.length != intLen)
+            return Arrays.copyOfRange(value, offset, offset + intLen);
+        return value;
+    }
+
+    /**
+     * Convert this MutableBigInteger to a long value. The caller has to make
+     * sure this MutableBigInteger can be fit into long.
+     */
+    private long toLong() {
+        assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long";
+        if (intLen == 0)
+            return 0;
+        long d = value[offset] & LONG_MASK;
+        return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d;
+    }
+
+    /**
+     * Convert this MutableBigInteger to a BigInteger object.
+     */
+    BigInteger toBigInteger(int sign) {
+        if (intLen == 0 || sign == 0)
+            return BigInteger.ZERO;
+        return new BigInteger(getMagnitudeArray(), sign);
+    }
+
+    /**
+     * Converts this number to a nonnegative {@code BigInteger}.
+     */
+    BigInteger toBigInteger() {
+        normalize();
+        return toBigInteger(isZero() ? 0 : 1);
+    }
+
+    /**
+     * Convert this MutableBigInteger to BigDecimal object with the specified sign
+     * and scale.
+     */
+    BigDecimal toBigDecimal(int sign, int scale) {
+        if (intLen == 0 || sign == 0)
+            return BigDecimal.zeroValueOf(scale);
+        int[] mag = getMagnitudeArray();
+        int len = mag.length;
+        int d = mag[0];
+        // If this MutableBigInteger can't be fit into long, we need to
+        // make a BigInteger object for the resultant BigDecimal object.
+        if (len > 2 || (d < 0 && len == 2))
+            return new BigDecimal(new BigInteger(mag, sign), INFLATED, scale, 0);
+        long v = (len == 2) ?
+            ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
+            d & LONG_MASK;
+        return BigDecimal.valueOf(sign == -1 ? -v : v, scale);
+    }
+
+    /**
+     * This is for internal use in converting from a MutableBigInteger
+     * object into a long value given a specified sign.
+     * returns INFLATED if value is not fit into long
+     */
+    long toCompactValue(int sign) {
+        if (intLen == 0 || sign == 0)
+            return 0L;
+        int[] mag = getMagnitudeArray();
+        int len = mag.length;
+        int d = mag[0];
+        // If this MutableBigInteger can not be fitted into long, we need to
+        // make a BigInteger object for the resultant BigDecimal object.
+        if (len > 2 || (d < 0 && len == 2))
+            return INFLATED;
+        long v = (len == 2) ?
+            ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
+            d & LONG_MASK;
+        return sign == -1 ? -v : v;
+    }
+
+    /**
+     * Clear out a MutableBigInteger for reuse.
+     */
+    void clear() {
+        offset = intLen = 0;
+        for (int index=0, n=value.length; index < n; index++)
+            value[index] = 0;
+    }
+
+    /**
+     * Set a MutableBigInteger to zero, removing its offset.
+     */
+    void reset() {
+        offset = intLen = 0;
+    }
+
+    /**
+     * Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1
+     * as this MutableBigInteger is numerically less than, equal to, or
+     * greater than <tt>b</tt>.
+     */
+    final int compare(MutableBigInteger b) {
+        int blen = b.intLen;
+        if (intLen < blen)
+            return -1;
+        if (intLen > blen)
+           return 1;
+
+        // Add Integer.MIN_VALUE to make the comparison act as unsigned integer
+        // comparison.
+        int[] bval = b.value;
+        for (int i = offset, j = b.offset; i < intLen + offset; i++, j++) {
+            int b1 = value[i] + 0x80000000;
+            int b2 = bval[j]  + 0x80000000;
+            if (b1 < b2)
+                return -1;
+            if (b1 > b2)
+                return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Returns a value equal to what {@code b.leftShift(32*ints); return compare(b);}
+     * would return, but doesn't change the value of {@code b}.
+     */
+    private int compareShifted(MutableBigInteger b, int ints) {
+        int blen = b.intLen;
+        int alen = intLen - ints;
+        if (alen < blen)
+            return -1;
+        if (alen > blen)
+           return 1;
+
+        // Add Integer.MIN_VALUE to make the comparison act as unsigned integer
+        // comparison.
+        int[] bval = b.value;
+        for (int i = offset, j = b.offset; i < alen + offset; i++, j++) {
+            int b1 = value[i] + 0x80000000;
+            int b2 = bval[j]  + 0x80000000;
+            if (b1 < b2)
+                return -1;
+            if (b1 > b2)
+                return 1;
+        }
+        return 0;
+    }
+
+    /**
+     * Compare this against half of a MutableBigInteger object (Needed for
+     * remainder tests).
+     * Assumes no leading unnecessary zeros, which holds for results
+     * from divide().
+     */
+    final int compareHalf(MutableBigInteger b) {
+        int blen = b.intLen;
+        int len = intLen;
+        if (len <= 0)
+            return blen <= 0 ? 0 : -1;
+        if (len > blen)
+            return 1;
+        if (len < blen - 1)
+            return -1;
+        int[] bval = b.value;
+        int bstart = 0;
+        int carry = 0;
+        // Only 2 cases left:len == blen or len == blen - 1
+        if (len != blen) { // len == blen - 1
+            if (bval[bstart] == 1) {
+                ++bstart;
+                carry = 0x80000000;
+            } else
+                return -1;
+        }
+        // compare values with right-shifted values of b,
+        // carrying shifted-out bits across words
+        int[] val = value;
+        for (int i = offset, j = bstart; i < len + offset;) {
+            int bv = bval[j++];
+            long hb = ((bv >>> 1) + carry) & LONG_MASK;
+            long v = val[i++] & LONG_MASK;
+            if (v != hb)
+                return v < hb ? -1 : 1;
+            carry = (bv & 1) << 31; // carray will be either 0x80000000 or 0
+        }
+        return carry == 0 ? 0 : -1;
+    }
+
+    /**
+     * Return the index of the lowest set bit in this MutableBigInteger. If the
+     * magnitude of this MutableBigInteger is zero, -1 is returned.
+     */
+    private final int getLowestSetBit() {
+        if (intLen == 0)
+            return -1;
+        int j, b;
+        for (j=intLen-1; (j > 0) && (value[j+offset] == 0); j--)
+            ;
+        b = value[j+offset];
+        if (b == 0)
+            return -1;
+        return ((intLen-1-j)<<5) + Integer.numberOfTrailingZeros(b);
+    }
+
+    /**
+     * Return the int in use in this MutableBigInteger at the specified
+     * index. This method is not used because it is not inlined on all
+     * platforms.
+     */
+    private final int getInt(int index) {
+        return value[offset+index];
+    }
+
+    /**
+     * Return a long which is equal to the unsigned value of the int in
+     * use in this MutableBigInteger at the specified index. This method is
+     * not used because it is not inlined on all platforms.
+     */
+    private final long getLong(int index) {
+        return value[offset+index] & LONG_MASK;
+    }
+
+    /**
+     * Ensure that the MutableBigInteger is in normal form, specifically
+     * making sure that there are no leading zeros, and that if the
+     * magnitude is zero, then intLen is zero.
+     */
+    final void normalize() {
+        if (intLen == 0) {
+            offset = 0;
+            return;
+        }
+
+        int index = offset;
+        if (value[index] != 0)
+            return;
+
+        int indexBound = index+intLen;
+        do {
+            index++;
+        } while(index < indexBound && value[index] == 0);
+
+        int numZeros = index - offset;
+        intLen -= numZeros;
+        offset = (intLen == 0 ?  0 : offset+numZeros);
+    }
+
+    /**
+     * If this MutableBigInteger cannot hold len words, increase the size
+     * of the value array to len words.
+     */
+    private final void ensureCapacity(int len) {
+        if (value.length < len) {
+            value = new int[len];
+            offset = 0;
+            intLen = len;
+        }
+    }
+
+    /**
+     * Convert this MutableBigInteger into an int array with no leading
+     * zeros, of a length that is equal to this MutableBigInteger's intLen.
+     */
+    int[] toIntArray() {
+        int[] result = new int[intLen];
+        for(int i=0; i < intLen; i++)
+            result[i] = value[offset+i];
+        return result;
+    }
+
+    /**
+     * Sets the int at index+offset in this MutableBigInteger to val.
+     * This does not get inlined on all platforms so it is not used
+     * as often as originally intended.
+     */
+    void setInt(int index, int val) {
+        value[offset + index] = val;
+    }
+
+    /**
+     * Sets this MutableBigInteger's value array to the specified array.
+     * The intLen is set to the specified length.
+     */
+    void setValue(int[] val, int length) {
+        value = val;
+        intLen = length;
+        offset = 0;
+    }
+
+    /**
+     * Sets this MutableBigInteger's value array to a copy of the specified
+     * array. The intLen is set to the length of the new array.
+     */
+    void copyValue(MutableBigInteger src) {
+        int len = src.intLen;
+        if (value.length < len)
+            value = new int[len];
+        System.arraycopy(src.value, src.offset, value, 0, len);
+        intLen = len;
+        offset = 0;
+    }
+
+    /**
+     * Sets this MutableBigInteger's value array to a copy of the specified
+     * array. The intLen is set to the length of the specified array.
+     */
+    void copyValue(int[] val) {
+        int len = val.length;
+        if (value.length < len)
+            value = new int[len];
+        System.arraycopy(val, 0, value, 0, len);
+        intLen = len;
+        offset = 0;
+    }
+
+    /**
+     * Returns true iff this MutableBigInteger has a value of one.
+     */
+    boolean isOne() {
+        return (intLen == 1) && (value[offset] == 1);
+    }
+
+    /**
+     * Returns true iff this MutableBigInteger has a value of zero.
+     */
+    boolean isZero() {
+        return (intLen == 0);
+    }
+
+    /**
+     * Returns true iff this MutableBigInteger is even.
+     */
+    boolean isEven() {
+        return (intLen == 0) || ((value[offset + intLen - 1] & 1) == 0);
+    }
+
+    /**
+     * Returns true iff this MutableBigInteger is odd.
+     */
+    boolean isOdd() {
+        return isZero() ? false : ((value[offset + intLen - 1] & 1) == 1);
+    }
+
+    /**
+     * Returns true iff this MutableBigInteger is in normal form. A
+     * MutableBigInteger is in normal form if it has no leading zeros
+     * after the offset, and intLen + offset <= value.length.
+     */
+    boolean isNormal() {
+        if (intLen + offset > value.length)
+            return false;
+        if (intLen == 0)
+            return true;
+        return (value[offset] != 0);
+    }
+
+    /**
+     * Returns a String representation of this MutableBigInteger in radix 10.
+     */
+    public String toString() {
+        BigInteger b = toBigInteger(1);
+        return b.toString();
+    }
+
+    /**
+     * Like {@link #rightShift(int)} but {@code n} can be greater than the length of the number.
+     */
+    void safeRightShift(int n) {
+        if (n/32 >= intLen) {
+            reset();
+        } else {
+            rightShift(n);
+        }
+    }
+
+    /**
+     * Right shift this MutableBigInteger n bits. The MutableBigInteger is left
+     * in normal form.
+     */
+    void rightShift(int n) {
+        if (intLen == 0)
+            return;
+        int nInts = n >>> 5;
+        int nBits = n & 0x1F;
+        this.intLen -= nInts;
+        if (nBits == 0)
+            return;
+        int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
+        if (nBits >= bitsInHighWord) {
+            this.primitiveLeftShift(32 - nBits);
+            this.intLen--;
+        } else {
+            primitiveRightShift(nBits);
+        }
+    }
+
+    /**
+     * Like {@link #leftShift(int)} but {@code n} can be zero.
+     */
+    void safeLeftShift(int n) {
+        if (n > 0) {
+            leftShift(n);
+        }
+    }
+
+    /**
+     * Left shift this MutableBigInteger n bits.
+     */
+    void leftShift(int n) {
+        /*
+         * If there is enough storage space in this MutableBigInteger already
+         * the available space will be used. Space to the right of the used
+         * ints in the value array is faster to utilize, so the extra space
+         * will be taken from the right if possible.
+         */
+        if (intLen == 0)
+           return;
+        int nInts = n >>> 5;
+        int nBits = n&0x1F;
+        int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
+
+        // If shift can be done without moving words, do so
+        if (n <= (32-bitsInHighWord)) {
+            primitiveLeftShift(nBits);
+            return;
+        }
+
+        int newLen = intLen + nInts +1;
+        if (nBits <= (32-bitsInHighWord))
+            newLen--;
+        if (value.length < newLen) {
+            // The array must grow
+            int[] result = new int[newLen];
+            for (int i=0; i < intLen; i++)
+                result[i] = value[offset+i];
+            setValue(result, newLen);
+        } else if (value.length - offset >= newLen) {
+            // Use space on right
+            for(int i=0; i < newLen - intLen; i++)
+                value[offset+intLen+i] = 0;
+        } else {
+            // Must use space on left
+            for (int i=0; i < intLen; i++)
+                value[i] = value[offset+i];
+            for (int i=intLen; i < newLen; i++)
+                value[i] = 0;
+            offset = 0;
+        }
+        intLen = newLen;
+        if (nBits == 0)
+            return;
+        if (nBits <= (32-bitsInHighWord))
+            primitiveLeftShift(nBits);
+        else
+            primitiveRightShift(32 -nBits);
+    }
+
+    /**
+     * A primitive used for division. This method adds in one multiple of the
+     * divisor a back to the dividend result at a specified offset. It is used
+     * when qhat was estimated too large, and must be adjusted.
+     */
+    private int divadd(int[] a, int[] result, int offset) {
+        long carry = 0;
+
+        for (int j=a.length-1; j >= 0; j--) {
+            long sum = (a[j] & LONG_MASK) +
+                       (result[j+offset] & LONG_MASK) + carry;
+            result[j+offset] = (int)sum;
+            carry = sum >>> 32;
+        }
+        return (int)carry;
+    }
+
+    /**
+     * This method is used for division. It multiplies an n word input a by one
+     * word input x, and subtracts the n word product from q. This is needed
+     * when subtracting qhat*divisor from dividend.
+     */
+    private int mulsub(int[] q, int[] a, int x, int len, int offset) {
+        long xLong = x & LONG_MASK;
+        long carry = 0;
+        offset += len;
+
+        for (int j=len-1; j >= 0; j--) {
+            long product = (a[j] & LONG_MASK) * xLong + carry;
+            long difference = q[offset] - product;
+            q[offset--] = (int)difference;
+            carry = (product >>> 32)
+                     + (((difference & LONG_MASK) >
+                         (((~(int)product) & LONG_MASK))) ? 1:0);
+        }
+        return (int)carry;
+    }
+
+    /**
+     * The method is the same as mulsun, except the fact that q array is not
+     * updated, the only result of the method is borrow flag.
+     */
+    private int mulsubBorrow(int[] q, int[] a, int x, int len, int offset) {
+        long xLong = x & LONG_MASK;
+        long carry = 0;
+        offset += len;
+        for (int j=len-1; j >= 0; j--) {
+            long product = (a[j] & LONG_MASK) * xLong + carry;
+            long difference = q[offset--] - product;
+            carry = (product >>> 32)
+                     + (((difference & LONG_MASK) >
+                         (((~(int)product) & LONG_MASK))) ? 1:0);
+        }
+        return (int)carry;
+    }
+
+    /**
+     * Right shift this MutableBigInteger n bits, where n is
+     * less than 32.
+     * Assumes that intLen > 0, n > 0 for speed
+     */
+    private final void primitiveRightShift(int n) {
+        int[] val = value;
+        int n2 = 32 - n;
+        for (int i=offset+intLen-1, c=val[i]; i > offset; i--) {
+            int b = c;
+            c = val[i-1];
+            val[i] = (c << n2) | (b >>> n);
+        }
+        val[offset] >>>= n;
+    }
+
+    /**
+     * Left shift this MutableBigInteger n bits, where n is
+     * less than 32.
+     * Assumes that intLen > 0, n > 0 for speed
+     */
+    private final void primitiveLeftShift(int n) {
+        int[] val = value;
+        int n2 = 32 - n;
+        for (int i=offset, c=val[i], m=i+intLen-1; i < m; i++) {
+            int b = c;
+            c = val[i+1];
+            val[i] = (b << n) | (c >>> n2);
+        }
+        val[offset+intLen-1] <<= n;
+    }
+
+    /**
+     * Returns a {@code BigInteger} equal to the {@code n}
+     * low ints of this number.
+     */
+    private BigInteger getLower(int n) {
+        if (isZero()) {
+            return BigInteger.ZERO;
+        } else if (intLen < n) {
+            return toBigInteger(1);
+        } else {
+            // strip zeros
+            int len = n;
+            while (len > 0 && value[offset+intLen-len] == 0)
+                len--;
+            int sign = len > 0 ? 1 : 0;
+            return new BigInteger(Arrays.copyOfRange(value, offset+intLen-len, offset+intLen), sign);
+        }
+    }
+
+    /**
+     * Discards all ints whose index is greater than {@code n}.
+     */
+    private void keepLower(int n) {
+        if (intLen >= n) {
+            offset += intLen - n;
+            intLen = n;
+        }
+    }
+
+    /**
+     * Adds the contents of two MutableBigInteger objects.The result
+     * is placed within this MutableBigInteger.
+     * The contents of the addend are not changed.
+     */
+    void add(MutableBigInteger addend) {
+        int x = intLen;
+        int y = addend.intLen;
+        int resultLen = (intLen > addend.intLen ? intLen : addend.intLen);
+        int[] result = (value.length < resultLen ? new int[resultLen] : value);
+
+        int rstart = result.length-1;
+        long sum;
+        long carry = 0;
+
+        // Add common parts of both numbers
+        while(x > 0 && y > 0) {
+            x--; y--;
+            sum = (value[x+offset] & LONG_MASK) +
+                (addend.value[y+addend.offset] & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+
+        // Add remainder of the longer number
+        while(x > 0) {
+            x--;
+            if (carry == 0 && result == value && rstart == (x + offset))
+                return;
+            sum = (value[x+offset] & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+        while(y > 0) {
+            y--;
+            sum = (addend.value[y+addend.offset] & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+
+        if (carry > 0) { // Result must grow in length
+            resultLen++;
+            if (result.length < resultLen) {
+                int temp[] = new int[resultLen];
+                // Result one word longer from carry-out; copy low-order
+                // bits into new result.
+                System.arraycopy(result, 0, temp, 1, result.length);
+                temp[0] = 1;
+                result = temp;
+            } else {
+                result[rstart--] = 1;
+            }
+        }
+
+        value = result;
+        intLen = resultLen;
+        offset = result.length - resultLen;
+    }
+
+    /**
+     * Adds the value of {@code addend} shifted {@code n} ints to the left.
+     * Has the same effect as {@code addend.leftShift(32*ints); add(addend);}
+     * but doesn't change the value of {@code addend}.
+     */
+    void addShifted(MutableBigInteger addend, int n) {
+        if (addend.isZero()) {
+            return;
+        }
+
+        int x = intLen;
+        int y = addend.intLen + n;
+        int resultLen = (intLen > y ? intLen : y);
+        int[] result = (value.length < resultLen ? new int[resultLen] : value);
+
+        int rstart = result.length-1;
+        long sum;
+        long carry = 0;
+
+        // Add common parts of both numbers
+        while (x > 0 && y > 0) {
+            x--; y--;
+            int bval = y+addend.offset < addend.value.length ? addend.value[y+addend.offset] : 0;
+            sum = (value[x+offset] & LONG_MASK) +
+                (bval & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+
+        // Add remainder of the longer number
+        while (x > 0) {
+            x--;
+            if (carry == 0 && result == value && rstart == (x + offset)) {
+                return;
+            }
+            sum = (value[x+offset] & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+        while (y > 0) {
+            y--;
+            int bval = y+addend.offset < addend.value.length ? addend.value[y+addend.offset] : 0;
+            sum = (bval & LONG_MASK) + carry;
+            result[rstart--] = (int)sum;
+            carry = sum >>> 32;
+        }
+
+        if (carry > 0) { // Result must grow in length
+            resultLen++;
+            if (result.length < resultLen) {
+                int temp[] = new int[resultLen];
+                // Result one word longer from carry-out; copy low-order
+                // bits into new result.
+                System.arraycopy(result, 0, temp, 1, result.length);
+                temp[0] = 1;
+                result = temp;
+            } else {
+                result[rstart--] = 1;
+            }
+        }
+
+        value = result;
+        intLen = resultLen;
+        offset = result.length - resultLen;
+    }
+
+    /**
+     * Like {@link #addShifted(MutableBigInteger, int)} but {@code this.intLen} must
+     * not be greater than {@code n}. In other words, concatenates {@code this}
+     * and {@code addend}.
+     */
+    void addDisjoint(MutableBigInteger addend, int n) {
+        if (addend.isZero())
+            return;
+
+        int x = intLen;
+        int y = addend.intLen + n;
+        int resultLen = (intLen > y ? intLen : y);
+        int[] result;
+        if (value.length < resultLen)
+            result = new int[resultLen];
+        else {
+            result = value;
+            Arrays.fill(value, offset+intLen, value.length, 0);
+        }
+
+        int rstart = result.length-1;
+
+        // copy from this if needed
+        System.arraycopy(value, offset, result, rstart+1-x, x);
+        y -= x;
+        rstart -= x;
+
+        int len = Math.min(y, addend.value.length-addend.offset);
+        System.arraycopy(addend.value, addend.offset, result, rstart+1-y, len);
+
+        // zero the gap
+        for (int i=rstart+1-y+len; i < rstart+1; i++)
+            result[i] = 0;
+
+        value = result;
+        intLen = resultLen;
+        offset = result.length - resultLen;
+    }
+
+    /**
+     * Adds the low {@code n} ints of {@code addend}.
+     */
+    void addLower(MutableBigInteger addend, int n) {
+        MutableBigInteger a = new MutableBigInteger(addend);
+        if (a.offset + a.intLen >= n) {
+            a.offset = a.offset + a.intLen - n;
+            a.intLen = n;
+        }
+        a.normalize();
+        add(a);
+    }
+
+    /**
+     * Subtracts the smaller of this and b from the larger and places the
+     * result into this MutableBigInteger.
+     */
+    int subtract(MutableBigInteger b) {
+        MutableBigInteger a = this;
+
+        int[] result = value;
+        int sign = a.compare(b);
+
+        if (sign == 0) {
+            reset();
+            return 0;
+        }
+        if (sign < 0) {
+            MutableBigInteger tmp = a;
+            a = b;
+            b = tmp;
+        }
+
+        int resultLen = a.intLen;
+        if (result.length < resultLen)
+            result = new int[resultLen];
+
+        long diff = 0;
+        int x = a.intLen;
+        int y = b.intLen;
+        int rstart = result.length - 1;
+
+        // Subtract common parts of both numbers
+        while (y > 0) {
+            x--; y--;
+
+            diff = (a.value[x+a.offset] & LONG_MASK) -
+                   (b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32));
+            result[rstart--] = (int)diff;
+        }
+        // Subtract remainder of longer number
+        while (x > 0) {
+            x--;
+            diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32));
+            result[rstart--] = (int)diff;
+        }
+
+        value = result;
+        intLen = resultLen;
+        offset = value.length - resultLen;
+        normalize();
+        return sign;
+    }
+
+    /**
+     * Subtracts the smaller of a and b from the larger and places the result
+     * into the larger. Returns 1 if the answer is in a, -1 if in b, 0 if no
+     * operation was performed.
+     */
+    private int difference(MutableBigInteger b) {
+        MutableBigInteger a = this;
+        int sign = a.compare(b);
+        if (sign == 0)
+            return 0;
+        if (sign < 0) {
+            MutableBigInteger tmp = a;
+            a = b;
+            b = tmp;
+        }
+
+        long diff = 0;
+        int x = a.intLen;
+        int y = b.intLen;
+
+        // Subtract common parts of both numbers
+        while (y > 0) {
+            x--; y--;
+            diff = (a.value[a.offset+ x] & LONG_MASK) -
+                (b.value[b.offset+ y] & LONG_MASK) - ((int)-(diff>>32));
+            a.value[a.offset+x] = (int)diff;
+        }
+        // Subtract remainder of longer number
+        while (x > 0) {
+            x--;
+            diff = (a.value[a.offset+ x] & LONG_MASK) - ((int)-(diff>>32));
+            a.value[a.offset+x] = (int)diff;
+        }
+
+        a.normalize();
+        return sign;
+    }
+
+    /**
+     * Multiply the contents of two MutableBigInteger objects. The result is
+     * placed into MutableBigInteger z. The contents of y are not changed.
+     */
+    void multiply(MutableBigInteger y, MutableBigInteger z) {
+        int xLen = intLen;
+        int yLen = y.intLen;
+        int newLen = xLen + yLen;
+
+        // Put z into an appropriate state to receive product
+        if (z.value.length < newLen)
+            z.value = new int[newLen];
+        z.offset = 0;
+        z.intLen = newLen;
+
+        // The first iteration is hoisted out of the loop to avoid extra add
+        long carry = 0;
+        for (int j=yLen-1, k=yLen+xLen-1; j >= 0; j--, k--) {
+                long product = (y.value[j+y.offset] & LONG_MASK) *
+                               (value[xLen-1+offset] & LONG_MASK) + carry;
+                z.value[k] = (int)product;
+                carry = product >>> 32;
+        }
+        z.value[xLen-1] = (int)carry;
+
+        // Perform the multiplication word by word
+        for (int i = xLen-2; i >= 0; i--) {
+            carry = 0;
+            for (int j=yLen-1, k=yLen+i; j >= 0; j--, k--) {
+                long product = (y.value[j+y.offset] & LONG_MASK) *
+                               (value[i+offset] & LONG_MASK) +
+                               (z.value[k] & LONG_MASK) + carry;
+                z.value[k] = (int)product;
+                carry = product >>> 32;
+            }
+            z.value[i] = (int)carry;
+        }
+
+        // Remove leading zeros from product
+        z.normalize();
+    }
+
+    /**
+     * Multiply the contents of this MutableBigInteger by the word y. The
+     * result is placed into z.
+     */
+    void mul(int y, MutableBigInteger z) {
+        if (y == 1) {
+            z.copyValue(this);
+            return;
+        }
+
+        if (y == 0) {
+            z.clear();
+            return;
+        }
+
+        // Perform the multiplication word by word
+        long ylong = y & LONG_MASK;
+        int[] zval = (z.value.length < intLen+1 ? new int[intLen + 1]
+                                              : z.value);
+        long carry = 0;
+        for (int i = intLen-1; i >= 0; i--) {
+            long product = ylong * (value[i+offset] & LONG_MASK) + carry;
+            zval[i+1] = (int)product;
+            carry = product >>> 32;
+        }
+
+        if (carry == 0) {
+            z.offset = 1;
+            z.intLen = intLen;
+        } else {
+            z.offset = 0;
+            z.intLen = intLen + 1;
+            zval[0] = (int)carry;
+        }
+        z.value = zval;
+    }
+
+     /**
+     * This method is used for division of an n word dividend by a one word
+     * divisor. The quotient is placed into quotient. The one word divisor is
+     * specified by divisor.
+     *
+     * @return the remainder of the division is returned.
+     *
+     */
+    int divideOneWord(int divisor, MutableBigInteger quotient) {
+        long divisorLong = divisor & LONG_MASK;
+
+        // Special case of one word dividend
+        if (intLen == 1) {
+            long dividendValue = value[offset] & LONG_MASK;
+            int q = (int) (dividendValue / divisorLong);
+            int r = (int) (dividendValue - q * divisorLong);
+            quotient.value[0] = q;
+            quotient.intLen = (q == 0) ? 0 : 1;
+            quotient.offset = 0;
+            return r;
+        }
+
+        if (quotient.value.length < intLen)
+            quotient.value = new int[intLen];
+        quotient.offset = 0;
+        quotient.intLen = intLen;
+
+        // Normalize the divisor
+        int shift = Integer.numberOfLeadingZeros(divisor);
+
+        int rem = value[offset];
+        long remLong = rem & LONG_MASK;
+        if (remLong < divisorLong) {
+            quotient.value[0] = 0;
+        } else {
+            quotient.value[0] = (int)(remLong / divisorLong);
+            rem = (int) (remLong - (quotient.value[0] * divisorLong));
+            remLong = rem & LONG_MASK;
+        }
+        int xlen = intLen;
+        while (--xlen > 0) {
+            long dividendEstimate = (remLong << 32) |
+                    (value[offset + intLen - xlen] & LONG_MASK);
+            int q;
+            if (dividendEstimate >= 0) {
+                q = (int) (dividendEstimate / divisorLong);
+                rem = (int) (dividendEstimate - q * divisorLong);
+            } else {
+                long tmp = divWord(dividendEstimate, divisor);
+                q = (int) (tmp & LONG_MASK);
+                rem = (int) (tmp >>> 32);
+            }
+            quotient.value[intLen - xlen] = q;
+            remLong = rem & LONG_MASK;
+        }
+
+        quotient.normalize();
+        // Unnormalize
+        if (shift > 0)
+            return rem % divisor;
+        else
+            return rem;
+    }
+
+    /**
+     * Calculates the quotient of this div b and places the quotient in the
+     * provided MutableBigInteger objects and the remainder object is returned.
+     *
+     */
+    MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient) {
+        return divide(b,quotient,true);
+    }
+
+    MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient, boolean needRemainder) {
+        if (b.intLen < BigInteger.BURNIKEL_ZIEGLER_THRESHOLD ||
+                intLen - b.intLen < BigInteger.BURNIKEL_ZIEGLER_OFFSET) {
+            return divideKnuth(b, quotient, needRemainder);
+        } else {
+            return divideAndRemainderBurnikelZiegler(b, quotient);
+        }
+    }
+
+    /**
+     * @see #divideKnuth(MutableBigInteger, MutableBigInteger, boolean)
+     */
+    MutableBigInteger divideKnuth(MutableBigInteger b, MutableBigInteger quotient) {
+        return divideKnuth(b,quotient,true);
+    }
+
+    /**
+     * Calculates the quotient of this div b and places the quotient in the
+     * provided MutableBigInteger objects and the remainder object is returned.
+     *
+     * Uses Algorithm D in Knuth section 4.3.1.
+     * Many optimizations to that algorithm have been adapted from the Colin
+     * Plumb C library.
+     * It special cases one word divisors for speed. The content of b is not
+     * changed.
+     *
+     */
+    MutableBigInteger divideKnuth(MutableBigInteger b, MutableBigInteger quotient, boolean needRemainder) {
+        if (b.intLen == 0)
+            throw new ArithmeticException("BigInteger divide by zero");
+
+        // Dividend is zero
+        if (intLen == 0) {
+            quotient.intLen = quotient.offset = 0;
+            return needRemainder ? new MutableBigInteger() : null;
+        }
+
+        int cmp = compare(b);
+        // Dividend less than divisor
+        if (cmp < 0) {
+            quotient.intLen = quotient.offset = 0;
+            return needRemainder ? new MutableBigInteger(this) : null;
+        }
+        // Dividend equal to divisor
+        if (cmp == 0) {
+            quotient.value[0] = quotient.intLen = 1;
+            quotient.offset = 0;
+            return needRemainder ? new MutableBigInteger() : null;
+        }
+
+        quotient.clear();
+        // Special case one word divisor
+        if (b.intLen == 1) {
+            int r = divideOneWord(b.value[b.offset], quotient);
+            if(needRemainder) {
+                if (r == 0)
+                    return new MutableBigInteger();
+                return new MutableBigInteger(r);
+            } else {
+                return null;
+            }
+        }
+
+        // Cancel common powers of two if we're above the KNUTH_POW2_* thresholds
+        if (intLen >= KNUTH_POW2_THRESH_LEN) {
+            int trailingZeroBits = Math.min(getLowestSetBit(), b.getLowestSetBit());
+            if (trailingZeroBits >= KNUTH_POW2_THRESH_ZEROS*32) {
+                MutableBigInteger a = new MutableBigInteger(this);
+                b = new MutableBigInteger(b);
+                a.rightShift(trailingZeroBits);
+                b.rightShift(trailingZeroBits);
+                MutableBigInteger r = a.divideKnuth(b, quotient);
+                r.leftShift(trailingZeroBits);
+                return r;
+            }
+        }
+
+        return divideMagnitude(b, quotient, needRemainder);
+    }
+
+    /**
+     * Computes {@code this/b} and {@code this%b} using the
+     * <a href="http://cr.yp.to/bib/1998/burnikel.ps"> Burnikel-Ziegler algorithm</a>.
+     * This method implements algorithm 3 from pg. 9 of the Burnikel-Ziegler paper.
+     * The parameter beta was chosen to b 2<sup>32</sup> so almost all shifts are
+     * multiples of 32 bits.<br/>
+     * {@code this} and {@code b} must be nonnegative.
+     * @param b the divisor
+     * @param quotient output parameter for {@code this/b}
+     * @return the remainder
+     */
+    MutableBigInteger divideAndRemainderBurnikelZiegler(MutableBigInteger b, MutableBigInteger quotient) {
+        int r = intLen;
+        int s = b.intLen;
+
+        // Clear the quotient
+        quotient.offset = quotient.intLen = 0;
+
+        if (r < s) {
+            return this;
+        } else {
+            // Unlike Knuth division, we don't check for common powers of two here because
+            // BZ already runs faster if both numbers contain powers of two and cancelling them has no
+            // additional benefit.
+
+            // step 1: let m = min{2^k | (2^k)*BURNIKEL_ZIEGLER_THRESHOLD > s}
+            int m = 1 << (32-Integer.numberOfLeadingZeros(s/BigInteger.BURNIKEL_ZIEGLER_THRESHOLD));
+
+            int j = (s+m-1) / m;      // step 2a: j = ceil(s/m)
+            int n = j * m;            // step 2b: block length in 32-bit units
+            long n32 = 32L * n;         // block length in bits
+            int sigma = (int) Math.max(0, n32 - b.bitLength());   // step 3: sigma = max{T | (2^T)*B < beta^n}
+            MutableBigInteger bShifted = new MutableBigInteger(b);
+            bShifted.safeLeftShift(sigma);   // step 4a: shift b so its length is a multiple of n
+            MutableBigInteger aShifted = new MutableBigInteger (this);
+            aShifted.safeLeftShift(sigma);     // step 4b: shift a by the same amount
+
+            // step 5: t is the number of blocks needed to accommodate a plus one additional bit
+            int t = (int) ((aShifted.bitLength()+n32) / n32);
+            if (t < 2) {
+                t = 2;
+            }
+
+            // step 6: conceptually split a into blocks a[t-1], ..., a[0]
+            MutableBigInteger a1 = aShifted.getBlock(t-1, t, n);   // the most significant block of a
+
+            // step 7: z[t-2] = [a[t-1], a[t-2]]
+            MutableBigInteger z = aShifted.getBlock(t-2, t, n);    // the second to most significant block
+            z.addDisjoint(a1, n);   // z[t-2]
+
+            // do schoolbook division on blocks, dividing 2-block numbers by 1-block numbers
+            MutableBigInteger qi = new MutableBigInteger();
+            MutableBigInteger ri;
+            for (int i=t-2; i > 0; i--) {
+                // step 8a: compute (qi,ri) such that z=b*qi+ri
+                ri = z.divide2n1n(bShifted, qi);
+
+                // step 8b: z = [ri, a[i-1]]
+                z = aShifted.getBlock(i-1, t, n);   // a[i-1]
+                z.addDisjoint(ri, n);
+                quotient.addShifted(qi, i*n);   // update q (part of step 9)
+            }
+            // final iteration of step 8: do the loop one more time for i=0 but leave z unchanged
+            ri = z.divide2n1n(bShifted, qi);
+            quotient.add(qi);
+
+            ri.rightShift(sigma);   // step 9: a and b were shifted, so shift back
+            return ri;
+        }
+    }
+
+    /**
+     * This method implements algorithm 1 from pg. 4 of the Burnikel-Ziegler paper.
+     * It divides a 2n-digit number by a n-digit number.<br/>
+     * The parameter beta is 2<sup>32</sup> so all shifts are multiples of 32 bits.
+     * <br/>
+     * {@code this} must be a nonnegative number such that {@code this.bitLength() <= 2*b.bitLength()}
+     * @param b a positive number such that {@code b.bitLength()} is even
+     * @param quotient output parameter for {@code this/b}
+     * @return {@code this%b}
+     */
+    private MutableBigInteger divide2n1n(MutableBigInteger b, MutableBigInteger quotient) {
+        int n = b.intLen;
+
+        // step 1: base case
+        if (n%2 != 0 || n < BigInteger.BURNIKEL_ZIEGLER_THRESHOLD) {
+            return divideKnuth(b, quotient);
+        }
+
+        // step 2: view this as [a1,a2,a3,a4] where each ai is n/2 ints or less
+        MutableBigInteger aUpper = new MutableBigInteger(this);
+        aUpper.safeRightShift(32*(n/2));   // aUpper = [a1,a2,a3]
+        keepLower(n/2);   // this = a4
+
+        // step 3: q1=aUpper/b, r1=aUpper%b
+        MutableBigInteger q1 = new MutableBigInteger();
+        MutableBigInteger r1 = aUpper.divide3n2n(b, q1);
+
+        // step 4: quotient=[r1,this]/b, r2=[r1,this]%b
+        addDisjoint(r1, n/2);   // this = [r1,this]
+        MutableBigInteger r2 = divide3n2n(b, quotient);
+
+        // step 5: let quotient=[q1,quotient] and return r2
+        quotient.addDisjoint(q1, n/2);
+        return r2;
+    }
+
+    /**
+     * This method implements algorithm 2 from pg. 5 of the Burnikel-Ziegler paper.
+     * It divides a 3n-digit number by a 2n-digit number.<br/>
+     * The parameter beta is 2<sup>32</sup> so all shifts are multiples of 32 bits.<br/>
+     * <br/>
+     * {@code this} must be a nonnegative number such that {@code 2*this.bitLength() <= 3*b.bitLength()}
+     * @param quotient output parameter for {@code this/b}
+     * @return {@code this%b}
+     */
+    private MutableBigInteger divide3n2n(MutableBigInteger b, MutableBigInteger quotient) {
+        int n = b.intLen / 2;   // half the length of b in ints
+
+        // step 1: view this as [a1,a2,a3] where each ai is n ints or less; let a12=[a1,a2]
+        MutableBigInteger a12 = new MutableBigInteger(this);
+        a12.safeRightShift(32*n);
+
+        // step 2: view b as [b1,b2] where each bi is n ints or less
+        MutableBigInteger b1 = new MutableBigInteger(b);
+        b1.safeRightShift(n * 32);
+        BigInteger b2 = b.getLower(n);
+
+        MutableBigInteger r;
+        MutableBigInteger d;
+        if (compareShifted(b, n) < 0) {
+            // step 3a: if a1<b1, let quotient=a12/b1 and r=a12%b1
+            r = a12.divide2n1n(b1, quotient);
+
+            // step 4: d=quotient*b2
+            d = new MutableBigInteger(quotient.toBigInteger().multiply(b2));
+        } else {
+            // step 3b: if a1>=b1, let quotient=beta^n-1 and r=a12-b1*2^n+b1
+            quotient.ones(n);
+            a12.add(b1);
+            b1.leftShift(32*n);
+            a12.subtract(b1);
+            r = a12;
+
+            // step 4: d=quotient*b2=(b2 << 32*n) - b2
+            d = new MutableBigInteger(b2);
+            d.leftShift(32 * n);
+            d.subtract(new MutableBigInteger(b2));
+        }
+
+        // step 5: r = r*beta^n + a3 - d (paper says a4)
+        // However, don't subtract d until after the while loop so r doesn't become negative
+        r.leftShift(32 * n);
+        r.addLower(this, n);
+
+        // step 6: add b until r>=d
+        while (r.compare(d) < 0) {
+            r.add(b);
+            quotient.subtract(MutableBigInteger.ONE);
+        }
+        r.subtract(d);
+
+        return r;
+    }
+
+    /**
+     * Returns a {@code MutableBigInteger} containing {@code blockLength} ints from
+     * {@code this} number, starting at {@code index*blockLength}.<br/>
+     * Used by Burnikel-Ziegler division.
+     * @param index the block index
+     * @param numBlocks the total number of blocks in {@code this} number
+     * @param blockLength length of one block in units of 32 bits
+     * @return
+     */
+    private MutableBigInteger getBlock(int index, int numBlocks, int blockLength) {
+        int blockStart = index * blockLength;
+        if (blockStart >= intLen) {
+            return new MutableBigInteger();
+        }
+
+        int blockEnd;
+        if (index == numBlocks-1) {
+            blockEnd = intLen;
+        } else {
+            blockEnd = (index+1) * blockLength;
+        }
+        if (blockEnd > intLen) {
+            return new MutableBigInteger();
+        }
+
+        int[] newVal = Arrays.copyOfRange(value, offset+intLen-blockEnd, offset+intLen-blockStart);
+        return new MutableBigInteger(newVal);
+    }
+
+    /** @see BigInteger#bitLength() */
+    long bitLength() {
+        if (intLen == 0)
+            return 0;
+        return intLen*32L - Integer.numberOfLeadingZeros(value[offset]);
+    }
+
+    /**
+     * Internally used  to calculate the quotient of this div v and places the
+     * quotient in the provided MutableBigInteger object and the remainder is
+     * returned.
+     *
+     * @return the remainder of the division will be returned.
+     */
+    long divide(long v, MutableBigInteger quotient) {
+        if (v == 0)
+            throw new ArithmeticException("BigInteger divide by zero");
+
+        // Dividend is zero
+        if (intLen == 0) {
+            quotient.intLen = quotient.offset = 0;
+            return 0;
+        }
+        if (v < 0)
+            v = -v;
+
+        int d = (int)(v >>> 32);
+        quotient.clear();
+        // Special case on word divisor
+        if (d == 0)
+            return divideOneWord((int)v, quotient) & LONG_MASK;
+        else {
+            return divideLongMagnitude(v, quotient).toLong();
+        }
+    }
+
+    private static void copyAndShift(int[] src, int srcFrom, int srcLen, int[] dst, int dstFrom, int shift) {
+        int n2 = 32 - shift;
+        int c=src[srcFrom];
+        for (int i=0; i < srcLen-1; i++) {
+            int b = c;
+            c = src[++srcFrom];
+            dst[dstFrom+i] = (b << shift) | (c >>> n2);
+        }
+        dst[dstFrom+srcLen-1] = c << shift;
+    }
+
+    /**
+     * Divide this MutableBigInteger by the divisor.
+     * The quotient will be placed into the provided quotient object &
+     * the remainder object is returned.
+     */
+    private MutableBigInteger divideMagnitude(MutableBigInteger div,
+                                              MutableBigInteger quotient,
+                                              boolean needRemainder ) {
+        // assert div.intLen > 1
+        // D1 normalize the divisor
+        int shift = Integer.numberOfLeadingZeros(div.value[div.offset]);
+        // Copy divisor value to protect divisor
+        final int dlen = div.intLen;
+        int[] divisor;
+        MutableBigInteger rem; // Remainder starts as dividend with space for a leading zero
+        if (shift > 0) {
+            divisor = new int[dlen];
+            copyAndShift(div.value,div.offset,dlen,divisor,0,shift);
+            if (Integer.numberOfLeadingZeros(value[offset]) >= shift) {
+                int[] remarr = new int[intLen + 1];
+                rem = new MutableBigInteger(remarr);
+                rem.intLen = intLen;
+                rem.offset = 1;
+                copyAndShift(value,offset,intLen,remarr,1,shift);
+            } else {
+                int[] remarr = new int[intLen + 2];
+                rem = new MutableBigInteger(remarr);
+                rem.intLen = intLen+1;
+                rem.offset = 1;
+                int rFrom = offset;
+                int c=0;
+                int n2 = 32 - shift;
+                for (int i=1; i < intLen+1; i++,rFrom++) {
+                    int b = c;
+                    c = value[rFrom];
+                    remarr[i] = (b << shift) | (c >>> n2);
+                }
+                remarr[intLen+1] = c << shift;
+            }
+        } else {
+            divisor = Arrays.copyOfRange(div.value, div.offset, div.offset + div.intLen);
+            rem = new MutableBigInteger(new int[intLen + 1]);
+            System.arraycopy(value, offset, rem.value, 1, intLen);
+            rem.intLen = intLen;
+            rem.offset = 1;
+        }
+
+        int nlen = rem.intLen;
+
+        // Set the quotient size
+        final int limit = nlen - dlen + 1;
+        if (quotient.value.length < limit) {
+            quotient.value = new int[limit];
+            quotient.offset = 0;
+        }
+        quotient.intLen = limit;
+        int[] q = quotient.value;
+
+
+        // Must insert leading 0 in rem if its length did not change
+        if (rem.intLen == nlen) {
+            rem.offset = 0;
+            rem.value[0] = 0;
+            rem.intLen++;
+        }
+
+        int dh = divisor[0];
+        long dhLong = dh & LONG_MASK;
+        int dl = divisor[1];
+
+        // D2 Initialize j
+        for (int j=0; j < limit-1; j++) {
+            // D3 Calculate qhat
+            // estimate qhat
+            int qhat = 0;
+            int qrem = 0;
+            boolean skipCorrection = false;
+            int nh = rem.value[j+rem.offset];
+            int nh2 = nh + 0x80000000;
+            int nm = rem.value[j+1+rem.offset];
+
+            if (nh == dh) {
+                qhat = ~0;
+                qrem = nh + nm;
+                skipCorrection = qrem + 0x80000000 < nh2;
+            } else {
+                long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
+                if (nChunk >= 0) {
+                    qhat = (int) (nChunk / dhLong);
+                    qrem = (int) (nChunk - (qhat * dhLong));
+                } else {
+                    long tmp = divWord(nChunk, dh);
+                    qhat = (int) (tmp & LONG_MASK);
+                    qrem = (int) (tmp >>> 32);
+                }
+            }
+
+            if (qhat == 0)
+                continue;
+
+            if (!skipCorrection) { // Correct qhat
+                long nl = rem.value[j+2+rem.offset] & LONG_MASK;
+                long rs = ((qrem & LONG_MASK) << 32) | nl;
+                long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
+
+                if (unsignedLongCompare(estProduct, rs)) {
+                    qhat--;
+                    qrem = (int)((qrem & LONG_MASK) + dhLong);
+                    if ((qrem & LONG_MASK) >=  dhLong) {
+                        estProduct -= (dl & LONG_MASK);
+                        rs = ((qrem & LONG_MASK) << 32) | nl;
+                        if (unsignedLongCompare(estProduct, rs))
+                            qhat--;
+                    }
+                }
+            }
+
+            // D4 Multiply and subtract
+            rem.value[j+rem.offset] = 0;
+            int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset);
+
+            // D5 Test remainder
+            if (borrow + 0x80000000 > nh2) {
+                // D6 Add back
+                divadd(divisor, rem.value, j+1+rem.offset);
+                qhat--;
+            }
+
+            // Store the quotient digit
+            q[j] = qhat;
+        } // D7 loop on j
+        // D3 Calculate qhat
+        // estimate qhat
+        int qhat = 0;
+        int qrem = 0;
+        boolean skipCorrection = false;
+        int nh = rem.value[limit - 1 + rem.offset];
+        int nh2 = nh + 0x80000000;
+        int nm = rem.value[limit + rem.offset];
+
+        if (nh == dh) {
+            qhat = ~0;
+            qrem = nh + nm;
+            skipCorrection = qrem + 0x80000000 < nh2;
+        } else {
+            long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
+            if (nChunk >= 0) {
+                qhat = (int) (nChunk / dhLong);
+                qrem = (int) (nChunk - (qhat * dhLong));
+            } else {
+                long tmp = divWord(nChunk, dh);
+                qhat = (int) (tmp & LONG_MASK);
+                qrem = (int) (tmp >>> 32);
+            }
+        }
+        if (qhat != 0) {
+            if (!skipCorrection) { // Correct qhat
+                long nl = rem.value[limit + 1 + rem.offset] & LONG_MASK;
+                long rs = ((qrem & LONG_MASK) << 32) | nl;
+                long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
+
+                if (unsignedLongCompare(estProduct, rs)) {
+                    qhat--;
+                    qrem = (int) ((qrem & LONG_MASK) + dhLong);
+                    if ((qrem & LONG_MASK) >= dhLong) {
+                        estProduct -= (dl & LONG_MASK);
+                        rs = ((qrem & LONG_MASK) << 32) | nl;
+                        if (unsignedLongCompare(estProduct, rs))
+                            qhat--;
+                    }
+                }
+            }
+
+
+            // D4 Multiply and subtract
+            int borrow;
+            rem.value[limit - 1 + rem.offset] = 0;
+            if(needRemainder)
+                borrow = mulsub(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
+            else
+                borrow = mulsubBorrow(rem.value, divisor, qhat, dlen, limit - 1 + rem.offset);
+
+            // D5 Test remainder
+            if (borrow + 0x80000000 > nh2) {
+                // D6 Add back
+                if(needRemainder)
+                    divadd(divisor, rem.value, limit - 1 + 1 + rem.offset);
+                qhat--;
+            }
+
+            // Store the quotient digit
+            q[(limit - 1)] = qhat;
+        }
+
+
+        if (needRemainder) {
+            // D8 Unnormalize
+            if (shift > 0)
+                rem.rightShift(shift);
+            rem.normalize();
+        }
+        quotient.normalize();
+        return needRemainder ? rem : null;
+    }
+
+    /**
+     * Divide this MutableBigInteger by the divisor represented by positive long
+     * value. The quotient will be placed into the provided quotient object &
+     * the remainder object is returned.
+     */
+    private MutableBigInteger divideLongMagnitude(long ldivisor, MutableBigInteger quotient) {
+        // Remainder starts as dividend with space for a leading zero
+        MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]);
+        System.arraycopy(value, offset, rem.value, 1, intLen);
+        rem.intLen = intLen;
+        rem.offset = 1;
+
+        int nlen = rem.intLen;
+
+        int limit = nlen - 2 + 1;
+        if (quotient.value.length < limit) {
+            quotient.value = new int[limit];
+            quotient.offset = 0;
+        }
+        quotient.intLen = limit;
+        int[] q = quotient.value;
+
+        // D1 normalize the divisor
+        int shift = Long.numberOfLeadingZeros(ldivisor);
+        if (shift > 0) {
+            ldivisor<<=shift;
+            rem.leftShift(shift);
+        }
+
+        // Must insert leading 0 in rem if its length did not change
+        if (rem.intLen == nlen) {
+            rem.offset = 0;
+            rem.value[0] = 0;
+            rem.intLen++;
+        }
+
+        int dh = (int)(ldivisor >>> 32);
+        long dhLong = dh & LONG_MASK;
+        int dl = (int)(ldivisor & LONG_MASK);
+
+        // D2 Initialize j
+        for (int j = 0; j < limit; j++) {
+            // D3 Calculate qhat
+            // estimate qhat
+            int qhat = 0;
+            int qrem = 0;
+            boolean skipCorrection = false;
+            int nh = rem.value[j + rem.offset];
+            int nh2 = nh + 0x80000000;
+            int nm = rem.value[j + 1 + rem.offset];
+
+            if (nh == dh) {
+                qhat = ~0;
+                qrem = nh + nm;
+                skipCorrection = qrem + 0x80000000 < nh2;
+            } else {
+                long nChunk = (((long) nh) << 32) | (nm & LONG_MASK);
+                if (nChunk >= 0) {
+                    qhat = (int) (nChunk / dhLong);
+                    qrem = (int) (nChunk - (qhat * dhLong));
+                } else {
+                    long tmp = divWord(nChunk, dh);
+                    qhat =(int)(tmp & LONG_MASK);
+                    qrem = (int)(tmp>>>32);
+                }
+            }
+
+            if (qhat == 0)
+                continue;
+
+            if (!skipCorrection) { // Correct qhat
+                long nl = rem.value[j + 2 + rem.offset] & LONG_MASK;
+                long rs = ((qrem & LONG_MASK) << 32) | nl;
+                long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
+
+                if (unsignedLongCompare(estProduct, rs)) {
+                    qhat--;
+                    qrem = (int) ((qrem & LONG_MASK) + dhLong);
+                    if ((qrem & LONG_MASK) >= dhLong) {
+                        estProduct -= (dl & LONG_MASK);
+                        rs = ((qrem & LONG_MASK) << 32) | nl;
+                        if (unsignedLongCompare(estProduct, rs))
+                            qhat--;
+                    }
+                }
+            }
+
+            // D4 Multiply and subtract
+            rem.value[j + rem.offset] = 0;
+            int borrow = mulsubLong(rem.value, dh, dl, qhat,  j + rem.offset);
+
+            // D5 Test remainder
+            if (borrow + 0x80000000 > nh2) {
+                // D6 Add back
+                divaddLong(dh,dl, rem.value, j + 1 + rem.offset);
+                qhat--;
+            }
+
+            // Store the quotient digit
+            q[j] = qhat;
+        } // D7 loop on j
+
+        // D8 Unnormalize
+        if (shift > 0)
+            rem.rightShift(shift);
+
+        quotient.normalize();
+        rem.normalize();
+        return rem;
+    }
+
+    /**
+     * A primitive used for division by long.
+     * Specialized version of the method divadd.
+     * dh is a high part of the divisor, dl is a low part
+     */
+    private int divaddLong(int dh, int dl, int[] result, int offset) {
+        long carry = 0;
+
+        long sum = (dl & LONG_MASK) + (result[1+offset] & LONG_MASK);
+        result[1+offset] = (int)sum;
+
+        sum = (dh & LONG_MASK) + (result[offset] & LONG_MASK) + carry;
+        result[offset] = (int)sum;
+        carry = sum >>> 32;
+        return (int)carry;
+    }
+
+    /**
+     * This method is used for division by long.
+     * Specialized version of the method sulsub.
+     * dh is a high part of the divisor, dl is a low part
+     */
+    private int mulsubLong(int[] q, int dh, int dl, int x, int offset) {
+        long xLong = x & LONG_MASK;
+        offset += 2;
+        long product = (dl & LONG_MASK) * xLong;
+        long difference = q[offset] - product;
+        q[offset--] = (int)difference;
+        long carry = (product >>> 32)
+                 + (((difference & LONG_MASK) >
+                     (((~(int)product) & LONG_MASK))) ? 1:0);
+        product = (dh & LONG_MASK) * xLong + carry;
+        difference = q[offset] - product;
+        q[offset--] = (int)difference;
+        carry = (product >>> 32)
+                 + (((difference & LONG_MASK) >
+                     (((~(int)product) & LONG_MASK))) ? 1:0);
+        return (int)carry;
+    }
+
+    /**
+     * Compare two longs as if they were unsigned.
+     * Returns true iff one is bigger than two.
+     */
+    private boolean unsignedLongCompare(long one, long two) {
+        return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
+    }
+
+    /**
+     * This method divides a long quantity by an int to estimate
+     * qhat for two multi precision numbers. It is used when
+     * the signed value of n is less than zero.
+     * Returns long value where high 32 bits contain remainder value and
+     * low 32 bits contain quotient value.
+     */
+    static long divWord(long n, int d) {
+        long dLong = d & LONG_MASK;
+        long r;
+        long q;
+        if (dLong == 1) {
+            q = (int)n;
+            r = 0;
+            return (r << 32) | (q & LONG_MASK);
+        }
+
+        // Approximate the quotient and remainder
+        q = (n >>> 1) / (dLong >>> 1);
+        r = n - q*dLong;
+
+        // Correct the approximation
+        while (r < 0) {
+            r += dLong;
+            q--;
+        }
+        while (r >= dLong) {
+            r -= dLong;
+            q++;
+        }
+        // n - q*dlong == r && 0 <= r <dLong, hence we're done.
+        return (r << 32) | (q & LONG_MASK);
+    }
+
+    /**
+     * Calculate GCD of this and b. This and b are changed by the computation.
+     */
+    MutableBigInteger hybridGCD(MutableBigInteger b) {
+        // Use Euclid's algorithm until the numbers are approximately the
+        // same length, then use the binary GCD algorithm to find the GCD.
+        MutableBigInteger a = this;
+        MutableBigInteger q = new MutableBigInteger();
+
+        while (b.intLen != 0) {
+            if (Math.abs(a.intLen - b.intLen) < 2)
+                return a.binaryGCD(b);
+
+            MutableBigInteger r = a.divide(b, q);
+            a = b;
+            b = r;
+        }
+        return a;
+    }
+
+    /**
+     * Calculate GCD of this and v.
+     * Assumes that this and v are not zero.
+     */
+    private MutableBigInteger binaryGCD(MutableBigInteger v) {
+        // Algorithm B from Knuth section 4.5.2
+        MutableBigInteger u = this;
+        MutableBigInteger r = new MutableBigInteger();
+
+        // step B1
+        int s1 = u.getLowestSetBit();
+        int s2 = v.getLowestSetBit();
+        int k = (s1 < s2) ? s1 : s2;
+        if (k != 0) {
+            u.rightShift(k);
+            v.rightShift(k);
+        }
+
+        // step B2
+        boolean uOdd = (k == s1);
+        MutableBigInteger t = uOdd ? v: u;
+        int tsign = uOdd ? -1 : 1;
+
+        int lb;
+        while ((lb = t.getLowestSetBit()) >= 0) {
+            // steps B3 and B4
+            t.rightShift(lb);
+            // step B5
+            if (tsign > 0)
+                u = t;
+            else
+                v = t;
+
+            // Special case one word numbers
+            if (u.intLen < 2 && v.intLen < 2) {
+                int x = u.value[u.offset];
+                int y = v.value[v.offset];
+                x  = binaryGcd(x, y);
+                r.value[0] = x;
+                r.intLen = 1;
+                r.offset = 0;
+                if (k > 0)
+                    r.leftShift(k);
+                return r;
+            }
+
+            // step B6
+            if ((tsign = u.difference(v)) == 0)
+                break;
+            t = (tsign >= 0) ? u : v;
+        }
+
+        if (k > 0)
+            u.leftShift(k);
+        return u;
+    }
+
+    /**
+     * Calculate GCD of a and b interpreted as unsigned integers.
+     */
+    static int binaryGcd(int a, int b) {
+        if (b == 0)
+            return a;
+        if (a == 0)
+            return b;
+
+        // Right shift a & b till their last bits equal to 1.
+        int aZeros = Integer.numberOfTrailingZeros(a);
+        int bZeros = Integer.numberOfTrailingZeros(b);
+        a >>>= aZeros;
+        b >>>= bZeros;
+
+        int t = (aZeros < bZeros ? aZeros : bZeros);
+
+        while (a != b) {
+            if ((a+0x80000000) > (b+0x80000000)) {  // a > b as unsigned
+                a -= b;
+                a >>>= Integer.numberOfTrailingZeros(a);
+            } else {
+                b -= a;
+                b >>>= Integer.numberOfTrailingZeros(b);
+            }
+        }
+        return a<<t;
+    }
+
+    /**
+     * Returns the modInverse of this mod p. This and p are not affected by
+     * the operation.
+     */
+    MutableBigInteger mutableModInverse(MutableBigInteger p) {
+        // Modulus is odd, use Schroeppel's algorithm
+        if (p.isOdd())
+            return modInverse(p);
+
+        // Base and modulus are even, throw exception
+        if (isEven())
+            throw new ArithmeticException("BigInteger not invertible.");
+
+        // Get even part of modulus expressed as a power of 2
+        int powersOf2 = p.getLowestSetBit();
+
+        // Construct odd part of modulus
+        MutableBigInteger oddMod = new MutableBigInteger(p);
+        oddMod.rightShift(powersOf2);
+
+        if (oddMod.isOne())
+            return modInverseMP2(powersOf2);
+
+        // Calculate 1/a mod oddMod
+        MutableBigInteger oddPart = modInverse(oddMod);
+
+        // Calculate 1/a mod evenMod
+        MutableBigInteger evenPart = modInverseMP2(powersOf2);
+
+        // Combine the results using Chinese Remainder Theorem
+        MutableBigInteger y1 = modInverseBP2(oddMod, powersOf2);
+        MutableBigInteger y2 = oddMod.modInverseMP2(powersOf2);
+
+        MutableBigInteger temp1 = new MutableBigInteger();
+        MutableBigInteger temp2 = new MutableBigInteger();
+        MutableBigInteger result = new MutableBigInteger();
+
+        oddPart.leftShift(powersOf2);
+        oddPart.multiply(y1, result);
+
+        evenPart.multiply(oddMod, temp1);
+        temp1.multiply(y2, temp2);
+
+        result.add(temp2);
+        return result.divide(p, temp1);
+    }
+
+    /*
+     * Calculate the multiplicative inverse of this mod 2^k.
+     */
+    MutableBigInteger modInverseMP2(int k) {
+        if (isEven())
+            throw new ArithmeticException("Non-invertible. (GCD != 1)");
+
+        if (k > 64)
+            return euclidModInverse(k);
+
+        int t = inverseMod32(value[offset+intLen-1]);
+
+        if (k < 33) {
+            t = (k == 32 ? t : t & ((1 << k) - 1));
+            return new MutableBigInteger(t);
+        }
+
+        long pLong = (value[offset+intLen-1] & LONG_MASK);
+        if (intLen > 1)
+            pLong |=  ((long)value[offset+intLen-2] << 32);
+        long tLong = t & LONG_MASK;
+        tLong = tLong * (2 - pLong * tLong);  // 1 more Newton iter step
+        tLong = (k == 64 ? tLong : tLong & ((1L << k) - 1));
+
+        MutableBigInteger result = new MutableBigInteger(new int[2]);
+        result.value[0] = (int)(tLong >>> 32);
+        result.value[1] = (int)tLong;
+        result.intLen = 2;
+        result.normalize();
+        return result;
+    }
+
+    /**
+     * Returns the multiplicative inverse of val mod 2^32.  Assumes val is odd.
+     */
+    static int inverseMod32(int val) {
+        // Newton's iteration!
+        int t = val;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        return t;
+    }
+
+    /**
+     * Returns the multiplicative inverse of val mod 2^64.  Assumes val is odd.
+     */
+    static long inverseMod64(long val) {
+        // Newton's iteration!
+        long t = val;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        t *= 2 - val*t;
+        assert(t * val == 1);
+        return t;
+    }
+
+    /**
+     * Calculate the multiplicative inverse of 2^k mod mod, where mod is odd.
+     */
+    static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) {
+        // Copy the mod to protect original
+        return fixup(new MutableBigInteger(1), new MutableBigInteger(mod), k);
+    }
+
+    /**
+     * Calculate the multiplicative inverse of this modulo mod, where the mod
+     * argument is odd.  This and mod are not changed by the calculation.
+     *
+     * This method implements an algorithm due to Richard Schroeppel, that uses
+     * the same intermediate representation as Montgomery Reduction
+     * ("Montgomery Form").  The algorithm is described in an unpublished
+     * manuscript entitled "Fast Modular Reciprocals."
+     */
+    private MutableBigInteger modInverse(MutableBigInteger mod) {
+        MutableBigInteger p = new MutableBigInteger(mod);
+        MutableBigInteger f = new MutableBigInteger(this);
+        MutableBigInteger g = new MutableBigInteger(p);
+        SignedMutableBigInteger c = new SignedMutableBigInteger(1);
+        SignedMutableBigInteger d = new SignedMutableBigInteger();
+        MutableBigInteger temp = null;
+        SignedMutableBigInteger sTemp = null;
+
+        int k = 0;
+        // Right shift f k times until odd, left shift d k times
+        if (f.isEven()) {
+            int trailingZeros = f.getLowestSetBit();
+            f.rightShift(trailingZeros);
+            d.leftShift(trailingZeros);
+            k = trailingZeros;
+        }
+
+        // The Almost Inverse Algorithm
+        while (!f.isOne()) {
+            // If gcd(f, g) != 1, number is not invertible modulo mod
+            if (f.isZero())
+                throw new ArithmeticException("BigInteger not invertible.");
+
+            // If f < g exchange f, g and c, d
+            if (f.compare(g) < 0) {
+                temp = f; f = g; g = temp;
+                sTemp = d; d = c; c = sTemp;
+            }
+
+            // If f == g (mod 4)
+            if (((f.value[f.offset + f.intLen - 1] ^
+                 g.value[g.offset + g.intLen - 1]) & 3) == 0) {
+                f.subtract(g);
+                c.signedSubtract(d);
+            } else { // If f != g (mod 4)
+                f.add(g);
+                c.signedAdd(d);
+            }
+
+            // Right shift f k times until odd, left shift d k times
+            int trailingZeros = f.getLowestSetBit();
+            f.rightShift(trailingZeros);
+            d.leftShift(trailingZeros);
+            k += trailingZeros;
+        }
+
+        if (c.compare(p) >= 0) { // c has a larger magnitude than p
+            MutableBigInteger remainder = c.divide(p,
+                new MutableBigInteger());
+            // The previous line ignores the sign so we copy the data back
+            // into c which will restore the sign as needed (and converts
+            // it back to a SignedMutableBigInteger)
+            c.copyValue(remainder);
+        }
+
+        if (c.sign < 0) {
+            c.signedAdd(p);
+        }
+
+        return fixup(c, p, k);
+    }
+
+    /**
+     * The Fixup Algorithm
+     * Calculates X such that X = C * 2^(-k) (mod P)
+     * Assumes C<P and P is odd.
+     */
+    static MutableBigInteger fixup(MutableBigInteger c, MutableBigInteger p,
+                                                                      int k) {
+        MutableBigInteger temp = new MutableBigInteger();
+        // Set r to the multiplicative inverse of p mod 2^32
+        int r = -inverseMod32(p.value[p.offset+p.intLen-1]);
+
+        for (int i=0, numWords = k >> 5; i < numWords; i++) {
+            // V = R * c (mod 2^j)
+            int  v = r * c.value[c.offset + c.intLen-1];
+            // c = c + (v * p)
+            p.mul(v, temp);
+            c.add(temp);
+            // c = c / 2^j
+            c.intLen--;
+        }
+        int numBits = k & 0x1f;
+        if (numBits != 0) {
+            // V = R * c (mod 2^j)
+            int v = r * c.value[c.offset + c.intLen-1];
+            v &= ((1<<numBits) - 1);
+            // c = c + (v * p)
+            p.mul(v, temp);
+            c.add(temp);
+            // c = c / 2^j
+            c.rightShift(numBits);
+        }
+
+        // In theory, c may be greater than p at this point (Very rare!)
+        if (c.compare(p) >= 0)
+            c = c.divide(p, new MutableBigInteger());
+
+        return c;
+    }
+
+    /**
+     * Uses the extended Euclidean algorithm to compute the modInverse of base
+     * mod a modulus that is a power of 2. The modulus is 2^k.
+     */
+    MutableBigInteger euclidModInverse(int k) {
+        MutableBigInteger b = new MutableBigInteger(1);
+        b.leftShift(k);
+        MutableBigInteger mod = new MutableBigInteger(b);
+
+        MutableBigInteger a = new MutableBigInteger(this);
+        MutableBigInteger q = new MutableBigInteger();
+        MutableBigInteger r = b.divide(a, q);
+
+        MutableBigInteger swapper = b;
+        // swap b & r
+        b = r;
+        r = swapper;
+
+        MutableBigInteger t1 = new MutableBigInteger(q);
+        MutableBigInteger t0 = new MutableBigInteger(1);
+        MutableBigInteger temp = new MutableBigInteger();
+
+        while (!b.isOne()) {
+            r = a.divide(b, q);
+
+            if (r.intLen == 0)
+                throw new ArithmeticException("BigInteger not invertible.");
+
+            swapper = r;
+            a = swapper;
+
+            if (q.intLen == 1)
+                t1.mul(q.value[q.offset], temp);
+            else
+                q.multiply(t1, temp);
+            swapper = q;
+            q = temp;
+            temp = swapper;
+            t0.add(q);
+
+            if (a.isOne())
+                return t0;
+
+            r = b.divide(a, q);
+
+            if (r.intLen == 0)
+                throw new ArithmeticException("BigInteger not invertible.");
+
+            swapper = b;
+            b =  r;
+
+            if (q.intLen == 1)
+                t0.mul(q.value[q.offset], temp);
+            else
+                q.multiply(t0, temp);
+            swapper = q; q = temp; temp = swapper;
+
+            t1.add(q);
+        }
+        mod.subtract(t1);
+        return mod;
+    }
+}
diff --git a/ojluni/src/main/java/java/math/RoundingMode.java b/ojluni/src/main/java/java/math/RoundingMode.java
new file mode 100644
index 0000000..3a4fe97
--- /dev/null
+++ b/ojluni/src/main/java/java/math/RoundingMode.java
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+/*
+ * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
+ */
+package java.math;
+
+/**
+ * Specifies a <i>rounding behavior</i> for numerical operations
+ * capable of discarding precision. Each rounding mode indicates how
+ * the least significant returned digit of a rounded result is to be
+ * calculated.  If fewer digits are returned than the digits needed to
+ * represent the exact numerical result, the discarded digits will be
+ * referred to as the <i>discarded fraction</i> regardless the digits'
+ * contribution to the value of the number.  In other words,
+ * considered as a numerical value, the discarded fraction could have
+ * an absolute value greater than one.
+ *
+ * <p>Each rounding mode description includes a table listing how
+ * different two-digit decimal values would round to a one digit
+ * decimal value under the rounding mode in question.  The result
+ * column in the tables could be gotten by creating a
+ * {@code BigDecimal} number with the specified value, forming a
+ * {@link MathContext} object with the proper settings
+ * ({@code precision} set to {@code 1}, and the
+ * {@code roundingMode} set to the rounding mode in question), and
+ * calling {@link BigDecimal#round round} on this number with the
+ * proper {@code MathContext}.  A summary table showing the results
+ * of these rounding operations for all rounding modes appears below.
+ *
+ *<table border>
+ * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
+ * <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
+ *                           rounding mode</th>
+ * <tr valign=top>
+ * <th>Input Number</th>         <th>{@code UP}</th>
+ *                                           <th>{@code DOWN}</th>
+ *                                                        <th>{@code CEILING}</th>
+ *                                                                       <th>{@code FLOOR}</th>
+ *                                                                                    <th>{@code HALF_UP}</th>
+ *                                                                                                   <th>{@code HALF_DOWN}</th>
+ *                                                                                                                    <th>{@code HALF_EVEN}</th>
+ *                                                                                                                                     <th>{@code UNNECESSARY}</th>
+ *
+ * <tr align=right><td>5.5</td>  <td>6</td>  <td>5</td>    <td>6</td>    <td>5</td>  <td>6</td>      <td>5</td>       <td>6</td>       <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>2.5</td>  <td>3</td>  <td>2</td>    <td>3</td>    <td>2</td>  <td>3</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>1.6</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>2</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>1.1</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>1.0</td>  <td>1</td>  <td>1</td>    <td>1</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>1</td>
+ * <tr align=right><td>-1.0</td> <td>-1</td> <td>-1</td>   <td>-1</td>   <td>-1</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>-1</td>
+ * <tr align=right><td>-1.1</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>-1.6</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-2</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>-2.5</td> <td>-3</td> <td>-2</td>   <td>-2</td>   <td>-3</td> <td>-3</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td>
+ * <tr align=right><td>-5.5</td> <td>-6</td> <td>-5</td>   <td>-5</td>   <td>-6</td> <td>-6</td>     <td>-5</td>      <td>-6</td>      <td>throw {@code ArithmeticException}</td>
+ *</table>
+ *
+ *
+ * <p>This {@code enum} is intended to replace the integer-based
+ * enumeration of rounding mode constants in {@link BigDecimal}
+ * ({@link BigDecimal#ROUND_UP}, {@link BigDecimal#ROUND_DOWN},
+ * etc. ).
+ *
+ * @see     BigDecimal
+ * @see     MathContext
+ * @author  Josh Bloch
+ * @author  Mike Cowlishaw
+ * @author  Joseph D. Darcy
+ * @since 1.5
+ */
+public enum RoundingMode {
+
+        /**
+         * Rounding mode to round away from zero.  Always increments the
+         * digit prior to a non-zero discarded fraction.  Note that this
+         * rounding mode never decreases the magnitude of the calculated
+         * value.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode UP Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code UP} rounding
+         *<tr align=right><td>5.5</td>  <td>6</td>
+         *<tr align=right><td>2.5</td>  <td>3</td>
+         *<tr align=right><td>1.6</td>  <td>2</td>
+         *<tr align=right><td>1.1</td>  <td>2</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-2</td>
+         *<tr align=right><td>-1.6</td> <td>-2</td>
+         *<tr align=right><td>-2.5</td> <td>-3</td>
+         *<tr align=right><td>-5.5</td> <td>-6</td>
+         *</table>
+         */
+    UP(BigDecimal.ROUND_UP),
+
+        /**
+         * Rounding mode to round towards zero.  Never increments the digit
+         * prior to a discarded fraction (i.e., truncates).  Note that this
+         * rounding mode never increases the magnitude of the calculated value.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode DOWN Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code DOWN} rounding
+         *<tr align=right><td>5.5</td>  <td>5</td>
+         *<tr align=right><td>2.5</td>  <td>2</td>
+         *<tr align=right><td>1.6</td>  <td>1</td>
+         *<tr align=right><td>1.1</td>  <td>1</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-1</td>
+         *<tr align=right><td>-1.6</td> <td>-1</td>
+         *<tr align=right><td>-2.5</td> <td>-2</td>
+         *<tr align=right><td>-5.5</td> <td>-5</td>
+         *</table>
+         */
+    DOWN(BigDecimal.ROUND_DOWN),
+
+        /**
+         * Rounding mode to round towards positive infinity.  If the
+         * result is positive, behaves as for {@code RoundingMode.UP};
+         * if negative, behaves as for {@code RoundingMode.DOWN}.  Note
+         * that this rounding mode never decreases the calculated value.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode CEILING Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code CEILING} rounding
+         *<tr align=right><td>5.5</td>  <td>6</td>
+         *<tr align=right><td>2.5</td>  <td>3</td>
+         *<tr align=right><td>1.6</td>  <td>2</td>
+         *<tr align=right><td>1.1</td>  <td>2</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-1</td>
+         *<tr align=right><td>-1.6</td> <td>-1</td>
+         *<tr align=right><td>-2.5</td> <td>-2</td>
+         *<tr align=right><td>-5.5</td> <td>-5</td>
+         *</table>
+         */
+    CEILING(BigDecimal.ROUND_CEILING),
+
+        /**
+         * Rounding mode to round towards negative infinity.  If the
+         * result is positive, behave as for {@code RoundingMode.DOWN};
+         * if negative, behave as for {@code RoundingMode.UP}.  Note that
+         * this rounding mode never increases the calculated value.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode FLOOR Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code FLOOR} rounding
+         *<tr align=right><td>5.5</td>  <td>5</td>
+         *<tr align=right><td>2.5</td>  <td>2</td>
+         *<tr align=right><td>1.6</td>  <td>1</td>
+         *<tr align=right><td>1.1</td>  <td>1</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-2</td>
+         *<tr align=right><td>-1.6</td> <td>-2</td>
+         *<tr align=right><td>-2.5</td> <td>-3</td>
+         *<tr align=right><td>-5.5</td> <td>-6</td>
+         *</table>
+         */
+    FLOOR(BigDecimal.ROUND_FLOOR),
+
+        /**
+         * Rounding mode to round towards {@literal "nearest neighbor"}
+         * unless both neighbors are equidistant, in which case round up.
+         * Behaves as for {@code RoundingMode.UP} if the discarded
+         * fraction is &ge; 0.5; otherwise, behaves as for
+         * {@code RoundingMode.DOWN}.  Note that this is the rounding
+         * mode commonly taught at school.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode HALF_UP Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code HALF_UP} rounding
+         *<tr align=right><td>5.5</td>  <td>6</td>
+         *<tr align=right><td>2.5</td>  <td>3</td>
+         *<tr align=right><td>1.6</td>  <td>2</td>
+         *<tr align=right><td>1.1</td>  <td>1</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-1</td>
+         *<tr align=right><td>-1.6</td> <td>-2</td>
+         *<tr align=right><td>-2.5</td> <td>-3</td>
+         *<tr align=right><td>-5.5</td> <td>-6</td>
+         *</table>
+         */
+    HALF_UP(BigDecimal.ROUND_HALF_UP),
+
+        /**
+         * Rounding mode to round towards {@literal "nearest neighbor"}
+         * unless both neighbors are equidistant, in which case round
+         * down.  Behaves as for {@code RoundingMode.UP} if the discarded
+         * fraction is &gt; 0.5; otherwise, behaves as for
+         * {@code RoundingMode.DOWN}.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode HALF_DOWN Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code HALF_DOWN} rounding
+         *<tr align=right><td>5.5</td>  <td>5</td>
+         *<tr align=right><td>2.5</td>  <td>2</td>
+         *<tr align=right><td>1.6</td>  <td>2</td>
+         *<tr align=right><td>1.1</td>  <td>1</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-1</td>
+         *<tr align=right><td>-1.6</td> <td>-2</td>
+         *<tr align=right><td>-2.5</td> <td>-2</td>
+         *<tr align=right><td>-5.5</td> <td>-5</td>
+         *</table>
+         */
+    HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
+
+        /**
+         * Rounding mode to round towards the {@literal "nearest neighbor"}
+         * unless both neighbors are equidistant, in which case, round
+         * towards the even neighbor.  Behaves as for
+         * {@code RoundingMode.HALF_UP} if the digit to the left of the
+         * discarded fraction is odd; behaves as for
+         * {@code RoundingMode.HALF_DOWN} if it's even.  Note that this
+         * is the rounding mode that statistically minimizes cumulative
+         * error when applied repeatedly over a sequence of calculations.
+         * It is sometimes known as {@literal "Banker's rounding,"} and is
+         * chiefly used in the USA.  This rounding mode is analogous to
+         * the rounding policy used for {@code float} and {@code double}
+         * arithmetic in Java.
+         *
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode HALF_EVEN Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code HALF_EVEN} rounding
+         *<tr align=right><td>5.5</td>  <td>6</td>
+         *<tr align=right><td>2.5</td>  <td>2</td>
+         *<tr align=right><td>1.6</td>  <td>2</td>
+         *<tr align=right><td>1.1</td>  <td>1</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>-1</td>
+         *<tr align=right><td>-1.6</td> <td>-2</td>
+         *<tr align=right><td>-2.5</td> <td>-2</td>
+         *<tr align=right><td>-5.5</td> <td>-6</td>
+         *</table>
+         */
+    HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
+
+        /**
+         * Rounding mode to assert that the requested operation has an exact
+         * result, hence no rounding is necessary.  If this rounding mode is
+         * specified on an operation that yields an inexact result, an
+         * {@code ArithmeticException} is thrown.
+         *<p>Example:
+         *<table border>
+         * <caption><b>Rounding mode UNNECESSARY Examples</b></caption>
+         *<tr valign=top><th>Input Number</th>
+         *    <th>Input rounded to one digit<br> with {@code UNNECESSARY} rounding
+         *<tr align=right><td>5.5</td>  <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>2.5</td>  <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>1.6</td>  <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>1.1</td>  <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>1.0</td>  <td>1</td>
+         *<tr align=right><td>-1.0</td> <td>-1</td>
+         *<tr align=right><td>-1.1</td> <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>-1.6</td> <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>-2.5</td> <td>throw {@code ArithmeticException}</td>
+         *<tr align=right><td>-5.5</td> <td>throw {@code ArithmeticException}</td>
+         *</table>
+         */
+    UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
+
+    // Corresponding BigDecimal rounding constant
+    final int oldMode;
+
+    /**
+     * Constructor
+     *
+     * @param oldMode The {@code BigDecimal} constant corresponding to
+     *        this mode
+     */
+    private RoundingMode(int oldMode) {
+        this.oldMode = oldMode;
+    }
+
+    /**
+     * Returns the {@code RoundingMode} object corresponding to a
+     * legacy integer rounding mode constant in {@link BigDecimal}.
+     *
+     * @param  rm legacy integer rounding mode to convert
+     * @return {@code RoundingMode} corresponding to the given integer.
+     * @throws IllegalArgumentException integer is out of range
+     */
+    public static RoundingMode valueOf(int rm) {
+        switch(rm) {
+
+        case BigDecimal.ROUND_UP:
+            return UP;
+
+        case BigDecimal.ROUND_DOWN:
+            return DOWN;
+
+        case BigDecimal.ROUND_CEILING:
+            return CEILING;
+
+        case BigDecimal.ROUND_FLOOR:
+            return FLOOR;
+
+        case BigDecimal.ROUND_HALF_UP:
+            return HALF_UP;
+
+        case BigDecimal.ROUND_HALF_DOWN:
+            return HALF_DOWN;
+
+        case BigDecimal.ROUND_HALF_EVEN:
+            return HALF_EVEN;
+
+        case BigDecimal.ROUND_UNNECESSARY:
+            return UNNECESSARY;
+
+        default:
+            throw new IllegalArgumentException("argument out of range");
+        }
+    }
+}
diff --git a/ojluni/src/main/java/java/math/SignedMutableBigInteger.java b/ojluni/src/main/java/java/math/SignedMutableBigInteger.java
new file mode 100644
index 0000000..a6e5fcd
--- /dev/null
+++ b/ojluni/src/main/java/java/math/SignedMutableBigInteger.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1999, 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 java.math;
+
+/**
+ * A class used to represent multiprecision integers that makes efficient
+ * use of allocated space by allowing a number to occupy only part of
+ * an array so that the arrays do not have to be reallocated as often.
+ * When performing an operation with many iterations the array used to
+ * hold a number is only increased when necessary and does not have to
+ * be the same size as the number it represents. A mutable number allows
+ * calculations to occur on the same number without having to create
+ * a new number for every step of the calculation as occurs with
+ * BigIntegers.
+ *
+ * Note that SignedMutableBigIntegers only support signed addition and
+ * subtraction. All other operations occur as with MutableBigIntegers.
+ *
+ * @see     BigInteger
+ * @author  Michael McCloskey
+ * @since   1.3
+ */
+
+class SignedMutableBigInteger extends MutableBigInteger {
+
+   /**
+     * The sign of this MutableBigInteger.
+     */
+    int sign = 1;
+
+    // Constructors
+
+    /**
+     * The default constructor. An empty MutableBigInteger is created with
+     * a one word capacity.
+     */
+    SignedMutableBigInteger() {
+        super();
+    }
+
+    /**
+     * Construct a new MutableBigInteger with a magnitude specified by
+     * the int val.
+     */
+    SignedMutableBigInteger(int val) {
+        super(val);
+    }
+
+    /**
+     * Construct a new MutableBigInteger with a magnitude equal to the
+     * specified MutableBigInteger.
+     */
+    SignedMutableBigInteger(MutableBigInteger val) {
+        super(val);
+    }
+
+   // Arithmetic Operations
+
+   /**
+     * Signed addition built upon unsigned add and subtract.
+     */
+    void signedAdd(SignedMutableBigInteger addend) {
+        if (sign == addend.sign)
+            add(addend);
+        else
+            sign = sign * subtract(addend);
+
+    }
+
+   /**
+     * Signed addition built upon unsigned add and subtract.
+     */
+    void signedAdd(MutableBigInteger addend) {
+        if (sign == 1)
+            add(addend);
+        else
+            sign = sign * subtract(addend);
+
+    }
+
+   /**
+     * Signed subtraction built upon unsigned add and subtract.
+     */
+    void signedSubtract(SignedMutableBigInteger addend) {
+        if (sign == addend.sign)
+            sign = sign * subtract(addend);
+        else
+            add(addend);
+
+    }
+
+   /**
+     * Signed subtraction built upon unsigned add and subtract.
+     */
+    void signedSubtract(MutableBigInteger addend) {
+        if (sign == 1)
+            sign = sign * subtract(addend);
+        else
+            add(addend);
+        if (intLen == 0)
+             sign = 1;
+    }
+
+    /**
+     * Print out the first intLen ints of this MutableBigInteger's value
+     * array starting at offset.
+     */
+    public String toString() {
+        return this.toBigInteger(sign).toString();
+    }
+
+}
diff --git a/luni/src/main/java/java/math/TEST_MAPPING b/ojluni/src/main/java/java/math/TEST_MAPPING
similarity index 100%
rename from luni/src/main/java/java/math/TEST_MAPPING
rename to ojluni/src/main/java/java/math/TEST_MAPPING
diff --git a/ojluni/src/main/java/java/math/package-info.java b/ojluni/src/main/java/java/math/package-info.java
new file mode 100644
index 0000000..377cc25
--- /dev/null
+++ b/ojluni/src/main/java/java/math/package-info.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+/**
+ * Provides classes for performing arbitrary-precision integer
+ * arithmetic ({@code BigInteger}) and arbitrary-precision decimal
+ * arithmetic ({@code BigDecimal}).  {@code BigInteger} is analogous
+ * to the primitive integer types except that it provides arbitrary
+ * precision, hence operations on {@code BigInteger}s do not overflow
+ * or lose precision.  In addition to standard arithmetic operations,
+ * {@code BigInteger} provides modular arithmetic, GCD calculation,
+ * primality testing, prime generation, bit manipulation, and a few
+ * other miscellaneous operations.
+ *
+ * {@code BigDecimal} provides arbitrary-precision signed decimal
+ * numbers suitable for currency calculations and the like.  {@code
+ * BigDecimal} gives the user complete control over rounding behavior,
+ * allowing the user to choose from a comprehensive set of eight
+ * rounding modes.
+ *
+ * @since JDK1.1
+ */
+package java.math;
diff --git a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
index a3c738a..df3b6ed 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java
@@ -55,7 +55,7 @@
     protected InetAddress connectedAddress = null;
     private int connectedPort = -1;
 
-    // Android-added: CloseGuard
+    // Android-added: CloseGuard.
     private final CloseGuard guard = CloseGuard.get();
 
     private static final String os = AccessController.doPrivileged(
@@ -67,7 +67,7 @@
      */
     private final static boolean connectDisabled = os.contains("OS X");
 
-    // BEGIN Android-removed: Android doesn't need to load native net library
+    // BEGIN Android-removed: Android doesn't need to load native net library.
     /**
      * Load net library into runtime.
      *
@@ -81,7 +81,7 @@
             });
     }
     */
-    // END Android-removed: Android doesn't need to load native net library
+    // END Android-removed: Android doesn't need to load native net library.
 
     /**
      * Creates a datagram socket
@@ -97,7 +97,7 @@
             throw ioe;
         }
 
-        // Android-added: CloseGuard/fdsan
+        // Android-added: CloseGuard/fdsan.
         if (fd != null && fd.valid()) {
             guard.open("close");
             IoUtils.setFdOwner(fd, this);
@@ -130,7 +130,7 @@
      * @param port the remote port number
      */
     protected void connect(InetAddress address, int port) throws SocketException {
-        // Android-added: BlockGuard
+        // Android-added: BlockGuard.
         BlockGuard.getThreadPolicy().onNetwork();
         connect0(address, port);
         connectedAddress = address;
@@ -248,7 +248,7 @@
      * Close the socket.
      */
     protected void close() {
-        // Android-added: CloseGuard
+        // Android-added: CloseGuard.
         guard.close();
 
         if (fd != null) {
@@ -263,7 +263,7 @@
     }
 
     protected void finalize() {
-        // Android-added: CloseGuard
+        // Android-added: CloseGuard.
         if (guard != null) {
             guard.warnIfOpen();
         }
@@ -375,7 +375,7 @@
             case SO_REUSEADDR:
             case SO_BROADCAST:
                 result = socketGetOption(optID);
-                // Android-added: Added for app compat reason. See methodgetNIFirstAddress
+                // Android-added: Added for app compat reason. See methodgetNIFirstAddress.
                 if (optID == IP_MULTICAST_IF) {
                     return getNIFirstAddress((Integer)result);
                 }
@@ -422,7 +422,7 @@
         return connectDisabled;
     }
 
-    // Android-changed: rewritten on the top of IoBridge
+    // Android-changed: rewritten on the top of IoBridge.
     int dataAvailable() {
         try {
             return IoBridge.available(fd);
diff --git a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
index 0500811..963b2ac 100644
--- a/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java
@@ -50,7 +50,7 @@
 {
     /* instance variable for SO_TIMEOUT */
     int timeout;   // timeout in millisec
-    // Android-removed: traffic class is set through socket
+    // Android-removed: traffic class is set through socket.
     // private int trafficClass;
 
     private boolean shut_rd = false;
@@ -63,7 +63,7 @@
     protected int fdUseCount = 0;
 
     /* lock when increment/decrementing fdUseCount */
-    // Android-added: @ReachabilitySensitive
+    // Android-added: @ReachabilitySensitive.
     // Marked mostly because it's used where fd is, and fd isn't declared here.
     // This adds reachabilityFences where we would if fd were annotated.
     @ReachabilitySensitive
@@ -83,7 +83,7 @@
     */
     protected boolean stream;
 
-    // BEGIN Android-removed: Android doesn't need to load native net library
+    // BEGIN Android-removed: Android doesn't need to load native net library.
     /*
     /**
      * Load net library into runtime.
@@ -98,9 +98,9 @@
             });
     }
     */
-    // END Android-removed: Android doesn't need to load native net library
+    // END Android-removed: Android doesn't need to load native net library.
 
-    // Android-added: logs a warning if socket is not closed
+    // Android-added: logs a warning if socket is not closed.
     @ReachabilitySensitive
     private final CloseGuard guard = CloseGuard.get();
 
@@ -112,18 +112,18 @@
         this.stream = stream;
         if (!stream) {
             ResourceManager.beforeUdpCreate();
-            // Android-removed: socketCreate should set fd if it succeeds
+            // Android-removed: socketCreate should set fd if it succeeds.
             // fd = new FileDescriptor();
             try {
                 socketCreate(false);
             } catch (IOException ioe) {
                 ResourceManager.afterUdpClose();
-                // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
+                // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
                 // fd = null;
                 throw ioe;
             }
         } else {
-            // Android-removed: socketCreate should set fd if it succeeds
+            // Android-removed: socketCreate should set fd if it succeeds.
             // fd = new FileDescriptor();
             socketCreate(true);
         }
@@ -132,7 +132,7 @@
         if (serverSocket != null)
             serverSocket.setCreated();
 
-        // Android-added: CloseGuard
+        // Android-added: CloseGuard.
         if (fd != null && fd.valid()) {
             guard.open("close");
         }
@@ -301,7 +301,7 @@
         socketSetOption(opt, on, val);
         */
         // END Android-removed: Logic dealing with value type moved to socketSetOption.
-        // Android-added: Keep track of timeout value not handled by socketSetOption
+        // Android-added: Keep track of timeout value not handled by socketSetOption.
         if (opt == SO_TIMEOUT) {
             timeout = (Integer) val;
         }
@@ -385,7 +385,7 @@
         try {
             acquireFD();
             try {
-                // Android-added: BlockGuard
+                // Android-added: BlockGuard.
                 BlockGuard.getThreadPolicy().onNetwork();
                 socketConnect(address, port, timeout);
                 /* socket may have been closed during poll/select */
@@ -446,7 +446,7 @@
     protected void accept(SocketImpl s) throws IOException {
         acquireFD();
         try {
-            // Android-added: BlockGuard
+            // Android-added: BlockGuard.
             BlockGuard.getThreadPolicy().onNetwork();
             socketAccept(s);
         } finally {
@@ -558,10 +558,9 @@
                 if (!stream) {
                     ResourceManager.afterUdpClose();
                 }
-                // Android-changed:
-                // Socket should be untagged before the preclose. After preclose,
-                // socket will dup2-ed to marker_fd, therefore, it won't describe the same file.
-                // If closingPending is true, then the socket has been preclosed.
+                // Android-changed: Socket should be untagged before the preclose.
+                // After preclose, socket will dup2-ed to marker_fd, therefore, it won't describe
+                // the same file.  If closingPending is true, then the socket has been preclosed.
                 //
                 // Also, close the CloseGuard when the #close is called.
                 if (!closePending) {
@@ -582,8 +581,8 @@
                         } finally {
                             socketClose();
                         }
-                        // Android-changed(http://b/26470377): Some Android code doesn't expect file
-                        // descriptor to be null. socketClose invalidates the fd by closing the fd.
+                        // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
+                        // socketClose invalidates the fd by closing the fd.
                         // fd = null;
                         return;
                     } else {
@@ -607,7 +606,7 @@
             // Android-changed: Notified the CloseGuard object as the fd has been released.
             guard.close();
         }
-        // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
+        // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
         // fd = null;
         super.reset();
     }
@@ -617,7 +616,7 @@
      * Shutdown read-half of the socket connection;
      */
     protected void shutdownInput() throws IOException {
-      // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+      // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
       if (fd != null && fd.valid()) {
           socketShutdown(SHUT_RD);
           if (socketInputStream != null) {
@@ -631,7 +630,7 @@
      * Shutdown write-half of the socket connection;
      */
     protected void shutdownOutput() throws IOException {
-      // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+      // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
       if (fd != null && fd.valid()) {
           socketShutdown(SHUT_WR);
           shut_wr = true;
@@ -643,7 +642,7 @@
     }
 
     protected void sendUrgentData (int data) throws IOException {
-        // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+        // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
         if (fd == null || !fd.valid()) {
             throw new IOException("Socket Closed");
         }
@@ -654,7 +653,7 @@
      * Cleans up if the user forgets to close it.
      */
     protected void finalize() throws IOException {
-        // Android-added: CloseGuard
+        // Android-added: CloseGuard.
         if (guard != null) {
             guard.warnIfOpen();
         }
@@ -688,8 +687,8 @@
                     try {
                         socketClose();
                     } catch (IOException e) {
-                        // Android-removed: b/26470377 Some Android code doesn't expect file
-                        // descriptor to be null. socketClose invalidates the fd by closing the fd.
+                        // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
+                        // socketClose invalidates the fd by closing the fd.
                         // } finally {
                         //     fd = null;
                     }
@@ -734,7 +733,7 @@
          * close is in progress.
          */
         synchronized (fdLock) {
-            // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+            // Android-changed: Closed sockets use an invalid fd, not null. b/26470377
             if (closePending || (fd == null) || !fd.valid()) {
                 return true;
             } else {
@@ -781,8 +780,8 @@
     abstract void socketShutdown(int howto)
         throws IOException;
 
-    // Android-changed: Method signature changed, socket{Get,Set}Option work directly with Object
-    // values.
+    // Android-changed: Method signature changes.
+    // socket{Get,Set}Option work directly with Object values.
     abstract void socketSetOption(int cmd, Object value) throws SocketException;
     abstract Object socketGetOption(int opt) throws SocketException;
 
diff --git a/ojluni/src/main/java/java/net/CookieManager.java b/ojluni/src/main/java/java/net/CookieManager.java
index dfd3b86..bff9734 100644
--- a/ojluni/src/main/java/java/net/CookieManager.java
+++ b/ojluni/src/main/java/java/net/CookieManager.java
@@ -250,7 +250,7 @@
                 }
             }
         }
-        // Android-added: b/25897688 A fix to return empty map if cookies list is empty
+        // Android-added: A fix to return empty map if cookies list is empty. b/25897688
         if (cookies.isEmpty()) {
             return Collections.emptyMap();
         }
@@ -315,7 +315,7 @@
                                 }
                             }
                             cookie.setPath(path);
-                        // Android-added: b/25763487 A fix to verify cookie URI before removal
+                        // Android-added: A fix to verify cookie URI before removal. b/25763487
                         } else {
                             // Validate existing path
                             if (!pathMatches(uri, cookie)) {
@@ -408,7 +408,7 @@
         return false;
     }
 
-    // Android-changed: b/25763487 Cookie path matching logic in OpenJDK was wrong
+    // Android-changed: Cookie path matching logic in OpenJDK was wrong. b/25763487
     /**
      * Return true iff. the path from {@code cookie} matches the path from {@code uri}.
      */
@@ -436,9 +436,9 @@
     private List<String> sortByPath(List<HttpCookie> cookies) {
         Collections.sort(cookies, new CookiePathComparator());
 
-        // BEGIN Android-changed: Netscape cookie spec and RFC 2965 have different format
-        // of Cookie header; RFC 2965 requires a leading $Version="1" string while Netscape does not
-        // The workaround here is to add a $Version="1" string in advance
+        // BEGIN Android-changed: Cookie header differs in Netscape cookie spec and RFC 2965.
+        // RFC 2965 requires a leading $Version="1" string while Netscape does not.
+        // The workaround here is to add a $Version="1" string in advance.
         final StringBuilder result = new StringBuilder();
         int minVersion = 1;
         for (HttpCookie cookie : cookies) {
@@ -461,7 +461,7 @@
 
         List<String> cookieHeader = new java.util.ArrayList<String>();
         cookieHeader.add(result.toString());
-        // END Android-changed: Netscape cookie spec and RFC 2965 have different format
+        // END Android-changed: Cookie header differs in Netscape cookie spec and RFC 2965.
         return cookieHeader;
     }
 
@@ -475,7 +475,7 @@
             // path rule only applies to the cookies with same name
             if (!c1.getName().equals(c2.getName())) return 0;
 
-            // Android-changed: normalize before comparison
+            // Android-changed: normalize before comparison.
             final String c1Path = normalizePath(c1.getPath());
             final String c2Path = normalizePath(c2.getPath());
 
diff --git a/ojluni/src/main/java/java/net/DatagramSocket.java b/ojluni/src/main/java/java/net/DatagramSocket.java
index 3e3faf7..e78f3f2 100755
--- a/ojluni/src/main/java/java/net/DatagramSocket.java
+++ b/ojluni/src/main/java/java/net/DatagramSocket.java
@@ -1349,7 +1349,11 @@
 
     // Android-added: for testing and internal use.
     /**
+     * Gets socket's underlying {@link FileDescriptor}.
+     *
      * @hide internal use only
+     *
+     * @return socket's underlying {@link FileDescriptor}.
      */
     public FileDescriptor getFileDescriptor$() {
         return impl.fd;
diff --git a/ojluni/src/main/java/java/net/HttpCookie.java b/ojluni/src/main/java/java/net/HttpCookie.java
index 3ff33c7..70b9b6b 100644
--- a/ojluni/src/main/java/java/net/HttpCookie.java
+++ b/ojluni/src/main/java/java/net/HttpCookie.java
@@ -57,7 +57,7 @@
  * @since 1.6
  */
 public final class HttpCookie implements Cloneable {
-    // BEGIN Android-added: Reserved name can't be HttpCookie name
+    // BEGIN Android-added: Reserved name can't be HttpCookie name.
     private static final Set<String> RESERVED_NAMES = new HashSet<String>();
 
     static {
@@ -73,7 +73,7 @@
         RESERVED_NAMES.add("secure");     // Netscape  RFC 2109  RFC 2965  RFC 6265
         RESERVED_NAMES.add("version");    //           RFC 2109  RFC 2965  RFC 6265
     }
-    // END Android-added: Reserved name can't be HttpCookie name
+    // END Android-added: Reserved name can't be HttpCookie name.
 
     // ---------------- Fields --------------
 
@@ -691,13 +691,13 @@
             String H = host.substring(0, lengthDiff);
             String D = host.substring(lengthDiff);
 
-            // BEGIN Android-changed: App compat reason
+            // BEGIN Android-changed: App compat reason.
             // 1) Disregard RFC 2965 sec. 3.3.2, the "The request-host is a HDN..."
             // 2) match "foo.local" for domain ".local".
             // return (H.indexOf('.') == -1 && D.equalsIgnoreCase(domain));
             return D.equalsIgnoreCase(domain) && ((domain.startsWith(".") && isFullyQualifiedDomainName(domain, 1))
                 || isLocalDomain);
-            // END Android-changed: App compat reason
+            // END Android-changed: App compat reason.
         }
         else if (lengthDiff == -1) {
             // if domain is actually .host
@@ -708,12 +708,12 @@
         return false;
     }
 
-    // BEGIN Android-added: App compat reason
+    // BEGIN Android-added: App compat reason.
     private static boolean isFullyQualifiedDomainName(String s, int firstCharacter) {
         int dotPosition = s.indexOf('.', firstCharacter + 1);
         return dotPosition != -1 && dotPosition < s.length() - 1;
     }
-    // END Android-added: App compat reason
+    // END Android-added: App compat reason.
 
     /**
      * Constructs a cookie header string representation of this cookie,
@@ -799,7 +799,7 @@
     // from RFC 2068, token special case characters
     //
     // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
-    // Android-changed: App compat reason. Disallow "=\t" as token
+    // Android-changed: App compat reason. Disallow "=\t" as token.
     // private static final String tspecials = ",; ";  // deliberately includes space
     private static final String tspecials = ",;= \t";
 
@@ -813,7 +813,7 @@
      *          {@code false} if it is not
      */
     private static boolean isToken(String value) {
-        // Android-added: Reserved name can't be a token
+        // Android-added: Reserved name can't be a token.
         if (RESERVED_NAMES.contains(value.toLowerCase(Locale.US))) {
             return false;
         }
@@ -998,7 +998,7 @@
                         // 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
+                        // Android-changed: Altered max age calculation to avoid setting.
                         // it to MAX_AGE_UNSPECIFIED (-1) if "expires" is one second in past.
                         Date date = HttpDate.parse(attrValue);
                         long maxAgeInSeconds = 0;
@@ -1030,7 +1030,7 @@
         }
     }
 
-    // BEGIN Android-removed: Android doesn't use JavaNetHttpCookieAccess
+    // BEGIN Android-removed: Android doesn't use JavaNetHttpCookieAccess.
     /*
     static {
         sun.misc.SharedSecrets.setJavaNetHttpCookieAccess(
@@ -1046,7 +1046,7 @@
         );
     }
     */
-    // END Android-removed: Android doesn't use JavaNetHttpCookieAccess
+    // END Android-removed: Android doesn't use JavaNetHttpCookieAccess.
 
     /*
      * Returns the original header this cookie was consructed from, if it was
diff --git a/ojluni/src/main/java/java/net/IDN.java b/ojluni/src/main/java/java/net/IDN.java
index a18c3a8..5bce94c 100644
--- a/ojluni/src/main/java/java/net/IDN.java
+++ b/ojluni/src/main/java/java/net/IDN.java
@@ -25,7 +25,7 @@
  */
 package java.net;
 
-import android.icu.text.IDNA;
+import com.android.icu.text.ExtendedIDNA;
 
 /**
  * Provides methods to convert internationalized domain names (IDNs) between
@@ -103,9 +103,9 @@
      * @throws IllegalArgumentException   if the input string doesn't conform to RFC 3490 specification
      */
     public static String toASCII(String input, int flag) {
-        // BEGIN Android-changed: Use ICU4J implementation
+        // BEGIN Android-changed: Use ICU4J implementation.
         try {
-            return IDNA.convertIDNToASCII(input, flag).toString();
+            return ExtendedIDNA.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.
@@ -114,7 +114,7 @@
             }
             throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
         }
-        // END Android-changed: Use ICU4J implementation
+        // END Android-changed: Use ICU4J implementation.
     }
 
 
@@ -158,20 +158,20 @@
      * @return          the translated {@code String}
      */
     public static String toUnicode(String input, int flag) {
-        // BEGIN Android-changed: Use ICU4J implementation
+        // BEGIN Android-changed: Use ICU4J implementation.
         try {
             // ICU only translates separators to ASCII for toASCII.
             // Java expects the translation for toUnicode too.
-            return convertFullStop(IDNA.convertIDNToUnicode(input, flag)).toString();
+            return convertFullStop(ExtendedIDNA.convertIDNToUnicode(input, flag)).toString();
         } catch (android.icu.text.StringPrepParseException e) {
             // The RI documentation explicitly states that if the conversion was unsuccessful
             // the original string is returned.
             return input;
         }
-        // END Android-changed: Use ICU4J implementation
+        // END Android-changed: Use ICU4J implementation.
     }
 
-    // BEGIN Android-added: Use ICU4J implementation
+    // BEGIN Android-added: Use ICU4J implementation.
     private static boolean isLabelSeperator(char c) {
         return (c == '\u3002' || c == '\uff0e' || c == '\uff61');
     }
@@ -184,7 +184,7 @@
         }
         return input;
     }
-    // END Android-added: Use ICU4J implementation
+    // END Android-added: Use ICU4J implementation.
 
     /**
      * Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
diff --git a/ojluni/src/main/java/java/net/InMemoryCookieStore.java b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
index 5df66c0..85aab8b 100644
--- a/ojluni/src/main/java/java/net/InMemoryCookieStore.java
+++ b/ojluni/src/main/java/java/net/InMemoryCookieStore.java
@@ -36,7 +36,7 @@
 import java.util.Iterator;
 import java.util.concurrent.locks.ReentrantLock;
 
-// Android-changed: App compat changes and bug fixes
+// Android-changed: App compat changes and bug fixes.
 // b/26456024 Add targetSdkVersion based compatibility for domain matching
 // b/33034917 Support clearing cookies by adding it with "max-age=0"
 // b/25897688 InMemoryCookieStore ignores scheme (http/https) port and path of the cookie
@@ -52,7 +52,7 @@
  */
 public class InMemoryCookieStore implements CookieStore {
     // the in-memory representation of cookies
-    // BEGIN Android-removed: Remove cookieJar and domainIndex
+    // BEGIN Android-removed: Remove cookieJar and domainIndex.
     /*
     private List<HttpCookie> cookieJar = null;
 
@@ -62,13 +62,13 @@
     //          presence of cookie when retrieve one form index store.
     private Map<String, List<HttpCookie>> domainIndex = null;
     */
-    // END Android-removed: Remove cookieJar and domainIndex
+    // END Android-removed: Remove cookieJar and domainIndex.
     private Map<URI, List<HttpCookie>> uriIndex = null;
 
     // use ReentrantLock instead of syncronized for scalability
     private ReentrantLock lock = null;
 
-    // BEGIN Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex
+    // BEGIN Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex.
     private final boolean applyMCompatibility;
 
     /**
@@ -83,7 +83,7 @@
         lock = new ReentrantLock(false);
         applyMCompatibility = (targetSdkVersion <= 23);
     }
-    // END Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex
+    // END Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex.
 
     /**
      * Add one cookie into cookie store.
@@ -96,8 +96,8 @@
 
         lock.lock();
         try {
-            // Android-changed: http://b/33034917, android supports clearing cookies
-            // by adding the cookie with max-age: 0.
+            // Android-changed: Android supports clearing cookies. http://b/33034917
+            // They are cleared by adding the cookie with max-age: 0.
             //if (cookie.getMaxAge() != 0) {
             addIndex(uriIndex, getEffectiveURI(uri), cookie);
             //}
@@ -121,7 +121,7 @@
         }
 
         List<HttpCookie> cookies = new ArrayList<HttpCookie>();
-        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // BEGIN Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
         lock.lock();
         try {
             // check domainIndex first
@@ -131,7 +131,7 @@
         } finally {
             lock.unlock();
         }
-        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // END Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
         return cookies;
     }
 
@@ -139,7 +139,7 @@
      * Get all cookies in cookie store, except those have expired
      */
     public List<HttpCookie> getCookies() {
-        // BEGIN Android-changed: Remove cookieJar and domainIndex
+        // BEGIN Android-changed: Remove cookieJar and domainIndex.
         List<HttpCookie> rt = new ArrayList<HttpCookie>();
 
         lock.lock();
@@ -159,7 +159,7 @@
             rt = Collections.unmodifiableList(rt);
             lock.unlock();
         }
-        // END Android-changed: Remove cookieJar and domainIndex
+        // END Android-changed: Remove cookieJar and domainIndex.
 
         return rt;
     }
@@ -213,7 +213,7 @@
             throw new NullPointerException("cookie is null");
         }
 
-        // BEGIN Android-changed: Fix uri not being removed from uriIndex
+        // BEGIN Android-changed: Fix uri not being removed from uriIndex.
         lock.lock();
         try {
             uri = getEffectiveURI(uri);
@@ -230,7 +230,7 @@
         } finally {
             lock.unlock();
         }
-        // END Android-changed: Fix uri not being removed from uriIndex
+        // END Android-changed: Fix uri not being removed from uriIndex.
     }
 
 
@@ -299,7 +299,7 @@
             // need to check H & D component
             String D = host.substring(lengthDiff);
 
-            // Android-changed: b/26456024 targetSdkVersion based compatibility for domain matching
+            // Android-changed: b/26456024 targetSdkVersion based compatibility for domain matching.
             // Android M and earlier: Cookies with domain "foo.com" would not match "bar.foo.com".
             // The RFC dictates that the user agent must treat those domains as if they had a
             // leading period and must therefore match "bar.foo.com".
@@ -319,7 +319,7 @@
 
     private void getInternal1(List<HttpCookie> cookies, Map<URI, List<HttpCookie>> cookieIndex,
             String host) {
-        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // BEGIN Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
         // Use a separate list to handle cookies that need to be removed so
         // that there is no conflict with iterators.
         ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
@@ -348,7 +348,7 @@
             }
             toRemove.clear();
         }
-        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // END Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
     }
 
     // @param cookies           [OUT] contains the found cookies
@@ -359,7 +359,7 @@
         void getInternal2(List<HttpCookie> cookies, Map<T, List<HttpCookie>> cookieIndex,
                           T comparator)
     {
-        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // BEGIN Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
         // Removed cookieJar
         for (T index : cookieIndex.keySet()) {
             if ((index == comparator) || (index != null && comparator.compareTo(index) == 0)) {
@@ -381,7 +381,7 @@
                 } // end of indexedCookies != null
             } // end of comparator.compareTo(index) == 0
         } // end of cookieIndex iteration
-        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // END Android-changed: InMemoryCookieStore ignores scheme (http/https). b/25897688
     }
 
     // add 'cookie' indexed by 'index' into 'indexStore'
@@ -389,9 +389,9 @@
                               T index,
                               HttpCookie cookie)
     {
-        // Android-changed: "index" can be null. We only use the URI based
-        // index on Android and we want to support null URIs. The underlying
-        // store is a HashMap which will support null keys anyway.
+        // Android-changed: "index" can be null.
+        // We only use the URI based index on Android and we want to support null URIs. The
+        // underlying store is a HashMap which will support null keys anyway.
         // if (index != null) {
         List<HttpCookie> cookies = indexStore.get(index);
         if (cookies != null) {
@@ -413,7 +413,7 @@
     //
     private URI getEffectiveURI(URI uri) {
         URI effectiveURI = null;
-        // Android-added: Fix NullPointerException
+        // Android-added: Fix NullPointerException.
         if (uri == null) {
             return null;
         }
diff --git a/ojluni/src/main/java/java/net/Inet4Address.java b/ojluni/src/main/java/java/net/Inet4Address.java
index 1fb7b92..08952ee 100644
--- a/ojluni/src/main/java/java/net/Inet4Address.java
+++ b/ojluni/src/main/java/java/net/Inet4Address.java
@@ -93,21 +93,34 @@
      *  serialized */
     private static final long serialVersionUID = 3286316764910316507L;
 
-    // BEGIN Android-added: Define special-purpose IPv4 address
-    /** @hide */
+    // BEGIN Android-added: Define special-purpose IPv4 address.
+    /**
+     * Reserved address for {@code INADDR_ANY}, to specify any IPv4 address at all.
+     *
+     * @hide
+     */
     public static final InetAddress ANY = new Inet4Address(null, new byte[] { 0, 0, 0, 0 });
 
-    /** @hide */
+    /**
+     * Broadcast address to transmit to all devices on network.
+     *
+     * @hide
+     */
     public static final InetAddress ALL =
             new Inet4Address(null, new byte[] { (byte) 255, (byte) 255,
                   (byte) 255, (byte) 255 });
-    /** @hide */
+
+    /**
+     * Loopback address to the local host.
+     *
+     * @hide
+     */
     public static final InetAddress LOOPBACK =
             new Inet4Address("localhost", new byte[] { 127, 0, 0, 1 });
-    // END Android-added: Define special-purpose IPv4 address
+    // END Android-added: Define special-purpose IPv4 address.
 
 
-    // BEGIN Android-removed: Android doesn't need to call native init
+    // BEGIN Android-removed: Android doesn't need to call native init.
     /*
      * Perform initializations.
      *
@@ -115,7 +128,7 @@
         init();
     }
     */
-    // END Android-removed: Android doesn't need to call native init
+    // END Android-removed: Android doesn't need to call native init.
     Inet4Address() {
         super();
         holder().hostName = null;
@@ -391,11 +404,11 @@
         return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
     }
 
-    // BEGIN Android-removed: Android doesn't need to call native init
+    // BEGIN Android-removed: Android doesn't need to call native init.
     /*
      * Perform class load-time initializations.
      *
     private static native void init();
     */
-    // END Android-removed: Android doesn't need to call native init
+    // END Android-removed: Android doesn't need to call native init.
 }
diff --git a/ojluni/src/main/java/java/net/Inet6Address.java b/ojluni/src/main/java/java/net/Inet6Address.java
index c0aadb3..a8c7510 100644
--- a/ojluni/src/main/java/java/net/Inet6Address.java
+++ b/ojluni/src/main/java/java/net/Inet6Address.java
@@ -178,23 +178,31 @@
 class Inet6Address extends InetAddress {
     final static int INADDRSZ = 16;
 
-    // BEGIN Android-removed: Remove special handling for link-local addresses
+    // BEGIN Android-removed: Remove special handling for link-local addresses.
     /*
     * cached scope_id - for link-local address use only.
     *
     private transient int cached_scope_id;  // 0
     */
-    // END Android-removed: Remove special handling for link-local addresses
+    // END Android-removed: Remove special handling for link-local addresses.
 
-    // BEGIN Android-added: Define special-purpose IPv6 address
-    /** @hide */
+    // BEGIN Android-added: Define special-purpose IPv6 address.
+    /**
+     * Reserved address for {@code INADDR_ANY}, to specify any IPv6 address at all.
+     *
+     * @hide
+     */
     public static final InetAddress ANY =
             new Inet6Address("::", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0);
 
-    /** @hide */
+    /**
+     * Loopback address to the local host.
+     *
+     * @hide
+     */
     public static final InetAddress LOOPBACK = new Inet6Address("ip6-localhost",
             new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 0);
-    // END Android-added: Define special-purpose IPv6 address
+    // END Android-added: Define special-purpose IPv6 address.
 
     private class Inet6AddressHolder {
 
@@ -252,7 +260,7 @@
         void init(byte addr[], int scope_id) {
             setAddr(addr);
 
-            // Android-changed: was >= 0
+            // Android-changed: was >= 0.
             if (scope_id > 0) {
                 this.scope_id = scope_id;
                 this.scope_id_set = true;
@@ -272,7 +280,7 @@
             }
         }
 
-        // Android-removed: getnameinfo returns smarter representations than getHostAddress()
+        // Android-removed: getnameinfo returns smarter representations than getHostAddress().
         /*
         String getHostAddress() {
             String s = numericToTextFormat(ipaddress);
@@ -389,11 +397,11 @@
 
     private static final long serialVersionUID = 6880410070516793377L;
 
-    // BEGIN Android-removed: Android doesn't need to call native init
+    // BEGIN Android-removed: Android doesn't need to call native init.
     /*
     // Perform native initialization
     static { init(); }
-    // END Android-removed: Android doesn't need to call native init
+    // END Android-removed: Android doesn't need to call native init.
     */
 
     Inet6Address() {
@@ -622,7 +630,7 @@
         throws IOException, ClassNotFoundException {
         NetworkInterface scope_ifname = null;
 
-        // Android-changed: was getClass().getClassLoader() != null
+        // Android-changed: was getClass().getClassLoader() != null.
         if (getClass().getClassLoader() != Class.class.getClassLoader()) {
             throw new SecurityException ("invalid address type");
         }
@@ -894,7 +902,7 @@
      */
     @Override
     public String getHostAddress() {
-        // Android-changed: getnameinfo returns smarter representations than getHostAddress()
+        // Android-changed: getnameinfo returns smarter representations than getHostAddress().
         // return holder6.getHostAddress();
         return Libcore.os.getnameinfo(this, NI_NUMERICHOST); // Can't throw.
     }
@@ -971,11 +979,11 @@
         return sb.toString();
     }
 
-    // BEGIN Android-removed: Android doesn't need to call native init
+    // BEGIN Android-removed: Android doesn't need to call native init.
     /*
      * Perform class load-time initializations.
      *
     private static native void init();
     */
-    // END Android-removed: Android doesn't need to call native init
+    // END Android-removed: Android doesn't need to call native init.
 }
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index e4f8660..0cefc10 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -1664,7 +1664,7 @@
      * @param netId the network to use for host resolution.
      * @return the {@code InetAddress} instance representing the host.
      * @throws UnknownHostException if the address lookup fails.
-     * @hide internal use only
+     * @hide
      */
     public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
         return impl.lookupAllHostAddr(host, netId)[0];
@@ -1678,7 +1678,7 @@
      * @param netId the network to use for host resolution.
      * @return the array of addresses associated with the specified host.
      * @throws UnknownHostException if the address lookup fails.
-     * @hide internal use only
+     * @hide
      */
     public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
         return impl.lookupAllHostAddr(host, netId).clone();
diff --git a/ojluni/src/main/java/java/net/NetworkInterface.java b/ojluni/src/main/java/java/net/NetworkInterface.java
index a30b6bf..e56e0cb 100644
--- a/ojluni/src/main/java/java/net/NetworkInterface.java
+++ b/ojluni/src/main/java/java/net/NetworkInterface.java
@@ -494,8 +494,11 @@
                 NetworkInterface parent = nis.get(parentName);
 
                 ni.virtual = true;
-                ni.parent = parent;
-                parent.childs.add(ni);
+
+                if (parent != null) {
+                    ni.parent = parent;
+                    parent.childs.add(ni);
+                }
             }
         }
 
diff --git a/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java b/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
index d4b1f2c..a086d9f 100644
--- a/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
@@ -47,6 +47,7 @@
 import static libcore.io.IoBridge.JAVA_MCAST_LEAVE_GROUP;
 import static sun.net.ExtendedOptionsImpl.*;
 
+// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6.
 /*
  * On Unix systems we simply delegate to native methods.
  *
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index bae1d1c..e8c253b 100644
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -1775,7 +1775,11 @@
 
     // Android-added: getFileDescriptor$() method for testing and internal use.
     /**
+     * Gets socket's underlying {@link FileDescriptor}.
+     *
      * @hide internal use only
+     *
+     * @return socket's underlying {@link FileDescriptor}.
      */
     public FileDescriptor getFileDescriptor$() {
         return impl.getFileDescriptor();
diff --git a/ojluni/src/main/java/java/net/SocketImpl.java b/ojluni/src/main/java/java/net/SocketImpl.java
index ade2630..51000db 100644
--- a/ojluni/src/main/java/java/net/SocketImpl.java
+++ b/ojluni/src/main/java/java/net/SocketImpl.java
@@ -229,7 +229,11 @@
 
     // Android-added: getFD$() for testing.
     /**
+     * Gets socket's underlying {@link FileDescriptor}.
+     *
      * @hide used by java.nio tests
+     *
+     * @return socket's underlying {@link FileDescriptor}.
      */
     public FileDescriptor getFD$() {
         return fd;
diff --git a/ojluni/src/main/java/java/net/URLStreamHandler.java b/ojluni/src/main/java/java/net/URLStreamHandler.java
index dffc6d5..c0876e8 100644
--- a/ojluni/src/main/java/java/net/URLStreamHandler.java
+++ b/ojluni/src/main/java/java/net/URLStreamHandler.java
@@ -134,9 +134,9 @@
 
         boolean isRelPath = false;
         boolean queryOnly = false;
-        // BEGIN Android-changed: App compat
+        // BEGIN Android-changed: App compat.
         boolean querySet = false;
-        // END Android-changed: App compat
+        // END Android-changed: App compat.
 
 // FIX: should not assume query if opaque
         // Strip off the query part
@@ -148,22 +148,22 @@
                 if (limit > queryStart)
                     limit = queryStart;
                 spec = spec.substring(0, queryStart);
-                // BEGIN Android-changed: App compat
+                // BEGIN Android-changed: App compat.
                 querySet = true;
-                // END Android-changed: App compat
+                // END Android-changed: App compat.
             }
         }
 
         int i = 0;
         // Parse the authority part if any
-        // BEGIN Android-changed: App compat
+        // BEGIN Android-changed: App compat.
         // boolean isUNCName = (start <= limit - 4) &&
         //                 (spec.charAt(start) == '/') &&
         //                 (spec.charAt(start + 1) == '/') &&
         //                 (spec.charAt(start + 2) == '/') &&
         //                 (spec.charAt(start + 3) == '/');
         boolean isUNCName = false;
-        // END Android-changed: App compat
+        // END Android-changed: App compat.
         if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
             (spec.charAt(start + 1) == '/')) {
             start += 2;
@@ -239,7 +239,7 @@
                     if (ind >= 0) {
                         // port can be null according to RFC2396
                         if (host.length() > (ind + 1)) {
-                            // BEGIN Android-changed: App compat
+                            // BEGIN Android-changed: App compat.
                             // port = Integer.parseInt(host.substring(ind + 1));
                             char firstPortChar = host.charAt(ind+1);
                             if (firstPortChar >= '0' && firstPortChar <= '9') {
@@ -248,7 +248,7 @@
                                 throw new IllegalArgumentException("invalid port: " +
                                                                    host.substring(ind + 1));
                             }
-                            // END Android-changed: App compat
+                            // END Android-changed: App compat.
                         }
                         host = host.substring(0, ind);
                     }
@@ -263,14 +263,14 @@
 
             // If the authority is defined then the path is defined by the
             // spec only; See RFC 2396 Section 5.2.4.
-            // BEGIN Android-changed: App compat
+            // BEGIN Android-changed: App compat.
             // if (authority != null && authority.length() > 0)
             //   path = "";
             path = null;
             if (!querySet) {
                 query = null;
             }
-            // END Android-changed: App compat
+            // END Android-changed: App compat.
         }
 
         if (host == null) {
@@ -297,21 +297,21 @@
                 path = seperator + spec.substring(start, limit);
             }
         }
-        // BEGIN Android-changed: App compat
+        // BEGIN Android-changed: App compat.
         //else if (queryOnly && path != null) {
         //    int ind = path.lastIndexOf('/');
         //    if (ind < 0)
         //        ind = 0;
         //    path = path.substring(0, ind) + "/";
         //}
-        // END Android-changed: App compat
+        // END Android-changed: App compat.
         if (path == null)
             path = "";
 
-        // BEGIN Android-changed
+        // BEGIN Android-changed: always assume isRelPath is true.
         //if (isRelPath) {
         if (true) {
-        // END Android-changed
+        // END Android-changed: always assume isRelPath is true.
             // Remove embedded /./
             while ((i = path.indexOf("/./")) >= 0) {
                 path = path.substring(0, i) + path.substring(i + 2);
@@ -319,21 +319,21 @@
             // Remove embedded /../ if possible
             i = 0;
             while ((i = path.indexOf("/../", i)) >= 0) {
-                // BEGIN Android-changed: App compat
+                // BEGIN Android-changed: App compat.
                 /*
                  * Trailing /../
                  */
                 if (i == 0) {
                     path = path.substring(i + 3);
                     i = 0;
-                // END Android-changed: App compat
+                // END Android-changed: App compat.
                 /*
                  * A "/../" will cancel the previous segment and itself,
                  * unless that segment is a "/../" itself
                  * i.e. "/a/b/../c" becomes "/a/c"
                  * but "/../../a" should stay unchanged
                  */
-                // Android-changed: App compat
+                // Android-changed: App compat.
                 // if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
                 } else if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
                     (path.indexOf("/../", limit) != 0)) {
@@ -360,7 +360,7 @@
             if (path.endsWith("/."))
                 path = path.substring(0, path.length() -1);
 
-            // Android-changed: App compat: Remove trailing ?
+            // Android-changed: App compat: Remove trailing '?'.
             if (path.endsWith("?"))
                 path = path.substring(0, path.length() -1);
         }
@@ -391,7 +391,7 @@
      * @since 1.3
      */
     protected boolean equals(URL u1, URL u2) {
-        // Android-changed: Avoid network I/O
+        // Android-changed: Avoid network I/O.
         return Objects.equals(u1.getRef(), u2.getRef()) &&
                Objects.equals(u1.getQuery(), u2.getQuery()) &&
                // sameFile compares the protocol, file, port & host components of
@@ -408,7 +408,7 @@
      * @since 1.3
      */
     protected int hashCode(URL u) {
-        // Android-changed: Avoid network I/O
+        // Android-changed: Avoid network I/O.
         // Hash on the same set of fields that we compare in equals().
         return Objects.hash(
                 u.getRef(),
@@ -522,7 +522,7 @@
         if (u.getRef() != null)
             len += 1 + u.getRef().length();
 
-        // BEGIN Android-changed: Add a toExternalForm variant that optionally escapes illegal chars
+        // BEGIN Android-changed: New toExternalForm variant that optionally escapes illegal chars.
         // TODO: The variant has been removed. We can potentially revert the change
         StringBuilder result = new StringBuilder(len);
         result.append(u.getProtocol());
@@ -535,7 +535,7 @@
         if (fileAndQuery != null) {
             result.append(fileAndQuery);
         }
-        // END Android-changed: Add a toExternalForm variant that optionally escapes illegal chars
+        // END Android-changed: New toExternalForm variant that optionally escapes illegal chars.
         if (u.getRef() != null) {
             result.append("#");
             result.append(u.getRef());
@@ -543,7 +543,7 @@
         return result.toString();
     }
 
-    // Android-changed: Removed @see tag (target is package-private):
+    // 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.
diff --git a/ojluni/src/main/java/java/nio/charset/Charset.java b/ojluni/src/main/java/java/nio/charset/Charset.java
index 5a3b35a..2571569 100755
--- a/ojluni/src/main/java/java/nio/charset/Charset.java
+++ b/ojluni/src/main/java/java/nio/charset/Charset.java
@@ -26,7 +26,7 @@
 
 package java.nio.charset;
 
-import com.android.icu.charset.CharsetICU;
+import com.android.icu.charset.CharsetFactory;
 import java.io.UnsupportedEncodingException;
 import java.nio.ByteBuffer;
 import java.nio.CharBuffer;
@@ -508,7 +508,7 @@
 
         // Android-changed: Drop support for "standard" and "extended"
         // providers.
-        if ((cs = CharsetICU.charsetForName(charsetName))  != null ||
+        if ((cs = CharsetFactory.create(charsetName))  != null ||
             (cs = lookupViaProviders(charsetName))              != null)
         {
             cache(charsetName, cs);
@@ -628,8 +628,8 @@
                     TreeMap<String,Charset> m =
                         new TreeMap<String,Charset>(
                             ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
-                    for (String charsetName : CharsetICU.getAvailableCharsetNames()) {
-                        Charset charset = CharsetICU.charsetForName(charsetName);
+                    for (String charsetName : CharsetFactory.getAvailableCharsetNames()) {
+                        Charset charset = CharsetFactory.create(charsetName);
                         m.put(charset.name(), charset);
                     }
                     // Android-changed: No more "standard" provider.
@@ -685,7 +685,6 @@
      * @throws IllegalCharsetNameException
      *         If the canonical name or any of the aliases are illegal
      */
-    @libcore.api.IntraCoreApi
     protected Charset(String canonicalName, String[] aliases) {
         checkName(canonicalName);
         String[] as = (aliases == null) ? new String[0] : aliases;
diff --git a/ojluni/src/main/java/java/security/Provider.java b/ojluni/src/main/java/java/security/Provider.java
index 9936859..6deb954 100644
--- a/ojluni/src/main/java/java/security/Provider.java
+++ b/ojluni/src/main/java/java/security/Provider.java
@@ -95,7 +95,7 @@
     // Declare serialVersionUID to be compatible with JDK1.1
     static final long serialVersionUID = -4298000515446427739L;
 
-    // Android-added: Provider registration
+    // Android-added: Provider registration.
     // Marking a provider as "registered" makes it change the security version when
     // changes to it are made.  As of 2017-05-22 this is only used in ProviderTest.
     // TODO: Change ProviderTest to no longer require this mechanism
@@ -703,7 +703,7 @@
 
     private void readObject(ObjectInputStream in)
                 throws IOException, ClassNotFoundException {
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         registered = false;
         Map<Object,Object> copy = new HashMap<>();
         for (Map.Entry<Object,Object> entry : super.entrySet()) {
@@ -717,7 +717,7 @@
     }
 
     private boolean checkLegacy(Object key) {
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         if (registered) {
             Security.increaseVersion();
         }
@@ -742,7 +742,7 @@
         for (Map.Entry<?,?> e : t.entrySet()) {
             implPut(e.getKey(), e.getValue());
         }
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         if (registered) {
             Security.increaseVersion();
         }
@@ -817,7 +817,7 @@
             if (!checkLegacy(key)) {
                 return null;
             }
-            // BEGIN Android-changed: use compute() instead of computeIfAbsent() to avoid cast fails
+            // BEGIN Android-changed: use compute(), not computeIfAbsent(), to avoid cast fails.
             // The upstream code cannot ever succeed as the cast from BiFunction to Function
             // always fails.
             // legacyStrings.computeIfAbsent((String) key,
@@ -825,7 +825,7 @@
             legacyStrings.compute((String) key,
                     (BiFunction<? super String, ? super String, ? extends String>)
                             remappingFunction);
-            // END Android-changed: use compute() instead of computeIfAbsent() to avoid cast fails
+            // END Android-changed: use compute(), not computeIfAbsent(), to avoid cast fails.
         }
         return super.compute(key, remappingFunction);
     }
@@ -887,7 +887,7 @@
         serviceSet = null;
         super.clear();
         putId();
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         if (registered) {
           Security.increaseVersion();
         }
@@ -1192,7 +1192,7 @@
             String key = type + "." + algorithm + " " + entry.getKey();
             super.put(key, entry.getValue());
         }
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         if (registered) {
             Security.increaseVersion();
         }
@@ -1214,7 +1214,7 @@
             String key = type + "." + algorithm + " " + entry.getKey();
             super.remove(key);
         }
-        // Android-added: Provider registration
+        // Android-added: Provider registration.
         if (registered) {
           Security.increaseVersion();
         }
@@ -1883,7 +1883,7 @@
 
     }
 
-    // BEGIN Android-added: Provider registration
+    // BEGIN Android-added: Provider registration.
     /**
      * @hide
      */
@@ -1922,5 +1922,5 @@
         // stored field, if the services didn't change in the meantime.
         getServices();
     }
-    // END Android-added: Provider registration
+    // END Android-added: Provider registration.
 }
diff --git a/ojluni/src/main/java/java/text/DateFormat.java b/ojluni/src/main/java/java/text/DateFormat.java
index d7d5081..8622c2f 100644
--- a/ojluni/src/main/java/java/text/DateFormat.java
+++ b/ojluni/src/main/java/java/text/DateFormat.java
@@ -600,13 +600,21 @@
      */
     public static Boolean is24Hour;
 
+    // BEGIN Android-changed: Improve javadoc for stable SystemApi.
     /**
-     * Override the time formatting behavior for SHORT and MEDIUM time formats.
-     * {@code null}: use Locale default. {@code true}: force 24-hour format.
-     * {@code false} force 12-hour format.
+     * Override the time formatting behavior for {@link #SHORT} and {@link #MEDIUM} time formats.
+     * Accepts one of the following:
+     * <ul>
+     *   <li>{@code null}: use Locale default/li>
+     *   <li>{@code true}: force 24-hour format</li>
+     *   <li>{@code false} force 12-hour format</li>
+     * </ul>
+     *
+     * @param is24Hour whether to use 24-hour format or not. {@code null} uses locale default.
      *
      * @hide for internal use only.
      */
+    // END Android-changed: Improve javadoc for stable SystemApi.
     public static final void set24HourTimePref(Boolean is24Hour) {
         DateFormat.is24Hour = is24Hour;
     }
diff --git a/ojluni/src/main/java/java/text/DateFormatSymbols.java b/ojluni/src/main/java/java/text/DateFormatSymbols.java
index 5216928..de10644 100644
--- a/ojluni/src/main/java/java/text/DateFormatSymbols.java
+++ b/ojluni/src/main/java/java/text/DateFormatSymbols.java
@@ -101,7 +101,7 @@
  */
 public class DateFormatSymbols implements Serializable, Cloneable {
 
-    // Android-changed: Removed reference to DateFormatSymbolsProvider but suggested getInstance()
+    // Android-changed: Removed reference to DateFormatSymbolsProvider but suggested getInstance().
     // be used instead in case Android supports it in future.
     /**
      * Construct a DateFormatSymbols object by loading format data from
@@ -123,7 +123,7 @@
         initializeData(Locale.getDefault(Locale.Category.FORMAT));
     }
 
-    // Android-changed: Removed reference to DateFormatSymbolsProvider but suggested getInstance()
+    // Android-changed: Removed reference to DateFormatSymbolsProvider but suggested getInstance().
     // be used instead in case Android supports it in future.
     /**
      * Construct a DateFormatSymbols object by loading format data from
@@ -229,7 +229,7 @@
      * Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
      * All locales use the same these unlocalized pattern characters.
      */
-    // Android-changed: Add 'c' (standalone day of week), 'b' (day period),
+    // Android-changed: Add 'c' (standalone day of week), 'b' (day period),.
     //   'B' (flexible day period)
     static final String  patternChars = "GyMdkHmsSEDFwWahKzZYuXLcbB";
 
@@ -258,7 +258,7 @@
     static final int PATTERN_MONTH_STANDALONE     = 22; // L
     // Android-added: Constant for standalone day of week.
     static final int PATTERN_STANDALONE_DAY_OF_WEEK = 23; // c
-    // Android-added: Constant for pattern letter 'b', 'B'
+    // Android-added: Constant for pattern letter 'b', 'B'.
     static final int PATTERN_DAY_PERIOD = 24; // b
     static final int PATTERN_FLEXIBLE_DAY_PERIOD = 25; // B
 
@@ -848,7 +848,7 @@
         // END Android-changed: Use ICU data and move cache handling to getCachedInstance().
     }
 
-    // Android-removed: toOneBasedArray(String[])
+    // Android-removed: toOneBasedArray(String[]).
 
     // BEGIN Android-added: initializeSupplementaryData(LocaleData) for tiny and standalone fields.
     private void initializeSupplementaryData(LocaleData localeData) {
@@ -921,10 +921,11 @@
         }
         return zoneStrings;
     }
+    // END Android-changed: extract initialization of zoneStrings to separate method.
 
     private String[][] getZoneStringsImpl(boolean needsCopy) {
+        // Android-changed: use helper method to initialize zoneStrings.
         String[][] zoneStrings = internalZoneStrings();
-        // END Android-changed: extract initialization of zoneStrings to separate method.
 
         if (!needsCopy) {
             return zoneStrings;
diff --git a/ojluni/src/main/java/java/text/DecimalFormat.java b/ojluni/src/main/java/java/text/DecimalFormat.java
index a2a37b1..1dc430c 100644
--- a/ojluni/src/main/java/java/text/DecimalFormat.java
+++ b/ojluni/src/main/java/java/text/DecimalFormat.java
@@ -39,7 +39,6 @@
 
 package java.text;
 
-import android.icu.impl.number.DecimalFormatProperties.ParseMode;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -55,6 +54,8 @@
 import libcore.icu.LocaleData;
 import android.icu.math.MathContext;
 
+import com.android.icu.text.CompatibleDecimalFormatFactory;
+
 /**
  * <code>DecimalFormat</code> is a concrete subclass of
  * <code>NumberFormat</code> that formats decimal numbers. It has a variety of
@@ -487,10 +488,9 @@
      * {@link #icuDecimalFormat} in the process. This should only be called from constructors.
      */
     private void initPattern(String pattern) {
-        this.icuDecimalFormat =  new android.icu.text.DecimalFormat(pattern,
-                symbols.getIcuDecimalFormatSymbols());
         // Android-changed: Compatibility mode for j.t.DecimalFormat. http://b/112355520
-        icuDecimalFormat.setParseStrictMode(ParseMode.JAVA_COMPATIBILITY);
+        this.icuDecimalFormat = CompatibleDecimalFormatFactory.create(pattern,
+                symbols.getIcuDecimalFormatSymbols());
         updateFieldsFromIcu();
     }
 
@@ -897,7 +897,7 @@
         return format(number, result, fieldPosition.getFieldDelegate());
         */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
-        icuDecimalFormat.format(number, result, fieldPosition);
+        icuDecimalFormat.format(number, result, icuFieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
         return result;
@@ -966,7 +966,7 @@
         return format(number, result, fieldPosition.getFieldDelegate(), false);
         */
         FieldPosition icuFieldPosition = getIcuFieldPosition(fieldPosition);
-        icuDecimalFormat.format(number, result, fieldPosition);
+        icuDecimalFormat.format(number, result, icuFieldPosition);
         fieldPosition.setBeginIndex(icuFieldPosition.getBeginIndex());
         fieldPosition.setEndIndex(icuFieldPosition.getEndIndex());
         return result;
diff --git a/ojluni/src/main/java/java/text/Normalizer.java b/ojluni/src/main/java/java/text/Normalizer.java
index 8c22547..f1e77ff 100644
--- a/ojluni/src/main/java/java/text/Normalizer.java
+++ b/ojluni/src/main/java/java/text/Normalizer.java
@@ -38,6 +38,10 @@
 
 package java.text;
 
+import android.icu.text.Normalizer2;
+
+import java.util.function.Supplier;
+
 /**
  * This class provides the method <code>normalize</code> which transforms Unicode
  * text into an equivalent composed or decomposed form, allowing for easier
@@ -123,27 +127,27 @@
         /**
          * Canonical decomposition.
          */
-        NFD(android.icu.text.Normalizer.NFD),
+        NFD(Normalizer2::getNFDInstance),
 
         /**
          * Canonical decomposition, followed by canonical composition.
          */
-        NFC(android.icu.text.Normalizer.NFC),
+        NFC(Normalizer2::getNFCInstance),
 
         /**
          * Compatibility decomposition.
          */
-        NFKD(android.icu.text.Normalizer.NFKD),
+        NFKD(Normalizer2::getNFKDInstance),
 
         /**
          * Compatibility decomposition, followed by canonical composition.
          */
-        NFKC(android.icu.text.Normalizer.NFKC);
+        NFKC(Normalizer2::getNFKCInstance);
 
-        private final android.icu.text.Normalizer.Mode icuMode;
+        private final Supplier<Normalizer2> icuNormalizer;
 
-        Form(android.icu.text.Normalizer.Mode icuMode) {
-            this.icuMode = icuMode;
+        Form(Supplier<Normalizer2> icuNormalizer) {
+            this.icuNormalizer = icuNormalizer;
         }
     }
     // END Android-changed: remove static modifier and add mapping to equivalent ICU values.
@@ -164,7 +168,7 @@
      */
     public static String normalize(CharSequence src, Form form) {
         // Android-changed: Switched to ICU.
-        return android.icu.text.Normalizer.normalize(src.toString(), form.icuMode);
+        return form.icuNormalizer.get().normalize(src);
     }
 
     /**
@@ -182,6 +186,6 @@
      */
     public static boolean isNormalized(CharSequence src, Form form) {
         // Android-changed: Switched to ICU.
-        return android.icu.text.Normalizer.isNormalized(src.toString(), form.icuMode, 0);
+        return form.icuNormalizer.get().isNormalized(src);
     }
 }
diff --git a/ojluni/src/main/java/java/text/SimpleDateFormat.java b/ojluni/src/main/java/java/text/SimpleDateFormat.java
index ca5a504..36a4601 100644
--- a/ojluni/src/main/java/java/text/SimpleDateFormat.java
+++ b/ojluni/src/main/java/java/text/SimpleDateFormat.java
@@ -39,27 +39,22 @@
 
 package java.text;
 
-import android.icu.text.TimeZoneFormat;
 import android.icu.text.TimeZoneNames;
 import android.icu.util.ULocale;
 
+import com.android.icu.text.ExtendedTimeZoneNames;
+import com.android.icu.text.ExtendedTimeZoneNames.Match;
+
 import java.io.IOException;
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
-import java.util.Arrays;
 import java.util.Calendar;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.Date;
-import java.util.EnumSet;
 import java.util.GregorianCalendar;
-import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
 import java.util.NavigableMap;
-import java.util.Set;
 import java.util.SimpleTimeZone;
-import java.util.SortedMap;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -71,6 +66,8 @@
 
 // Android-changed: Added supported API level, removed unnecessary <br>
 // Android-changed: Clarified info about X symbol time zone parsing
+// Android-changed: Changed MMMMM to MMMM in month format example (ICU behavior).
+// http://b/147860740
 /**
  * <code>SimpleDateFormat</code> is a concrete class for formatting and
  * parsing dates in a locale-sensitive manner. It allows for formatting
@@ -422,7 +419,7 @@
  *         <td><code>"K:mm a, z"</code>
  *         <td><code>0:08 PM, PDT</code>
  *     <tr style="background-color: rgb(238, 238, 255);">
- *         <td><code>"yyyyy.MMMMM.dd GGG hh:mm aaa"</code>
+ *         <td><code>"yyyyy.MMMM.dd GGG hh:mm aaa"</code>
  *         <td><code>02001.July.04 AD 12:08 PM</code>
  *     <tr>
  *         <td><code>"EEE, d MMM yyyy HH:mm:ss Z"</code>
@@ -594,7 +591,7 @@
     /**
      * ICU TimeZoneNames used to format and parse time zone names.
      */
-    private transient TimeZoneNames timeZoneNames;
+    private transient ExtendedTimeZoneNames timeZoneNames;
 
     /**
      * Constructs a <code>SimpleDateFormat</code> using the default pattern and
@@ -1997,27 +1994,16 @@
         }
     }
 
-    private TimeZoneNames getTimeZoneNames() {
+    private ExtendedTimeZoneNames getExtendedTimeZoneNames() {
         if (timeZoneNames == null) {
-            timeZoneNames = TimeZoneNames.getInstance(locale);
+            timeZoneNames = ExtendedTimeZoneNames.getInstance(ULocale.forLocale(locale));
         }
         return timeZoneNames;
     }
 
-    /**
-     * The set of name types accepted when parsing time zone names.
-     */
-    private static final EnumSet<TimeZoneNames.NameType> NAME_TYPES =
-            EnumSet.of(TimeZoneNames.NameType.LONG_GENERIC, TimeZoneNames.NameType.LONG_STANDARD,
-                    TimeZoneNames.NameType.LONG_DAYLIGHT, TimeZoneNames.NameType.SHORT_GENERIC,
-                    TimeZoneNames.NameType.SHORT_STANDARD, TimeZoneNames.NameType.SHORT_DAYLIGHT);
-
-    /**
-     * Time zone name types that indicate daylight saving time.
-     */
-    private static final Set<TimeZoneNames.NameType> DST_NAME_TYPES =
-            Collections.unmodifiableSet(EnumSet.of(
-                    TimeZoneNames.NameType.LONG_DAYLIGHT, TimeZoneNames.NameType.SHORT_DAYLIGHT));
+    private TimeZoneNames getTimeZoneNames() {
+        return getExtendedTimeZoneNames().getTimeZoneNames();
+    }
 
     /**
      * Parses the time zone string using the ICU4J class {@link TimeZoneNames}.
@@ -2025,71 +2011,26 @@
     private int subParseZoneStringFromICU(String text, int start, CalendarBuilder calb) {
         String currentTimeZoneID = android.icu.util.TimeZone.getCanonicalID(getTimeZone().getID());
 
-        TimeZoneNames tzNames = getTimeZoneNames();
-        TimeZoneNames.MatchInfo bestMatch = null;
-        // The MetaZones associated with the current time zone are needed in two places, both of
-        // which are avoided in some cases, so they are computed lazily.
-        Set<String> currentTzMetaZoneIds = null;
-
-        Collection<TimeZoneNames.MatchInfo> matches = tzNames.find(text, start, NAME_TYPES);
-        for (TimeZoneNames.MatchInfo match : matches) {
-            if (bestMatch == null || bestMatch.matchLength() < match.matchLength()) {
-                bestMatch = match;
-            } else if (bestMatch.matchLength() == match.matchLength()) {
-                if (currentTimeZoneID.equals(match.tzID())) {
-                    // Prefer the currently set timezone over other matches, even if they are
-                    // the same length.
-                    bestMatch = match;
-                    break;
-                } else if (match.mzID() != null) {
-                    if (currentTzMetaZoneIds == null) {
-                        currentTzMetaZoneIds =
-                                tzNames.getAvailableMetaZoneIDs(currentTimeZoneID);
-                    }
-                    if (currentTzMetaZoneIds.contains(match.mzID())) {
-                        bestMatch = match;
-                        break;
-                    }
-                }
-            }
-        }
-        if (bestMatch == null) {
+        Match matchedName = getExtendedTimeZoneNames().matchName(text, start, currentTimeZoneID);
+        if (matchedName == null) {
             // No match found, return error.
             return -start;
         }
 
-        String tzId = bestMatch.tzID();
-        if (tzId == null) {
-            if (currentTzMetaZoneIds == null) {
-                currentTzMetaZoneIds = tzNames.getAvailableMetaZoneIDs(currentTimeZoneID);
-            }
-            if (currentTzMetaZoneIds.contains(bestMatch.mzID())) {
-                tzId = currentTimeZoneID;
-            } else {
-                // Match was for a meta-zone, find the matching reference zone.
-                ULocale uLocale = ULocale.forLocale(locale);
-                String region = uLocale.getCountry();
-                if (region.length() == 0) {
-                    uLocale = ULocale.addLikelySubtags(uLocale);
-                    region = uLocale.getCountry();
-                }
-                tzId = tzNames.getReferenceZoneID(bestMatch.mzID(), region);
-            }
-        }
-
+        String tzId = matchedName.getTzId();
         TimeZone newTimeZone = TimeZone.getTimeZone(tzId);
         if (!currentTimeZoneID.equals(tzId)) {
             setTimeZone(newTimeZone);
         }
 
         // Same logic as in subParseZoneStringFromSymbols, see below for details.
-        boolean isDst = DST_NAME_TYPES.contains(bestMatch.nameType());
+        boolean isDst = matchedName.isDst();
         int dstAmount = isDst ? newTimeZone.getDSTSavings() : 0;
         if (!isDst || dstAmount != 0) {
             calb.clear(Calendar.ZONE_OFFSET).set(Calendar.DST_OFFSET, dstAmount);
         }
 
-        return bestMatch.matchLength() + start;
+        return matchedName.getMatchLength() + start;
     }
 
     /**
diff --git a/ojluni/src/main/java/java/time/Duration.java b/ojluni/src/main/java/java/time/Duration.java
index 8637c40..ef1e802 100644
--- a/ojluni/src/main/java/java/time/Duration.java
+++ b/ojluni/src/main/java/java/time/Duration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -61,6 +61,8 @@
  */
 package java.time;
 
+import static java.time.LocalTime.MINUTES_PER_HOUR;
+import static java.time.LocalTime.NANOS_PER_MILLI;
 import static java.time.LocalTime.NANOS_PER_SECOND;
 import static java.time.LocalTime.SECONDS_PER_DAY;
 import static java.time.LocalTime.SECONDS_PER_HOUR;
@@ -223,7 +225,7 @@
      * This method allows an arbitrary number of nanoseconds to be passed in.
      * The factory will alter the values of the second and nanosecond in order
      * to ensure that the stored nanosecond is in the range 0 to 999,999,999.
-     * For example, the following will result in the exactly the same duration:
+     * For example, the following will result in exactly the same duration:
      * <pre>
      *  Duration.ofSeconds(3, 1);
      *  Duration.ofSeconds(4, -999_999_999);
@@ -954,7 +956,7 @@
         if (multiplicand == 1) {
             return this;
         }
-        return create(toSeconds().multiply(BigDecimal.valueOf(multiplicand)));
+        return create(toBigDecimalSeconds().multiply(BigDecimal.valueOf(multiplicand)));
      }
 
     /**
@@ -973,16 +975,34 @@
         if (divisor == 1) {
             return this;
         }
-        return create(toSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
+        return create(toBigDecimalSeconds().divide(BigDecimal.valueOf(divisor), RoundingMode.DOWN));
      }
 
     /**
+     * Returns number of whole times a specified Duration occurs within this Duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param divisor the value to divide the duration by, positive or negative, not null
+     * @return number of whole times, rounded toward zero, a specified
+     *         {@code Duration} occurs within this Duration, may be negative
+     * @throws ArithmeticException if the divisor is zero, or if numeric overflow occurs
+     * @since 9
+     */
+    public long dividedBy(Duration divisor) {
+        Objects.requireNonNull(divisor, "divisor");
+        BigDecimal dividendBigD = toBigDecimalSeconds();
+        BigDecimal divisorBigD = divisor.toBigDecimalSeconds();
+        return dividendBigD.divideToIntegralValue(divisorBigD).longValueExact();
+    }
+
+    /**
      * Converts this duration to the total length in seconds and
      * fractional nanoseconds expressed as a {@code BigDecimal}.
      *
      * @return the total length of the duration in seconds, with a scale of 9, not null
      */
-    private BigDecimal toSeconds() {
+    private BigDecimal toBigDecimalSeconds() {
         return BigDecimal.valueOf(seconds).add(BigDecimal.valueOf(nanos, 9));
     }
 
@@ -1149,6 +1169,20 @@
     }
 
     /**
+     * Gets the number of seconds in this duration.
+     * <p>
+     * This returns the total number of whole seconds in the duration.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the whole seconds part of the length of the duration, positive or negative
+     * @since 9
+     */
+    public long toSeconds() {
+        return seconds;
+    }
+
+    /**
      * Converts this duration to the total length in milliseconds.
      * <p>
      * If this duration is too large to fit in a {@code long} milliseconds, then an
@@ -1182,6 +1216,150 @@
         return totalNanos;
     }
 
+    /**
+     * Extracts the number of days in the duration.
+     * <p>
+     * This returns the total number of days in the duration by dividing the
+     * number of seconds by 86400.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of days in the duration, may be negative
+     * @since 9
+     */
+    public long toDaysPart(){
+        return seconds / SECONDS_PER_DAY;
+    }
+
+    /**
+     * Extracts the number of hours part in the duration.
+     * <p>
+     * This returns the number of remaining hours when dividing {@link #toHours}
+     * by hours in a day.
+     * This is based on the standard definition of a day as 24 hours.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of hours part in the duration, may be negative
+     * @since 9
+     */
+    public int toHoursPart(){
+        return (int) (toHours() % 24);
+    }
+
+    /**
+     * Extracts the number of minutes part in the duration.
+     * <p>
+     * This returns the number of remaining minutes when dividing {@link #toMinutes}
+     * by minutes in an hour.
+     * This is based on the standard definition of an hour as 60 minutes.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of minutes parts in the duration, may be negative
+     * @since 9
+     */
+    public int toMinutesPart(){
+        return (int) (toMinutes() % MINUTES_PER_HOUR);
+    }
+
+    /**
+     * Extracts the number of seconds part in the duration.
+     * <p>
+     * This returns the remaining seconds when dividing {@link #toSeconds}
+     * by seconds in a minute.
+     * This is based on the standard definition of a minute as 60 seconds.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of seconds parts in the duration, may be negative
+     * @since 9
+     */
+    public int toSecondsPart(){
+        return (int) (seconds % SECONDS_PER_MINUTE);
+    }
+
+    /**
+     * Extracts the number of milliseconds part of the duration.
+     * <p>
+     * This returns the milliseconds part by dividing the number of nanoseconds by 1,000,000.
+     * The length of the duration is stored using two fields - seconds and nanoseconds.
+     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
+     * the length in seconds.
+     * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the number of milliseconds part of the duration.
+     * @since 9
+     */
+    public int toMillisPart(){
+        return nanos / 1000_000;
+    }
+
+    /**
+     * Get the nanoseconds part within seconds of the duration.
+     * <p>
+     * The length of the duration is stored using two fields - seconds and nanoseconds.
+     * The nanoseconds part is a value from 0 to 999,999,999 that is an adjustment to
+     * the length in seconds.
+     * The total duration is defined by calling {@link #getNano()} and {@link #getSeconds()}.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @return the nanoseconds within the second part of the length of the duration, from 0 to 999,999,999
+     * @since 9
+     */
+    public int toNanosPart(){
+        return nanos;
+    }
+
+
+    //-----------------------------------------------------------------------
+    /**
+     * Returns a copy of this {@code Duration} truncated to the specified unit.
+     * <p>
+     * Truncating the duration returns a copy of the original with conceptual fields
+     * smaller than the specified unit set to zero.
+     * For example, truncating with the {@link ChronoUnit#MINUTES MINUTES} unit will
+     * round down towards zero to the nearest minute, setting the seconds and
+     * nanoseconds to zero.
+     * <p>
+     * The unit must have a {@linkplain TemporalUnit#getDuration() duration}
+     * that divides into the length of a standard day without remainder.
+     * This includes all
+     * {@linkplain ChronoUnit#isTimeBased() time-based units on {@code ChronoUnit}}
+     * and {@link ChronoUnit#DAYS DAYS}. Other ChronoUnits throw an exception.
+     * <p>
+     * This instance is immutable and unaffected by this method call.
+     *
+     * @param unit the unit to truncate to, not null
+     * @return a {@code Duration} based on this duration with the time truncated, not null
+     * @throws DateTimeException if the unit is invalid for truncation
+     * @throws UnsupportedTemporalTypeException if the unit is not supported
+     * @since 9
+     */
+    public Duration truncatedTo(TemporalUnit unit) {
+        Objects.requireNonNull(unit, "unit");
+        if (unit == ChronoUnit.SECONDS && (seconds >= 0 || nanos == 0)) {
+            return new Duration(seconds, 0);
+        } else if (unit == ChronoUnit.NANOS) {
+            return this;
+        }
+        Duration unitDur = unit.getDuration();
+        if (unitDur.getSeconds() > LocalTime.SECONDS_PER_DAY) {
+            throw new UnsupportedTemporalTypeException("Unit is too large to be used for truncation");
+        }
+        long dur = unitDur.toNanos();
+        if ((LocalTime.NANOS_PER_DAY % dur) != 0) {
+            throw new UnsupportedTemporalTypeException("Unit must divide into a standard day without remainder");
+        }
+        long nod = (seconds % LocalTime.SECONDS_PER_DAY) * LocalTime.NANOS_PER_SECOND + nanos;
+        long result = (nod / dur) * dur;
+        return plusNanos(result - nod);
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this duration to the specified {@code Duration}.
@@ -1189,7 +1367,7 @@
      * The comparison is based on the total length of the durations.
      * It is "consistent with equals", as defined by {@link Comparable}.
      *
-     * @param otherDuration  the other duration to compare to, not null
+     * @param otherDuration the other duration to compare to, not null
      * @return the comparator value, negative if less, positive if greater
      */
     @Override
@@ -1207,7 +1385,7 @@
      * <p>
      * The comparison is based on the total length of the durations.
      *
-     * @param otherDuration  the other duration, null returns false
+     * @param otherDuration the other duration, null returns false
      * @return true if the other duration is equal to this one
      */
     @Override
@@ -1240,7 +1418,7 @@
      * <p>
      * The format of the returned string will be {@code PTnHnMnS}, where n is
      * the relevant hours, minutes or seconds part of the duration.
-     * Any fractional seconds are placed after a decimal point i the seconds section.
+     * Any fractional seconds are placed after a decimal point in the seconds section.
      * If a section has a zero value, it is omitted.
      * The hours, minutes and seconds will all have the same sign.
      * <p>
diff --git a/ojluni/src/main/java/java/time/LocalTime.java b/ojluni/src/main/java/java/time/LocalTime.java
index b0b1b4d..22343c1 100644
--- a/ojluni/src/main/java/java/time/LocalTime.java
+++ b/ojluni/src/main/java/java/time/LocalTime.java
@@ -184,6 +184,10 @@
      */
     static final long MICROS_PER_DAY = SECONDS_PER_DAY * 1000_000L;
     /**
+     * Nanos per millisecond.
+     */
+    static final long NANOS_PER_MILLI = 1000_000L;
+    /**
      * Nanos per second.
      */
     static final long NANOS_PER_SECOND = 1000_000_000L;
@@ -268,10 +272,7 @@
         Objects.requireNonNull(clock, "clock");
         // inline OffsetTime factory to avoid creating object and InstantProvider checks
         final Instant now = clock.instant();  // called once
-        ZoneOffset offset = clock.getZone().getRules().getOffset(now);
-        long localSecond = now.getEpochSecond() + offset.getTotalSeconds();  // overflow caught later
-        int secsOfDay = (int) Math.floorMod(localSecond, SECONDS_PER_DAY);
-        return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + now.getNano());
+        return ofInstant(now, clock.getZone());
     }
 
     //-----------------------------------------------------------------------
@@ -337,6 +338,28 @@
         return create(hour, minute, second, nanoOfSecond);
     }
 
+    /**
+     * Obtains an instance of {@code LocalTime} from an {@code Instant} and zone ID.
+     * <p>
+     * This creates a local time based on the specified instant.
+     * First, the offset from UTC/Greenwich is obtained using the zone ID and instant,
+     * which is simple as there is only one valid offset for each instant.
+     * Then, the instant and offset are used to calculate the local time.
+     *
+     * @param instant  the instant to create the time from, not null
+     * @param zone  the time-zone, which may be an offset, not null
+     * @return the local time, not null
+     * @since 9
+     */
+    public static LocalTime ofInstant(Instant instant, ZoneId zone) {
+        Objects.requireNonNull(instant, "instant");
+        Objects.requireNonNull(zone, "zone");
+        ZoneOffset offset = zone.getRules().getOffset(instant);
+        long localSecond = instant.getEpochSecond() + offset.getTotalSeconds();
+        int secsOfDay = Math.floorMod(localSecond, SECONDS_PER_DAY);
+        return ofNanoOfDay(secsOfDay * NANOS_PER_SECOND + instant.getNano());
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Obtains an instance of {@code LocalTime} from a second-of-day value.
@@ -591,7 +614,7 @@
      * If the field is a {@link ChronoField} then the query is implemented here.
      * The {@link #isSupported(TemporalField) supported fields} will return valid
      * values based on this time, except {@code NANO_OF_DAY} and {@code MICRO_OF_DAY}
-     * which are too large to fit in an {@code int} and throw a {@code DateTimeException}.
+     * which are too large to fit in an {@code int} and throw an {@code UnsupportedTemporalTypeException}.
      * All other {@code ChronoField} instances will throw an {@code UnsupportedTemporalTypeException}.
      * <p>
      * If the field is not a {@code ChronoField}, then the result of this method
@@ -1462,6 +1485,30 @@
         return total;
     }
 
+    /**
+     * Converts this {@code LocalTime} to the number of seconds since the epoch
+     * of 1970-01-01T00:00:00Z.
+     * <p>
+     * This combines this local time with the specified date and
+     * offset to calculate the epoch-second value, which is the
+     * number of elapsed seconds from 1970-01-01T00:00:00Z.
+     * Instants on the time-line after the epoch are positive, earlier
+     * are negative.
+     *
+     * @param date the local date, not null
+     * @param offset the zone offset, not null
+     * @return the number of seconds since the epoch of 1970-01-01T00:00:00Z, may be negative
+     * @since 9
+     */
+    public long toEpochSecond(LocalDate date, ZoneOffset offset) {
+        Objects.requireNonNull(date, "date");
+        Objects.requireNonNull(offset, "offset");
+        long epochDay = date.toEpochDay();
+        long secs = epochDay * 86400 + toSecondOfDay();
+        secs -= offset.getTotalSeconds();
+        return secs;
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Compares this time to another time.
diff --git a/ojluni/src/main/java/java/time/TEST_MAPPING b/ojluni/src/main/java/java/time/TEST_MAPPING
index 5b24483..54d2ea6 100644
--- a/ojluni/src/main/java/java/time/TEST_MAPPING
+++ b/ojluni/src/main/java/java/time/TEST_MAPPING
@@ -7,7 +7,9 @@
           "include-filter": "libcore.java.time"
         }
       ]
-    },
+    }
+  ],
+  "presubmit-large": [
     {
       "name": "CtsLibcoreOjTestCases",
       "options": [
@@ -23,4 +25,4 @@
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
index 736a8fc..fff8d9a 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeFormatterBuilder.java
@@ -61,7 +61,6 @@
  */
 package java.time.format;
 
-import android.icu.impl.ZoneMeta;
 import android.icu.text.LocaleDisplayNames;
 import android.icu.text.TimeZoneFormat;
 import android.icu.text.TimeZoneNames;
@@ -78,6 +77,10 @@
 import static java.time.temporal.ChronoField.SECOND_OF_MINUTE;
 import static java.time.temporal.ChronoField.YEAR;
 
+import com.android.icu.util.ExtendedCalendar;
+
+import libcore.icu.ICU;
+
 import java.lang.ref.SoftReference;
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -210,14 +213,20 @@
             throw new IllegalArgumentException("Either dateStyle or timeStyle must be non-null");
         }
 
-        // Android-changed: get format string from ICU.
+        // BEGIN 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));
+        ExtendedCalendar extendedCalendar = ICU.getExtendedCalendar(locale,
+                chrono.getCalendarType());
+        String pattern = extendedCalendar.getDateTimePattern(convertStyle(dateStyle),
+                convertStyle(timeStyle));
+        // Transform the pattern coming from ICU because DateTimeFormatter does not handle some date
+        // symbols, e.g. 'B' / 'b', and thus we use a heuristic algorithm to remove the symbol.
+        // See http://b/174804526.
+        pattern = ICU.transformIcuDateTimePattern_forJavaTime(pattern);
+        // END Android-changed: get format string from ICU.
         return pattern;
     }
 
@@ -3698,9 +3707,9 @@
                 names = new String[TYPES.length + 1];
                 // Zeroth index used for id, other indexes based on NameType constant + 1.
                 names[0] = id;
-                String canonicalId = ZoneMeta.getCanonicalCLDRID(id);
-                timeZoneNames.getDisplayNames(canonicalId, TYPES, System.currentTimeMillis(),
-                        /* dest */ names, /* destoffset */ 1);
+                String canonicalId = ZoneName.getSystemCanonicalID(id);
+                libcore.icu.TimeZoneNames.getDisplayNames(timeZoneNames, canonicalId, TYPES,
+                        System.currentTimeMillis(), /* dest */ names, /* destoffset */ 1);
                 if (names == null) {
                     return null;
                 }
@@ -3826,7 +3835,8 @@
                 for (String zid : regionIds) {
                     tree.add(zid, zid);    // don't convert zid -> metazone
                     zid = ZoneName.toZid(zid, locale);
-                    timeZoneNames.getDisplayNames(zid, types, now, names, 0);
+                    libcore.icu.TimeZoneNames.getDisplayNames(timeZoneNames, zid, types, now,
+                            names, 0);
                     for (int i = 0; i < names.length; i++) {
                         if (names[i] != null) {
                             tree.add(names[i], zid);
@@ -3841,7 +3851,8 @@
                             continue;
                         }
                         String canonicalId = ZoneName.toZid(zid, locale);
-                        timeZoneNames.getDisplayNames(canonicalId, types, now, names, 0);
+                        libcore.icu.TimeZoneNames.getDisplayNames(timeZoneNames, canonicalId, types,
+                                now, names, 0);
                         for (int i = 0; i < names.length; i++) {
                             if (names[i] != null) {
                                 tree.add(names[i], zid);
diff --git a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
index 260196a..490d91f 100644
--- a/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
+++ b/ojluni/src/main/java/java/time/format/DateTimeTextProvider.java
@@ -61,15 +61,16 @@
  */
 package java.time.format;
 
-import android.icu.impl.ICUData;
-import android.icu.impl.ICUResourceBundle;
-import android.icu.util.UResourceBundle;
+import android.icu.text.DateFormatSymbols;
+import android.icu.util.ULocale;
 
 import static java.time.temporal.ChronoField.AMPM_OF_DAY;
 import static java.time.temporal.ChronoField.DAY_OF_WEEK;
 import static java.time.temporal.ChronoField.ERA;
 import static java.time.temporal.ChronoField.MONTH_OF_YEAR;
 
+import com.android.icu.text.ExtendedDateFormatSymbols;
+
 import java.time.chrono.Chronology;
 import java.time.chrono.IsoChronology;
 import java.time.chrono.JapaneseChronology;
@@ -452,17 +453,25 @@
                 }
             }
             */
-            ICUResourceBundle rb = (ICUResourceBundle) UResourceBundle
-                    .getBundleInstance(ICUData.ICU_BASE_NAME, locale);
-            ICUResourceBundle quartersRb = rb.getWithFallback("calendar/gregorian/quarters");
-            ICUResourceBundle formatRb = quartersRb.getWithFallback("format");
-            ICUResourceBundle standaloneRb = quartersRb.getWithFallback("stand-alone");
-            styleMap.put(TextStyle.FULL, extractQuarters(formatRb, "wide"));
-            styleMap.put(TextStyle.FULL_STANDALONE, extractQuarters(standaloneRb, "wide"));
-            styleMap.put(TextStyle.SHORT, extractQuarters(formatRb, "abbreviated"));
-            styleMap.put(TextStyle.SHORT_STANDALONE, extractQuarters(standaloneRb, "abbreviated"));
-            styleMap.put(TextStyle.NARROW, extractQuarters(formatRb, "narrow"));
-            styleMap.put(TextStyle.NARROW_STANDALONE, extractQuarters(standaloneRb, "narrow"));
+            ULocale uLocale = ULocale.forLocale(locale);
+            // TODO: Figure why we forced Gregorian calendar in the first patch in
+            // https://r.android.com/311224
+            uLocale.setKeywordValue("calendar", "gregorian");
+            ExtendedDateFormatSymbols extendedDfs = ExtendedDateFormatSymbols.getInstance(uLocale);
+            DateFormatSymbols dfs = extendedDfs.getDateFormatSymbols();
+            styleMap.put(TextStyle.FULL, extractQuarters(
+                    dfs.getQuarters(DateFormatSymbols.FORMAT, DateFormatSymbols.WIDE)));
+            styleMap.put(TextStyle.FULL_STANDALONE, extractQuarters(
+                    dfs.getQuarters(DateFormatSymbols.STANDALONE, DateFormatSymbols.WIDE)));
+            styleMap.put(TextStyle.SHORT, extractQuarters(
+                    dfs.getQuarters(DateFormatSymbols.FORMAT, DateFormatSymbols.ABBREVIATED)));
+            styleMap.put(TextStyle.SHORT_STANDALONE, extractQuarters(
+                    dfs.getQuarters(DateFormatSymbols.STANDALONE, DateFormatSymbols.ABBREVIATED)));
+            styleMap.put(TextStyle.NARROW, extractQuarters(
+                    extendedDfs.getNarrowQuarters(DateFormatSymbols.FORMAT)));
+            styleMap.put(TextStyle.NARROW_STANDALONE, extractQuarters(
+                    extendedDfs.getNarrowQuarters(DateFormatSymbols.STANDALONE)));
+
             // END Android-changed: Use ICU resources.
             return new LocaleStore(styleMap);
         }
@@ -470,16 +479,15 @@
         return "";  // null marker for map
     }
 
-    // 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();
+    // BEGIN Android-added: Extracts a Map of quarter names.
+    private static Map<Long, String> extractQuarters(String[] quarters) {
         Map<Long, String> map = new HashMap<>();
-        for (int q = 0; q < names.length; q++) {
-            map.put((long) (q + 1), names[q]);
+        for (int q = 0; q < quarters.length; q++) {
+            map.put((long) (q + 1), quarters[q]);
         }
         return map;
     }
-    // END Android-added: Extracts a Map of quarter names from ICU resource bundle.
+    // END Android-added: Extracts a Map of quarter names.
 
     /**
      * Helper method to create an immutable entry.
diff --git a/ojluni/src/main/java/java/time/format/ZoneName.java b/ojluni/src/main/java/java/time/format/ZoneName.java
index fe4a95a..daecb6e 100644
--- a/ojluni/src/main/java/java/time/format/ZoneName.java
+++ b/ojluni/src/main/java/java/time/format/ZoneName.java
@@ -24,7 +24,6 @@
  */
 package java.time.format;
 
-import android.icu.impl.ZoneMeta;
 import android.icu.text.TimeZoneNames;
 import android.icu.util.TimeZone;
 import android.icu.util.ULocale;
@@ -57,14 +56,28 @@
     }
 
     public static String toZid(String zid) {
-        // Android-changed: Use ICU ZoneMeta.
-        String canonicalCldrId = ZoneMeta.getCanonicalCLDRID(zid);
+        // Android-changed: Use ICU TimeZone.getCanonicalID().
+        String canonicalCldrId = getSystemCanonicalID(zid);
         if (canonicalCldrId != null) {
             return canonicalCldrId;
         }
         return zid;
     }
 
+    // BEGIN Android-added: Get non-custom system canonical time zone Id from ICU.
+    public static String getSystemCanonicalID(String zid) {
+        if (TimeZone.UNKNOWN_ZONE_ID.equals(zid)) {
+            return zid;
+        }
+        boolean[] isSystemID = { false };
+        String canonicalID = TimeZone.getCanonicalID(zid, isSystemID);
+        if (canonicalID == null || !isSystemID[0]) {
+            return null;
+        }
+        return canonicalID;
+    }
+    // END Android-added: Get non-custom system canonical time zone Id from ICU.
+
     // Android-removed: zidMap and aliasMap containing zone id data.
     // Android-removed: zidToMzone, mzoneToZid, mzoneToZidL, aliases and their initialization code.
 }
diff --git a/ojluni/src/main/java/java/time/temporal/ChronoField.java b/ojluni/src/main/java/java/time/temporal/ChronoField.java
index b8f7cee..e1e8250 100644
--- a/ojluni/src/main/java/java/time/temporal/ChronoField.java
+++ b/ojluni/src/main/java/java/time/temporal/ChronoField.java
@@ -621,7 +621,7 @@
 
         // Android-changed: use ICU names.
         DateTimePatternGenerator generator = DateTimePatternGenerator
-                .getFrozenInstance(ULocale.forLocale(locale));
+                .getInstance(ULocale.forLocale(locale));
         String icuName = generator.getAppendItemName(getIcuFieldNumber(this));
         return icuName != null && !icuName.isEmpty() ? icuName : name;
     }
diff --git a/ojluni/src/main/java/java/time/temporal/IsoFields.java b/ojluni/src/main/java/java/time/temporal/IsoFields.java
index 8b6f237..20b2cfd 100644
--- a/ojluni/src/main/java/java/time/temporal/IsoFields.java
+++ b/ojluni/src/main/java/java/time/temporal/IsoFields.java
@@ -420,7 +420,7 @@
                 Objects.requireNonNull(locale, "locale");
                 // Android-changed: Use ICU name values.
                 DateTimePatternGenerator dateTimePatternGenerator = DateTimePatternGenerator
-                        .getFrozenInstance(ULocale.forLocale(locale));
+                        .getInstance(ULocale.forLocale(locale));
                 String icuName = dateTimePatternGenerator
                         .getAppendItemName(DateTimePatternGenerator.WEEK_OF_YEAR);
                 return icuName != null && !icuName.isEmpty() ? icuName : toString();
diff --git a/ojluni/src/main/java/java/time/temporal/WeekFields.java b/ojluni/src/main/java/java/time/temporal/WeekFields.java
index 57f481c..b2f85ae 100644
--- a/ojluni/src/main/java/java/time/temporal/WeekFields.java
+++ b/ojluni/src/main/java/java/time/temporal/WeekFields.java
@@ -285,9 +285,8 @@
     public static WeekFields of(Locale locale) {
         Objects.requireNonNull(locale, "locale");
         // Android-changed: get Week data from ICU4J
-        ULocale ulocale = ULocale.forLocale(locale);
-        String region = ULocale.getRegionForSupplementalData(ulocale, /* inferRegion */ true);
-        Calendar.WeekData weekData = Calendar.getWeekDataForRegion(region);
+        Calendar calendar = Calendar.getInstance(locale);
+        Calendar.WeekData weekData = calendar.getWeekData();
         DayOfWeek dow = DayOfWeek.SUNDAY.plus(weekData.firstDayOfWeek - 1);
         return WeekFields.of(dow, weekData.minimalDaysInFirstWeek);
     }
@@ -1034,7 +1033,7 @@
             if (rangeUnit == YEARS) {  // only have values for week-of-year
                 // Android-changed: Use ICU name values.
                 DateTimePatternGenerator dateTimePatternGenerator = DateTimePatternGenerator
-                        .getFrozenInstance(ULocale.forLocale(locale));
+                        .getInstance(ULocale.forLocale(locale));
                 String icuName = dateTimePatternGenerator
                         .getAppendItemName(DateTimePatternGenerator.WEEK_OF_YEAR);
                 return icuName != null && !icuName.isEmpty() ? icuName : name;
diff --git a/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java b/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
index 5a4e37d..a48aa62 100644
--- a/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
+++ b/ojluni/src/main/java/java/time/zone/IcuZoneRulesProvider.java
@@ -21,25 +21,16 @@
 
 package java.time.zone;
 
-import android.icu.util.AnnualTimeZoneRule;
-import android.icu.util.BasicTimeZone;
-import android.icu.util.DateTimeRule;
-import android.icu.util.InitialTimeZoneRule;
+
 import android.icu.util.TimeZone;
-import android.icu.util.TimeZoneRule;
-import android.icu.util.TimeZoneTransition;
-import java.time.DayOfWeek;
-import java.time.LocalTime;
-import java.time.Month;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
+
+import com.android.icu.util.ExtendedTimeZone;
+
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.NavigableMap;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
 import libcore.util.BasicLruCache;
 
 /**
@@ -49,11 +40,6 @@
  */
 public class IcuZoneRulesProvider extends ZoneRulesProvider {
 
-    // Arbitrary upper limit to number of transitions including the final rules.
-    private static final int MAX_TRANSITIONS = 10000;
-
-    private static final int SECONDS_IN_DAY = 24 * 60 * 60;
-
     private final BasicLruCache<String, ZoneRules> cache = new ZoneRulesCache(8);
 
     @Override
@@ -80,216 +66,8 @@
                         provideRules(zoneId, /* forCaching */ false)));
     }
 
-    /*
-     * This implementation is only tested with BasicTimeZone objects and depends on
-     * implementation details of that class:
-     *
-     * 0. TimeZone.getFrozenTimeZone() always returns a BasicTimeZone object.
-     * 1. The first rule is always an InitialTimeZoneRule (guaranteed by spec).
-     * 2. AnnualTimeZoneRules are only used as "final rules".
-     * 3. The final rules are either 0 or 2 AnnualTimeZoneRules
-     * 4. The final rules have endYear set to MAX_YEAR.
-     * 5. Each transition generated by the rules changes either the raw offset, the total offset
-     *    or both.
-     * 6. There is a non-immense number of transitions for any rule before the final rules apply
-     *    (enforced via the arbitrary limit defined in MAX_TRANSITIONS).
-     *
-     * Assumptions #5 and #6 are not strictly required for this code to work, but hold for the
-     * the data and code at the time of implementation. If they were broken they would indicate
-     * an incomplete understanding of how ICU TimeZoneRules are used which would probably mean that
-     * this code needs to be updated.
-     *
-     * These assumptions are verified using the verify() method where appropriate.
-     */
     static ZoneRules generateZoneRules(String zoneId) {
-        TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
-        // Assumption #0
-        verify(timeZone instanceof BasicTimeZone, zoneId,
-                "Unexpected time zone class " + timeZone.getClass());
-        BasicTimeZone tz = (BasicTimeZone) timeZone;
-        TimeZoneRule[] rules = tz.getTimeZoneRules();
-        // Assumption #1
-        InitialTimeZoneRule initial = (InitialTimeZoneRule) rules[0];
-
-        ZoneOffset baseStandardOffset = millisToOffset(initial.getRawOffset());
-        ZoneOffset baseWallOffset =
-                millisToOffset((initial.getRawOffset() + initial.getDSTSavings()));
-
-        List<ZoneOffsetTransition> standardOffsetTransitionList = new ArrayList<>();
-        List<ZoneOffsetTransition> transitionList = new ArrayList<>();
-        List<ZoneOffsetTransitionRule> lastRules = new ArrayList<>();
-
-        int preLastDstSavings = 0;
-        AnnualTimeZoneRule last1 = null;
-        AnnualTimeZoneRule last2 = null;
-
-        TimeZoneTransition transition = tz.getNextTransition(Long.MIN_VALUE, false);
-        int transitionCount = 1;
-        // This loop has two possible exit conditions (in normal operation):
-        // 1. for zones that end with a static value and have no ongoing DST changes, it will exit
-        //    via the normal condition (transition != null)
-        // 2. for zones with ongoing DST changes (represented by a "final zone" in ICU4J, and by
-        //    "last rules" in java.time) the "break transitionLoop" will be used to exit the loop.
-        transitionLoop:
-        while (transition != null) {
-            TimeZoneRule from = transition.getFrom();
-            TimeZoneRule to = transition.getTo();
-            boolean hadEffect = false;
-            if (from.getRawOffset() != to.getRawOffset()) {
-                standardOffsetTransitionList.add(new ZoneOffsetTransition(
-                        TimeUnit.MILLISECONDS.toSeconds(transition.getTime()),
-                        millisToOffset(from.getRawOffset()),
-                        millisToOffset(to.getRawOffset())));
-                hadEffect = true;
-            }
-            int fromTotalOffset = from.getRawOffset() + from.getDSTSavings();
-            int toTotalOffset = to.getRawOffset() + to.getDSTSavings();
-            if (fromTotalOffset != toTotalOffset) {
-                transitionList.add(new ZoneOffsetTransition(
-                        TimeUnit.MILLISECONDS.toSeconds(transition.getTime()),
-                        millisToOffset(fromTotalOffset),
-                        millisToOffset(toTotalOffset)));
-                hadEffect = true;
-            }
-            // Assumption #5
-            verify(hadEffect, zoneId, "Transition changed neither total nor raw offset.");
-            if (to instanceof AnnualTimeZoneRule) {
-                // The presence of an AnnualTimeZoneRule is taken as an indication of a final rule.
-                if (last1 == null) {
-                    preLastDstSavings = from.getDSTSavings();
-                    last1 = (AnnualTimeZoneRule) to;
-                    // Assumption #4
-                    verify(last1.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId,
-                            "AnnualTimeZoneRule is not permanent.");
-                } else {
-                    last2 = (AnnualTimeZoneRule) to;
-                    // Assumption #4
-                    verify(last2.getEndYear() == AnnualTimeZoneRule.MAX_YEAR, zoneId,
-                            "AnnualTimeZoneRule is not permanent.");
-
-                    // Assumption #3
-                    transition = tz.getNextTransition(transition.getTime(), false);
-                    verify(transition.getTo() == last1, zoneId,
-                            "Unexpected rule after 2 AnnualTimeZoneRules.");
-                    break transitionLoop;
-                }
-            } else {
-                // Assumption #2
-                verify(last1 == null, zoneId, "Unexpected rule after AnnualTimeZoneRule.");
-            }
-            verify(transitionCount <= MAX_TRANSITIONS, zoneId,
-                    "More than " + MAX_TRANSITIONS + " transitions.");
-            transition = tz.getNextTransition(transition.getTime(), false);
-            transitionCount++;
-        }
-        if (last1 != null) {
-            // Assumption #3
-            verify(last2 != null, zoneId, "Only one AnnualTimeZoneRule.");
-            lastRules.add(toZoneOffsetTransitionRule(last1, preLastDstSavings));
-            lastRules.add(toZoneOffsetTransitionRule(last2, last1.getDSTSavings()));
-        }
-
-        return ZoneRules.of(baseStandardOffset, baseWallOffset, standardOffsetTransitionList,
-                transitionList, lastRules);
-    }
-
-    /**
-     * Verify an assumption about the zone rules.
-     *
-     * @param check
-     *         {@code true} if the assumption holds, {@code false} otherwise.
-     * @param zoneId
-     *         Zone ID for which to check.
-     * @param message
-     *         Error description of a failed check.
-     * @throws ZoneRulesException
-     *         If and only if {@code check} is {@code false}.
-     */
-    private static void verify(boolean check, String zoneId, String message) {
-        if (!check) {
-            throw new ZoneRulesException(
-                    String.format("Failed verification of zone %s: %s", zoneId, message));
-        }
-    }
-
-    /**
-     * Transform an {@link AnnualTimeZoneRule} into an equivalent {@link ZoneOffsetTransitionRule}.
-     * This is only used for the "final rules".
-     *
-     * @param rule
-     *         The rule to transform.
-     * @param dstSavingMillisBefore
-     *         The DST offset before the first transition in milliseconds.
-     */
-    private static ZoneOffsetTransitionRule toZoneOffsetTransitionRule(
-            AnnualTimeZoneRule rule, int dstSavingMillisBefore) {
-        DateTimeRule dateTimeRule = rule.getRule();
-        // Calendar.JANUARY is 0, transform it into a proper Month.
-        Month month = Month.JANUARY.plus(dateTimeRule.getRuleMonth());
-        int dayOfMonthIndicator;
-        // Calendar.SUNDAY is 1, transform it into a proper DayOfWeek.
-        DayOfWeek dayOfWeek = DayOfWeek.SATURDAY.plus(dateTimeRule.getRuleDayOfWeek());
-        switch (dateTimeRule.getDateRuleType()) {
-            case DateTimeRule.DOM:
-                // Transition always on a specific day of the month.
-                dayOfMonthIndicator = dateTimeRule.getRuleDayOfMonth();
-                dayOfWeek = null;
-                break;
-            case DateTimeRule.DOW_GEQ_DOM:
-                // ICU representation matches java.time representation.
-                dayOfMonthIndicator = dateTimeRule.getRuleDayOfMonth();
-                break;
-            case DateTimeRule.DOW_LEQ_DOM:
-                // java.time uses a negative dayOfMonthIndicator to represent "Sun<=X" or "lastSun"
-                // rules. ICU uses this constant and the normal day. So "lastSun" in January would
-                // ruleDayOfMonth = 31 in ICU and dayOfMonthIndicator = -1 in java.time.
-                dayOfMonthIndicator = -month.maxLength() + dateTimeRule.getRuleDayOfMonth() - 1;
-                break;
-            case DateTimeRule.DOW:
-                // DOW is unspecified in the documentation and seems to never be used.
-                throw new ZoneRulesException("Date rule type DOW is unsupported");
-            default:
-                throw new ZoneRulesException(
-                        "Unexpected date rule type: " + dateTimeRule.getDateRuleType());
-        }
-        // Cast to int is save, as input is int.
-        int secondOfDay = (int) TimeUnit.MILLISECONDS.toSeconds(dateTimeRule.getRuleMillisInDay());
-        LocalTime time;
-        boolean timeEndOfDay;
-        if (secondOfDay == SECONDS_IN_DAY) {
-            time = LocalTime.MIDNIGHT;
-            timeEndOfDay = true;
-        } else {
-            time = LocalTime.ofSecondOfDay(secondOfDay);
-            timeEndOfDay = false;
-        }
-        ZoneOffsetTransitionRule.TimeDefinition timeDefinition;
-        switch (dateTimeRule.getTimeRuleType()) {
-            case DateTimeRule.WALL_TIME:
-                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.WALL;
-                break;
-            case DateTimeRule.STANDARD_TIME:
-                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.STANDARD;
-                break;
-            case DateTimeRule.UTC_TIME:
-                timeDefinition = ZoneOffsetTransitionRule.TimeDefinition.UTC;
-                break;
-            default:
-                throw new ZoneRulesException(
-                        "Unexpected time rule type " + dateTimeRule.getTimeRuleType());
-        }
-        ZoneOffset standardOffset = millisToOffset(rule.getRawOffset());
-        ZoneOffset offsetBefore = millisToOffset(rule.getRawOffset() + dstSavingMillisBefore);
-        ZoneOffset offsetAfter = millisToOffset(
-                rule.getRawOffset() + rule.getDSTSavings());
-        return ZoneOffsetTransitionRule.of(
-                month, dayOfMonthIndicator, dayOfWeek, time, timeEndOfDay, timeDefinition,
-                standardOffset, offsetBefore, offsetAfter);
-    }
-
-    private static ZoneOffset millisToOffset(int offset) {
-        // Cast to int is save, as input is int.
-        return ZoneOffset.ofTotalSeconds((int) TimeUnit.MILLISECONDS.toSeconds(offset));
+        return ExtendedTimeZone.getInstance(zoneId).createZoneRules();
     }
 
     private static class ZoneRulesCache extends BasicLruCache<String, ZoneRules> {
diff --git a/ojluni/src/main/java/java/util/Arrays.java b/ojluni/src/main/java/java/util/Arrays.java
index 6da3e5d..8cd8aaf 100644
--- a/ojluni/src/main/java/java/util/Arrays.java
+++ b/ojluni/src/main/java/java/util/Arrays.java
@@ -78,7 +78,7 @@
      * tasks that makes parallel speedups unlikely.
      * @hide
      */
-    // Android-changed: Make MIN_ARRAY_SORT_GRAN public and @hide (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.
@@ -1232,14 +1232,14 @@
      *         {@link Comparable} contract
      */
     public static void sort(Object[] a) {
-        // Android-removed: LegacyMergeSort support
+        // 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)
+    // Android-removed: legacyMergeSort() (unused on Android).
 
     /**
      * Sorts the specified range of the specified array of objects into
@@ -1295,14 +1295,14 @@
      */
     public static void sort(Object[] a, int fromIndex, int toIndex) {
         rangeCheck(a.length, fromIndex, toIndex);
-        // Android-removed: LegacyMergeSort support
+        // 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)
+    // Android-removed: legacyMergeSort() (unused on Android).
 
     /**
      * Tuning parameter: list size at or below which insertion sort will be
@@ -1417,7 +1417,7 @@
         if (c == null) {
             sort(a);
         } else {
-        // Android-removed: LegacyMergeSort support
+        // Android-removed: LegacyMergeSort support.
             // if (LegacyMergeSort.userRequested)
             //     legacyMergeSort(a, c);
             // else
@@ -1425,7 +1425,7 @@
         }
     }
 
-    // Android-removed: legacyMergeSort() (unused on Android)
+    // Android-removed: legacyMergeSort() (unused on Android).
 
     /**
      * Sorts the specified range of the specified array of objects according
@@ -1485,7 +1485,7 @@
             sort(a, fromIndex, toIndex);
         } else {
             rangeCheck(a.length, fromIndex, toIndex);
-            // Android-removed: LegacyMergeSort support
+            // Android-removed: LegacyMergeSort support.
             // if (LegacyMergeSort.userRequested)
             //     legacyMergeSort(a, fromIndex, toIndex, c);
             // else
@@ -1493,8 +1493,8 @@
         }
     }
 
-    // Android-removed: legacyMergeSort() (unused on Android)
-    // Android-removed: mergeSort() (unused on Android)
+    // Android-removed: legacyMergeSort() (unused on Android).
+    // Android-removed: mergeSort() (unused on Android).
 
     // Parallel prefix
 
@@ -4110,7 +4110,7 @@
 
         for (Object element : a) {
             int elementHash = 0;
-            // BEGIN Android-changed: getComponentType() is faster than instanceof()
+            // BEGIN Android-changed: getComponentType() is faster than instanceof().
             if (element != null) {
                 Class<?> cl = element.getClass().getComponentType();
                 if (cl == null)
@@ -4136,7 +4136,7 @@
                 else
                     elementHash = element.hashCode();
             }
-            // END Android-changed: getComponentType() is faster than instanceof()
+            // END Android-changed: getComponentType() is faster than instanceof().
             result = 31 * result + elementHash;
         }
 
diff --git a/ojluni/src/main/java/java/util/Calendar.java b/ojluni/src/main/java/java/util/Calendar.java
index 7093533..53994c1 100644
--- a/ojluni/src/main/java/java/util/Calendar.java
+++ b/ojluni/src/main/java/java/util/Calendar.java
@@ -1595,7 +1595,7 @@
      */
     protected Calendar(TimeZone zone, Locale aLocale)
     {
-        // BEGIN Android-added: Allow aLocale == null
+        // BEGIN Android-added: Allow aLocale == null.
         // http://b/16938922.
         //
         // TODO: This is for backwards compatibility only. Seems like a better idea to throw
@@ -1603,7 +1603,7 @@
         if (aLocale == null) {
             aLocale = Locale.getDefault();
         }
-        // END Android-added: Allow aLocale == null
+        // END Android-added: Allow aLocale == null.
         fields = new int[FIELD_COUNT];
         isSet = new boolean[FIELD_COUNT];
         stamp = new int[FIELD_COUNT];
@@ -1667,7 +1667,7 @@
         return createCalendar(zone, aLocale);
     }
 
-    // BEGIN Android-added: add getJapaneseImperialInstance()
+    // BEGIN Android-added: add getJapaneseImperialInstance().
     /**
      * Create a Japanese Imperial Calendar.
      * @hide
@@ -1675,14 +1675,14 @@
     public static Calendar getJapaneseImperialInstance(TimeZone zone, Locale aLocale) {
         return new JapaneseImperialCalendar(zone, aLocale);
     }
-    // END Android-added: add getJapaneseImperialInstance()
+    // END Android-added: add getJapaneseImperialInstance().
 
     private static Calendar createCalendar(TimeZone zone,
                                            Locale aLocale)
     {
-        // BEGIN Android-changed: only support GregorianCalendar here
+        // BEGIN Android-changed: only support GregorianCalendar here.
         return new GregorianCalendar(zone, aLocale);
-        // END Android-changed: only support GregorianCalendar here
+        // END Android-changed: only support GregorianCalendar here.
     }
 
     /**
@@ -2061,13 +2061,13 @@
      * @since 1.6
      */
     public String getDisplayName(int field, int style, Locale locale) {
-        // BEGIN Android-changed: Treat ALL_STYLES as SHORT
+        // BEGIN Android-changed: Treat ALL_STYLES as SHORT.
         // Android has traditionally treated ALL_STYLES as SHORT, even though
         // it's not documented to be a valid value for style.
         if (style == ALL_STYLES) {
             style = SHORT;
         }
-        // END Android-changed: Treat ALL_STYLES as SHORT
+        // END Android-changed: Treat ALL_STYLES as SHORT.
         if (!checkDisplayNameParams(field, style, SHORT, NARROW_FORMAT, locale,
                             ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
             return null;
@@ -2161,7 +2161,7 @@
                                     ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
             return null;
         }
-        // Android-added: Add complete() here to fix leniency, see http://b/35382060
+        // Android-added: Add complete() here to fix leniency. http://b/35382060
         complete();
 
         String calendarType = getCalendarType();
@@ -2209,12 +2209,12 @@
             baseStyle < minStyle || baseStyle > maxStyle) {
             throw new IllegalArgumentException();
         }
-        // BEGIN Android-added: Check for invalid baseStyle == 3
+        // BEGIN Android-added: Check for invalid baseStyle == 3.
         // 3 is not a valid base style (unlike 1, 2 and 4). Throw if used.
         if (baseStyle == 3) {
             throw new IllegalArgumentException();
         }
-        // END Android-added: Check for invalid baseStyle == 3
+        // END Android-added: Check for invalid baseStyle == 3.
         if (locale == null) {
             throw new NullPointerException();
         }
@@ -2574,12 +2574,12 @@
         return style & ~STANDALONE_MASK;
     }
 
-    // BEGIN Android-changed: Make toStandaloneStyle() public to use in java.text.SimpleDateFormat
+    // 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
+    // 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/Currency.java b/ojluni/src/main/java/java/util/Currency.java
index 94629c7..c7b8b16 100644
--- a/ojluni/src/main/java/java/util/Currency.java
+++ b/ojluni/src/main/java/java/util/Currency.java
@@ -361,16 +361,21 @@
         */
         android.icu.util.Currency icuInstance =
                 android.icu.util.Currency.getInstance(locale);
+        // Unknown historical reason to append variant to country code. The API documentation
+        // does not mention the effect of locale variant. The actual effect here is throwing
+        // IllegalArgumentException because the code like FR_EURO is not a valid country code.
         String variant = locale.getVariant();
         if (!variant.isEmpty() && (variant.equals("EURO") || variant.equals("HK") ||
                 variant.equals("PREEURO"))) {
             country = country + "_" + variant;
         }
-        String currencyCode = ICU.getCurrencyCode(country);
-        if (currencyCode == null) {
+        if (!ICU.isIsoCountry(country)) {
+            // Throws IllegalArgumentException as required by the API documentation.
             throw new IllegalArgumentException("Unsupported ISO 3166 country: " + locale);
         }
-        if (icuInstance == null || icuInstance.getCurrencyCode().equals("XXX")) {
+        String currencyCode = ICU.getCurrencyCode(country);
+        if (currencyCode == null || icuInstance == null ||
+                icuInstance.getCurrencyCode().equals("XXX")) { // XXX is not a real currency.
             return null;
         }
         return getInstance(currencyCode);
diff --git a/ojluni/src/main/java/java/util/GregorianCalendar.java b/ojluni/src/main/java/java/util/GregorianCalendar.java
index 1d8c87b..46733e9 100644
--- a/ojluni/src/main/java/java/util/GregorianCalendar.java
+++ b/ojluni/src/main/java/java/util/GregorianCalendar.java
@@ -739,12 +739,12 @@
         gdate = (BaseCalendar.Date) gcal.newCalendarDate(getZone());
     }
 
-    // BEGIN Android-added
+    // BEGIN Android-added: Constructor.
     GregorianCalendar(long milliseconds) {
         this();
         setTimeInMillis(milliseconds);
     }
-    // END Android-added
+    // END Android-added: Constructor.
 
 /////////////////
 // Public methods
@@ -1080,7 +1080,7 @@
             }
 
             fd += delta; // fd is the expected fixed date after the calculation
-            // BEGIN Android-changed: time zone related calculation via helper methods
+            // BEGIN Android-changed: time zone related calculation via helper methods.
             // Calculate the time in the UTC time zone.
             long utcTime = (fd - EPOCH_OFFSET) * ONE_DAY + timeOfDay;
 
@@ -1093,7 +1093,7 @@
 
             // Update the time and recompute the fields.
             setTimeInMillis(millis);
-            // END Android-changed: time zone related calculation via helper methods
+            // END Android-changed: time zone related calculation via helper methods.
         }
     }
 
@@ -2346,12 +2346,12 @@
         }
         if (tzMask != (ZONE_OFFSET_MASK|DST_OFFSET_MASK)) {
             if (tz instanceof ZoneInfo) {
-                // BEGIN Android-changed: use libcore.util.ZoneInfo
+                // BEGIN Android-changed: use libcore.util.ZoneInfo.
                 // The method name to get offsets differs from sun.util.calendar.ZoneInfo
                 // zoneOffset = ((ZoneInfo)tz).getOffsets(time, zoneOffsets);
                 ZoneInfo zoneInfo = (ZoneInfo) tz;
                 zoneOffset = zoneInfo.getOffsetsByUtcTime(time, zoneOffsets);
-                // END Android-changed: use libcore.util.ZoneInfo
+                // END Android-changed: use libcore.util.ZoneInfo.
             } else {
                 zoneOffset = tz.getOffset(time);
                 zoneOffsets[0] = tz.getRawOffset();
@@ -2801,11 +2801,11 @@
         // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
         // or DST_OFFSET fields; then we use those fields.
         TimeZone zone = getZone();
-        // BEGIN Android-changed: time zone related calculation via helper methods
+        // BEGIN Android-changed: time zone related calculation via helper methods.
         int tzMask = fieldMask & (ZONE_OFFSET_MASK|DST_OFFSET_MASK);
 
         millis = adjustForZoneAndDaylightSavingsTime(tzMask, millis, zone);
-        // END Android-changed: time zone related calculation via helper methods
+        // END Android-changed: time zone related calculation via helper methods.
 
         // Set this calendar's time in milliseconds
         time = millis;
@@ -2828,7 +2828,7 @@
         setFieldsNormalized(mask);
     }
 
-    // BEGIN Android-added: helper methods for time zone related calculation
+    // BEGIN Android-added: helper methods for time zone related calculation.
     /**
      * Calculates the time in milliseconds that this calendar represents using the UTC time,
      * timezone information (specifically Daylight Savings Time (DST) rules, if any) and knowledge
@@ -2998,7 +2998,7 @@
         }
         return dstOffset;
     }
-    // END Android-added: helper methods for time zone related calculation
+    // END Android-added: helper methods for time zone related calculation.
 
     /**
      * Computes the fixed date under either the Gregorian or the
diff --git a/ojluni/src/main/java/java/util/ImmutableCollections.java b/ojluni/src/main/java/java/util/ImmutableCollections.java
index 2bc0cc1..e42538c 100644
--- a/ojluni/src/main/java/java/util/ImmutableCollections.java
+++ b/ojluni/src/main/java/java/util/ImmutableCollections.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 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
@@ -69,125 +69,316 @@
 
     static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }
 
-    // ---------- List Implementations ----------
-
-    abstract static class AbstractImmutableList<E> extends AbstractList<E>
-                                                implements RandomAccess, Serializable {
+    static abstract class AbstractImmutableCollection<E> extends AbstractCollection<E> {
+        // all mutating methods throw UnsupportedOperationException
         @Override public boolean add(E e) { throw uoe(); }
         @Override public boolean addAll(Collection<? extends E> c) { throw uoe(); }
-        @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
         @Override public void    clear() { throw uoe(); }
         @Override public boolean remove(Object o) { throw uoe(); }
         @Override public boolean removeAll(Collection<?> c) { throw uoe(); }
         @Override public boolean removeIf(Predicate<? super E> filter) { throw uoe(); }
-        @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
         @Override public boolean retainAll(Collection<?> c) { throw uoe(); }
-        @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
     }
 
-    static final class List0<E> extends AbstractImmutableList<E> {
-        private static final List0<?> INSTANCE = new List0<>();
+    // ---------- List Implementations ----------
 
-        @SuppressWarnings("unchecked")
-        static <T> List0<T> instance() {
-            return (List0<T>) INSTANCE;
+    // make a copy, short-circuiting based on implementation class
+    @SuppressWarnings("unchecked")
+    static <E> List<E> listCopy(Collection<? extends E> coll) {
+        if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) {
+            return (List<E>)coll;
+        } else {
+            return (List<E>)List.of(coll.toArray());
         }
+    }
 
-        private List0() { }
+    @SuppressWarnings("unchecked")
+    static <E> List<E> emptyList() {
+        return (List<E>) ListN.EMPTY_LIST;
+    }
+
+    static abstract class AbstractImmutableList<E> extends AbstractImmutableCollection<E>
+            implements List<E>, RandomAccess {
+
+        // all mutating methods throw UnsupportedOperationException
+        @Override public void    add(int index, E element) { throw uoe(); }
+        @Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
+        @Override public E       remove(int index) { throw uoe(); }
+        @Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
+        @Override public E       set(int index, E element) { throw uoe(); }
+        @Override public void    sort(Comparator<? super E> c) { throw uoe(); }
 
         @Override
-        public int size() {
-            return 0;
+        public List<E> subList(int fromIndex, int toIndex) {
+            int size = size();
+            subListRangeCheck(fromIndex, toIndex, size);
+            return SubList.fromList(this, fromIndex, toIndex);
         }
 
-        @Override
-        public E get(int index) {
-            Objects.checkIndex(index, 0); // always throws IndexOutOfBoundsException
-            return null;                  // but the compiler doesn't know this
+        static void subListRangeCheck(int fromIndex, int toIndex, int size) {
+            if (fromIndex < 0)
+                throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
+            if (toIndex > size)
+                throw new IndexOutOfBoundsException("toIndex = " + toIndex);
+            if (fromIndex > toIndex)
+                throw new IllegalArgumentException("fromIndex(" + fromIndex +
+                        ") > toIndex(" + toIndex + ")");
         }
 
         @Override
         public Iterator<E> iterator() {
-            return Collections.emptyIterator();
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST);
+            return new ListItr<E>(this, size());
         }
 
         @Override
-        public boolean contains(Object o) {
+        public ListIterator<E> listIterator() {
+            return listIterator(0);
+        }
+
+        @Override
+        public ListIterator<E> listIterator(final int index) {
+            int size = size();
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
+            }
+            return new ListItr<E>(this, size, index);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == this) {
+                return true;
+            }
+
+            if (!(o instanceof List)) {
+                return false;
+            }
+
+            Iterator<?> oit = ((List<?>) o).iterator();
+            for (int i = 0, s = size(); i < s; i++) {
+                if (!oit.hasNext() || !get(i).equals(oit.next())) {
+                    return false;
+                }
+            }
+            return !oit.hasNext();
+        }
+
+        @Override
+        public int indexOf(Object o) {
             Objects.requireNonNull(o);
-            return false;
+            for (int i = 0, s = size(); i < s; i++) {
+                if (o.equals(get(i))) {
+                    return i;
+                }
+            }
+            return -1;
         }
 
         @Override
-        public boolean containsAll(Collection<?> o) {
-            return o.isEmpty(); // implicit nullcheck of o
+        public int lastIndexOf(Object o) {
+            Objects.requireNonNull(o);
+            for (int i = size() - 1; i >= 0; i--) {
+                if (o.equals(get(i))) {
+                    return i;
+                }
+            }
+            return -1;
         }
 
         @Override
         public int hashCode() {
-            return 1;
-        }
-    }
-
-    static final class List1<E> extends AbstractImmutableList<E> {
-        @Stable
-        private final E e0;
-
-        List1(E e0) {
-            this.e0 = Objects.requireNonNull(e0);
-        }
-
-        @Override
-        public int size() {
-            return 1;
-        }
-
-        @Override
-        public E get(int index) {
-            Objects.checkIndex(index, 1);
-            return e0;
-        }
-
-        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-            throw new InvalidObjectException("not serial proxy");
-        }
-
-        private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST, e0);
+            int hash = 1;
+            for (int i = 0, s = size(); i < s; i++) {
+                hash = 31 * hash + get(i).hashCode();
+            }
+            return hash;
         }
 
         @Override
         public boolean contains(Object o) {
-            return o.equals(e0); // implicit nullcheck of o
+            return indexOf(o) >= 0;
         }
 
-        @Override
-        public int hashCode() {
-            return 31 + e0.hashCode();
+        IndexOutOfBoundsException outOfBounds(int index) {
+            return new IndexOutOfBoundsException("Index: " + index + " Size: " + size());
         }
     }
 
-    static final class List2<E> extends AbstractImmutableList<E> {
+    static final class ListItr<E> implements ListIterator<E> {
+
+        @Stable
+        private final List<E> list;
+
+        @Stable
+        private final int size;
+
+        @Stable
+        private final boolean isListIterator;
+
+        private int cursor;
+
+        ListItr(List<E> list, int size) {
+            this.list = list;
+            this.size = size;
+            this.cursor = 0;
+            isListIterator = false;
+        }
+
+        ListItr(List<E> list, int size, int index) {
+            this.list = list;
+            this.size = size;
+            this.cursor = index;
+            isListIterator = true;
+        }
+
+        public boolean hasNext() {
+            return cursor != size;
+        }
+
+        public E next() {
+            try {
+                int i = cursor;
+                E next = list.get(i);
+                cursor = i + 1;
+                return next;
+            } catch (IndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public void remove() {
+            throw uoe();
+        }
+
+        public boolean hasPrevious() {
+            if (!isListIterator) {
+                throw uoe();
+            }
+            return cursor != 0;
+        }
+
+        public E previous() {
+            if (!isListIterator) {
+                throw uoe();
+            }
+            try {
+                int i = cursor - 1;
+                E previous = list.get(i);
+                cursor = i;
+                return previous;
+            } catch (IndexOutOfBoundsException e) {
+                throw new NoSuchElementException();
+            }
+        }
+
+        public int nextIndex() {
+            if (!isListIterator) {
+                throw uoe();
+            }
+            return cursor;
+        }
+
+        public int previousIndex() {
+            if (!isListIterator) {
+                throw uoe();
+            }
+            return cursor - 1;
+        }
+
+        public void set(E e) {
+            throw uoe();
+        }
+
+        public void add(E e) {
+            throw uoe();
+        }
+    }
+
+    static final class SubList<E> extends AbstractImmutableList<E>
+            implements RandomAccess {
+
+        @Stable
+        private final List<E> root;
+
+        @Stable
+        private final int offset;
+
+        @Stable
+        private final int size;
+
+        private SubList(List<E> root, int offset, int size) {
+            this.root = root;
+            this.offset = offset;
+            this.size = size;
+        }
+
+        /**
+         * Constructs a sublist of another SubList.
+         */
+        static <E> SubList<E> fromSubList(SubList<E> parent, int fromIndex, int toIndex) {
+            return new SubList<>(parent.root, parent.offset + fromIndex, toIndex - fromIndex);
+        }
+
+        /**
+         * Constructs a sublist of an arbitrary AbstractImmutableList, which is
+         * not a SubList itself.
+         */
+        static <E> SubList<E> fromList(List<E> list, int fromIndex, int toIndex) {
+            return new SubList<>(list, fromIndex, toIndex - fromIndex);
+        }
+
+        public E get(int index) {
+            Objects.checkIndex(index, size);
+            return root.get(offset + index);
+        }
+
+        public int size() {
+            return size;
+        }
+
+        public Iterator<E> iterator() {
+            return new ListItr<>(this, size());
+        }
+
+        public ListIterator<E> listIterator(int index) {
+            rangeCheck(index);
+            return new ListItr<>(this, size(), index);
+        }
+
+        public List<E> subList(int fromIndex, int toIndex) {
+            subListRangeCheck(fromIndex, toIndex, size);
+            return SubList.fromSubList(this, fromIndex, toIndex);
+        }
+
+        private void rangeCheck(int index) {
+            if (index < 0 || index > size) {
+                throw outOfBounds(index);
+            }
+        }
+    }
+
+    static final class List12<E> extends AbstractImmutableList<E>
+            implements Serializable {
+
         @Stable
         private final E e0;
+
         @Stable
         private final E e1;
 
-        List2(E e0, E e1) {
+        List12(E e0) {
+            this.e0 = Objects.requireNonNull(e0);
+            this.e1 = null;
+        }
+
+        List12(E e0, E e1) {
             this.e0 = Objects.requireNonNull(e0);
             this.e1 = Objects.requireNonNull(e1);
         }
 
         @Override
         public int size() {
-            return 2;
+            return e1 != null ? 2 : 1;
         }
 
         @Override
@@ -195,20 +386,10 @@
             Objects.checkIndex(index, 2);
             if (index == 0) {
                 return e0;
-            } else { // index == 1
+            } else if (index == 1 && e1 != null) {
                 return e1;
             }
-        }
-
-        @Override
-        public boolean contains(Object o) {
-            return o.equals(e0) || o.equals(e1); // implicit nullcheck of o
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 31 + e0.hashCode();
-            return 31 * hash + e1.hashCode();
+            throw outOfBounds(index);
         }
 
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
@@ -216,11 +397,20 @@
         }
 
         private Object writeReplace() {
-            return new CollSer(CollSer.IMM_LIST, e0, e1);
+            if (e1 == null) {
+                return new CollSer(CollSer.IMM_LIST, e0);
+            } else {
+                return new CollSer(CollSer.IMM_LIST, e0, e1);
+            }
         }
+
     }
 
-    static final class ListN<E> extends AbstractImmutableList<E> {
+    static final class ListN<E> extends AbstractImmutableList<E>
+            implements Serializable {
+
+        static final List<?> EMPTY_LIST = new ListN<>();
+
         @Stable
         private final E[] elements;
 
@@ -232,7 +422,12 @@
             for (int i = 0; i < input.length; i++) {
                 tmp[i] = Objects.requireNonNull(input[i]);
             }
-            this.elements = tmp;
+            elements = tmp;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return size() == 0;
         }
 
         @Override
@@ -242,29 +437,9 @@
 
         @Override
         public E get(int index) {
-            Objects.checkIndex(index, elements.length);
             return elements[index];
         }
 
-        @Override
-        public boolean contains(Object o) {
-            for (E e : elements) {
-                if (o.equals(e)) { // implicit nullcheck of o
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public int hashCode() {
-            int hash = 1;
-            for (E e : elements) {
-                hash = 31 * hash + e.hashCode();
-            }
-            return hash;
-        }
-
         private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
             throw new InvalidObjectException("not serial proxy");
         }
diff --git a/ojluni/src/main/java/java/util/LinkedHashMap.java b/ojluni/src/main/java/java/util/LinkedHashMap.java
index 9d3815f..26f1880 100644
--- a/ojluni/src/main/java/java/util/LinkedHashMap.java
+++ b/ojluni/src/main/java/java/util/LinkedHashMap.java
@@ -491,6 +491,9 @@
     // Android-added: eldest(), for internal use in LRU caches
     /**
      * Returns the eldest entry in the map, or {@code null} if the map is empty.
+     *
+     * @return eldest entry in the map, or {@code null} if the map is empty
+     *
      * @hide
      */
     public Map.Entry<K, V> eldest() {
diff --git a/ojluni/src/main/java/java/util/List.java b/ojluni/src/main/java/java/util/List.java
index 1b9deb3..fca40ac 100644
--- a/ojluni/src/main/java/java/util/List.java
+++ b/ojluni/src/main/java/java/util/List.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -88,15 +88,16 @@
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
- * <h2><a id="immutable">Immutable List Static Factory Methods</a></h2>
- * <p>The {@link List#of(Object...) List.of()} static factory methods
- * provide a convenient way to create immutable lists. The {@code List}
+ * <h2><a id="unmodifiable">Unmodifiable Lists</a></h2>
+ * <p>The {@link List#of(Object...) List.of} and
+ * {@link List#copyOf List.copyOf} static factory methods
+ * provide a convenient way to create unmodifiable lists. The {@code List}
  * instances created by these methods have the following characteristics:
  *
  * <ul>
- * <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
- * or replaced. Calling any mutator method will always cause
- * {@code UnsupportedOperationException} to be thrown.
+ * <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Elements cannot
+ * be added, removed, or replaced. Calling any mutator method on the List
+ * will always cause {@code UnsupportedOperationException} to be thrown.
  * However, if the contained elements are themselves mutable,
  * this may cause the List's contents to appear to change.
  * <li>They disallow {@code null} elements. Attempts to create them with
@@ -796,9 +797,9 @@
     }
 
     /**
-     * Returns an immutable list containing zero elements.
+     * Returns an unmodifiable list containing zero elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @return an empty {@code List}
@@ -806,13 +807,13 @@
      * @since 9
      */
     static <E> List<E> of() {
-        return ImmutableCollections.List0.instance();
+        return ImmutableCollections.emptyList();
     }
 
     /**
-     * Returns an immutable list containing one element.
+     * Returns an unmodifiable list containing one element.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the single element
@@ -822,13 +823,13 @@
      * @since 9
      */
     static <E> List<E> of(E e1) {
-        return new ImmutableCollections.List1<>(e1);
+        return new ImmutableCollections.List12<>(e1);
     }
 
     /**
-     * Returns an immutable list containing two elements.
+     * Returns an unmodifiable list containing two elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -839,13 +840,13 @@
      * @since 9
      */
     static <E> List<E> of(E e1, E e2) {
-        return new ImmutableCollections.List2<>(e1, e2);
+        return new ImmutableCollections.List12<>(e1, e2);
     }
 
     /**
-     * Returns an immutable list containing three elements.
+     * Returns an unmodifiable list containing three elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -861,9 +862,9 @@
     }
 
     /**
-     * Returns an immutable list containing four elements.
+     * Returns an unmodifiable list containing four elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -880,9 +881,9 @@
     }
 
     /**
-     * Returns an immutable list containing five elements.
+     * Returns an unmodifiable list containing five elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -900,9 +901,9 @@
     }
 
     /**
-     * Returns an immutable list containing six elements.
+     * Returns an unmodifiable list containing six elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -922,9 +923,9 @@
     }
 
     /**
-     * Returns an immutable list containing seven elements.
+     * Returns an unmodifiable list containing seven elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -945,9 +946,9 @@
     }
 
     /**
-     * Returns an immutable list containing eight elements.
+     * Returns an unmodifiable list containing eight elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -969,9 +970,9 @@
     }
 
     /**
-     * Returns an immutable list containing nine elements.
+     * Returns an unmodifiable list containing nine elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -994,9 +995,9 @@
     }
 
     /**
-     * Returns an immutable list containing ten elements.
+     * Returns an unmodifiable list containing ten elements.
      *
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @param <E> the {@code List}'s element type
      * @param e1 the first element
@@ -1020,8 +1021,8 @@
     }
 
     /**
-     * Returns an immutable list containing an arbitrary number of elements.
-     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     * Returns an unmodifiable list containing an arbitrary number of elements.
+     * See <a href="#unmodifiable">Unmodifiable Lists</a> for details.
      *
      * @apiNote
      * This method also accepts a single array as an argument. The element type of
@@ -1049,13 +1050,33 @@
     static <E> List<E> of(E... elements) {
         switch (elements.length) { // implicit null check of elements
             case 0:
-                return ImmutableCollections.List0.instance();
+                return ImmutableCollections.emptyList();
             case 1:
-                return new ImmutableCollections.List1<>(elements[0]);
+                return new ImmutableCollections.List12<>(elements[0]);
             case 2:
-                return new ImmutableCollections.List2<>(elements[0], elements[1]);
+                return new ImmutableCollections.List12<>(elements[0], elements[1]);
             default:
                 return new ImmutableCollections.ListN<>(elements);
         }
     }
+
+    /**
+     * Returns an <a href="#unmodifiable">unmodifiable List</a> containing the elements of
+     * the given Collection, in its iteration order. The given Collection must not be null,
+     * and it must not contain any null elements. If the given Collection is subsequently
+     * modified, the returned List will not reflect such modifications.
+     *
+     * @implNote
+     * If the given Collection is an <a href="#unmodifiable">unmodifiable List</a>,
+     * calling copyOf will generally not create a copy.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param coll a {@code Collection} from which elements are drawn, must be non-null
+     * @return a {@code List} containing the elements of the given {@code Collection}
+     * @throws NullPointerException if coll is null, or if it contains any nulls
+     * @since 10
+     */
+    static <E> List<E> copyOf(Collection<? extends E> coll) {
+        return ImmutableCollections.listCopy(coll);
+    }
 }
diff --git a/ojluni/src/main/java/java/util/Locale.java b/ojluni/src/main/java/java/util/Locale.java
index 1ce4a202..80f9ed7 100644
--- a/ojluni/src/main/java/java/util/Locale.java
+++ b/ojluni/src/main/java/java/util/Locale.java
@@ -2750,24 +2750,6 @@
     }
     */
 
-    // 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);
-        // Map new language codes to the obsolete language
-        // codes so the correct resource bundles will be used.
-        if (languageCode.equals("he")) {
-            adjusted = "iw";
-        } else if (languageCode.equals("id")) {
-            adjusted = "in";
-        } else if (languageCode.equals("yi")) {
-            adjusted = "ji";
-        }
-
-        return adjusted;
-    }
-    // END Android-added: adjustLanguageCode(), for internal use only.
-
     /**
      * Enum for locale categories.  These locale categories are used to get/set
      * the default locale for the specific functionality represented by the
diff --git a/ojluni/src/main/java/java/util/Map.java b/ojluni/src/main/java/java/util/Map.java
index ed365ec..cf07a11 100644
--- a/ojluni/src/main/java/java/util/Map.java
+++ b/ojluni/src/main/java/java/util/Map.java
@@ -1653,4 +1653,30 @@
         // KeyValueHolder checks for nulls
         return new KeyValueHolder<>(k, v);
     }
+
+    /**
+     * Returns an <a href="#unmodifiable">unmodifiable Map</a> containing the entries
+     * of the given Map. The given Map must not be null, and it must not contain any
+     * null keys or values. If the given Map is subsequently modified, the returned
+     * Map will not reflect such modifications.
+     *
+     * @implNote
+     * If the given Map is an <a href="#unmodifiable">unmodifiable Map</a>,
+     * calling copyOf will generally not create a copy.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param map a {@code Map} from which entries are drawn, must be non-null
+     * @return a {@code Map} containing the entries of the given {@code Map}
+     * @throws NullPointerException if map is null, or if it contains any null keys or values
+     * @since 10
+     */
+    @SuppressWarnings({"rawtypes","unchecked"})
+    static <K, V> Map<K, V> copyOf(Map<? extends K, ? extends V> map) {
+        if (map instanceof ImmutableCollections.AbstractImmutableMap) {
+            return (Map<K,V>)map;
+        } else {
+            return (Map<K,V>)Map.ofEntries(map.entrySet().toArray(new Entry[0]));
+        }
+    }
 }
diff --git a/ojluni/src/main/java/java/util/Set.java b/ojluni/src/main/java/java/util/Set.java
index 0499ea3..c2f6560 100644
--- a/ojluni/src/main/java/java/util/Set.java
+++ b/ojluni/src/main/java/java/util/Set.java
@@ -700,4 +700,30 @@
                 return new ImmutableCollections.SetN<>(elements);
         }
     }
+
+    /**
+     * Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
+     * of the given Collection. The given Collection must not be null, and it must not
+     * contain any null elements. If the given Collection contains duplicate elements,
+     * an arbitrary element of the duplicates is preserved. If the given Collection is
+     * subsequently modified, the returned Set will not reflect such modifications.
+     *
+     * @implNote
+     * If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
+     * calling copyOf will generally not create a copy.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param coll a {@code Collection} from which elements are drawn, must be non-null
+     * @return a {@code Set} containing the elements of the given {@code Collection}
+     * @throws NullPointerException if coll is null, or if it contains any nulls
+     * @since 10
+     */
+    @SuppressWarnings("unchecked")
+    static <E> Set<E> copyOf(Collection<? extends E> coll) {
+        if (coll instanceof ImmutableCollections.AbstractImmutableSet) {
+            return (Set<E>)coll;
+        } else {
+            return (Set<E>)Set.of(new HashSet<>(coll).toArray());
+        }
+    }
 }
diff --git a/ojluni/src/main/java/java/util/TEST_MAPPING b/ojluni/src/main/java/java/util/TEST_MAPPING
index e1434fb..a8ec92d 100644
--- a/ojluni/src/main/java/java/util/TEST_MAPPING
+++ b/ojluni/src/main/java/java/util/TEST_MAPPING
@@ -10,7 +10,9 @@
           "include-filter": "org.apache.harmony.tests.java.util"
         }
       ]
-    },
+    }
+  ],
+  "presubmit-large": [
     {
       "name": "CtsLibcoreOjTestCases",
       "options": [
@@ -23,4 +25,4 @@
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/ojluni/src/main/java/java/util/TimeZone.java b/ojluni/src/main/java/java/util/TimeZone.java
index cf5e5f8..265a59d 100644
--- a/ojluni/src/main/java/java/util/TimeZone.java
+++ b/ojluni/src/main/java/java/util/TimeZone.java
@@ -40,6 +40,10 @@
 package java.util;
 
 import android.icu.text.TimeZoneNames;
+import com.android.i18n.timezone.ZoneInfoData;
+import com.android.i18n.timezone.ZoneInfoDb;
+import com.android.icu.util.ExtendedTimeZone;
+
 import java.io.IOException;
 import java.io.Serializable;
 import java.time.ZoneId;
@@ -47,7 +51,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import libcore.io.IoUtils;
-import libcore.timezone.ZoneInfoDb;
+import libcore.util.ZoneInfo;
 
 import dalvik.system.RuntimeHooks;
 
@@ -574,11 +578,9 @@
         }
 
         // In the database?
-        TimeZone zone = null;
-        try {
-            zone = ZoneInfoDb.getInstance().makeTimeZone(id);
-        } catch (IOException ignored) {
-        }
+
+        ZoneInfoData zoneInfoData = ZoneInfoDb.getInstance().makeZoneInfoData(id);
+        TimeZone zone = zoneInfoData == null ? null : ZoneInfo.createZoneInfo(zoneInfoData);
 
         // Custom time zone?
         if (zone == null && id.length() > 3 && id.startsWith("GMT")) {
@@ -745,7 +747,7 @@
         }
         defaultTimeZone = timeZone != null ? (TimeZone) timeZone.clone() : null;
         // Android-changed: notify ICU4J of changed default TimeZone.
-        android.icu.util.TimeZone.setICUDefault(null);
+        ExtendedTimeZone.clearDefaultTimeZone();
     }
 
     /**
diff --git a/ojluni/src/main/java/java/util/TreeMap.java b/ojluni/src/main/java/java/util/TreeMap.java
index 20d98bc..3359635 100644
--- a/ojluni/src/main/java/java/util/TreeMap.java
+++ b/ojluni/src/main/java/java/util/TreeMap.java
@@ -1343,7 +1343,7 @@
      */
     abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
         implements NavigableMap<K,V>, java.io.Serializable {
-        // Android-changed: Explicitly add a serialVersionUID so that we're serialization
+        // Android-changed: Explicitly add a serialVersionUID so that we're serialization.
         // compatible with the Java-7 version of this class. Several new methods were added
         // in Java-8 but none of them have any bearing on the serialized format of the class
         // or require any additional state to be preserved.
@@ -1877,11 +1877,11 @@
         }
 
         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
-            // BEGIN Android-changed: Fix for edge cases
+            // BEGIN Android-changed: Fix for edge cases.
             // if (!inRange(toKey, inclusive))
             if (!inRange(toKey) && !(!toEnd && m.compare(toKey, hi) == 0 &&
                 !hiInclusive && !inclusive))
-            // END Android-changed: Fix for edge cases
+            // END Android-changed: Fix for edge cases.
                 throw new IllegalArgumentException("toKey out of range");
             return new AscendingSubMap<>(m,
                                          fromStart, lo,    loInclusive,
@@ -1889,11 +1889,11 @@
         }
 
         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
-            // BEGIN Android-changed: Fix for edge cases
+            // BEGIN Android-changed: Fix for edge cases.
             // if (!inRange(fromKey, inclusive))
             if (!inRange(fromKey) && !(!fromStart && m.compare(fromKey, lo) == 0 &&
                 !loInclusive && !inclusive))
-            // END Android-changed: Fix for edge cases
+            // END Android-changed: Fix for edge cases.
                 throw new IllegalArgumentException("fromKey out of range");
             return new AscendingSubMap<>(m,
                                          false, fromKey, inclusive,
@@ -1970,11 +1970,11 @@
         }
 
         public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
-            // BEGIN Android-changed: Fix for edge cases
+            // BEGIN Android-changed: Fix for edge cases.
             // if (!inRange(toKey, inclusive))
             if (!inRange(toKey) && !(!fromStart && m.compare(toKey, lo) == 0 &&
                 !loInclusive && !inclusive))
-            // END Android-changed: Fix for edge cases
+            // END Android-changed: Fix for edge cases.
                 throw new IllegalArgumentException("toKey out of range");
             return new DescendingSubMap<>(m,
                                           false, toKey, inclusive,
@@ -1982,11 +1982,11 @@
         }
 
         public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
-            // BEGIN Android-changed: Fix for edge cases
+            // BEGIN Android-changed: Fix for edge cases.
             // if (!inRange(fromKey, inclusive))
             if (!inRange(fromKey) && !(!toEnd && m.compare(fromKey, hi) == 0 &&
                 !hiInclusive && !inclusive))
-            // END Android-changed: Fix for edge cases
+            // 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/concurrent/CompletableFuture.java b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
index 976bfe4..e98e1be 100644
--- a/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
+++ b/ojluni/src/main/java/java/util/concurrent/CompletableFuture.java
@@ -2407,7 +2407,6 @@
      * @param <U> the type of the value
      * @return a new CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public <U> CompletableFuture<U> newIncompleteFuture() {
         return new CompletableFuture<U>();
@@ -2423,7 +2422,6 @@
      *
      * @return the executor
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public Executor defaultExecutor() {
         return ASYNC_POOL;
@@ -2442,7 +2440,6 @@
      *
      * @return the new CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletableFuture<T> copy() {
         return uniCopyStage();
@@ -2460,7 +2457,6 @@
      *
      * @return the new CompletionStage
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletionStage<T> minimalCompletionStage() {
         return uniAsMinimalStage();
@@ -2476,7 +2472,6 @@
      * @param executor the executor to use for asynchronous execution
      * @return this CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier,
                                               Executor executor) {
@@ -2495,7 +2490,6 @@
      * to complete this CompletableFuture
      * @return this CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletableFuture<T> completeAsync(Supplier<? extends T> supplier) {
         return completeAsync(supplier, defaultExecutor());
@@ -2512,7 +2506,6 @@
      *        {@code timeout} parameter
      * @return this CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit) {
         if (unit == null)
@@ -2534,7 +2527,6 @@
      *        {@code timeout} parameter
      * @return this CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public CompletableFuture<T> completeOnTimeout(T value, long timeout,
                                                   TimeUnit unit) {
@@ -2559,7 +2551,6 @@
      * @param executor the base executor
      * @return the new delayed executor
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public static Executor delayedExecutor(long delay, TimeUnit unit,
                                            Executor executor) {
@@ -2579,7 +2570,6 @@
      *        {@code delay} parameter
      * @return the new delayed executor
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public static Executor delayedExecutor(long delay, TimeUnit unit) {
         if (unit == null)
@@ -2596,7 +2586,6 @@
      * @param <U> the type of the value
      * @return the completed CompletionStage
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public static <U> CompletionStage<U> completedStage(U value) {
         return new MinimalStage<U>((value == null) ? NIL : value);
@@ -2610,7 +2599,6 @@
      * @param <U> the type of the value
      * @return the exceptionally completed CompletableFuture
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public static <U> CompletableFuture<U> failedFuture(Throwable ex) {
         if (ex == null) throw new NullPointerException();
@@ -2626,7 +2614,6 @@
      * @param <U> the type of the value
      * @return the exceptionally completed CompletionStage
      * @since 9
-     * @hide API from OpenJDK 9, not yet exposed on Android.
      */
     public static <U> CompletionStage<U> failedStage(Throwable ex) {
         if (ex == null) throw new NullPointerException();
diff --git a/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java b/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
index c32e2d1..6b9fcc3 100644
--- a/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
+++ b/ojluni/src/main/java/java/util/concurrent/ScheduledExecutorService.java
@@ -80,7 +80,7 @@
  *     final Runnable beeper = new Runnable() {
  *       public void run() { System.out.println("beep"); }
  *     };
- *     final ScheduledFuture<?> beeperHandle =
+ *     final ScheduledFuture&lt;?&lt; beeperHandle =
  *       scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
  *     scheduler.schedule(new Runnable() {
  *       public void run() { beeperHandle.cancel(true); }
diff --git a/ojluni/src/main/java/java/util/regex/Pattern.java b/ojluni/src/main/java/java/util/regex/Pattern.java
index a4ead58..bd7ba5b 100644
--- a/ojluni/src/main/java/java/util/regex/Pattern.java
+++ b/ojluni/src/main/java/java/util/regex/Pattern.java
@@ -883,7 +883,10 @@
      */
     public static final int UNICODE_CASE = 0x40;
 
+    // Android-changed: Android does not support CANON_EQ flag.
     /**
+     * This flag is not supported on Android.
+     *
      * Enables canonical equivalence.
      *
      * <p> When this flag is specified then two characters will be considered
@@ -901,15 +904,15 @@
 
     // Android-changed: Android always uses unicode character classes.
     /**
+     * This flag is not supported on Android, and Unicode character classes are always
+     * used.
+     *
      * Enables the Unicode version of <i>Predefined character classes</i> and
      * <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>
      *
-     * This flag has no effect on Android, unicode character classes are always
-     * used.
-     *
      * @since 1.7
      */
     public static final int UNICODE_CHARACTER_CLASS = 0x100;
@@ -959,6 +962,7 @@
         return new Pattern(regex, 0);
     }
 
+    // Android-changed: Android doesn't support CANON_EQ and UNICODE_CHARACTER_CLASS flags.
     /**
      * Compiles the given regular expression into a pattern with the given
      * flags.
@@ -969,8 +973,7 @@
      * @param  flags
      *         Match flags, a bit mask that may include
      *         {@link #CASE_INSENSITIVE}, {@link #MULTILINE}, {@link #DOTALL},
-     *         {@link #UNICODE_CASE}, {@link #CANON_EQ}, {@link #UNIX_LINES},
-     *         {@link #LITERAL}, {@link #UNICODE_CHARACTER_CLASS}
+     *         {@link #UNICODE_CASE}, {@link #UNIX_LINES}, {@link #LITERAL},
      *         and {@link #COMMENTS}
      *
      * @return the given regular expression compiled into a pattern with the given flags
diff --git a/ojluni/src/main/java/java/util/stream/TEST_MAPPING b/ojluni/src/main/java/java/util/stream/TEST_MAPPING
index 9673e09..d2efaa1 100644
--- a/ojluni/src/main/java/java/util/stream/TEST_MAPPING
+++ b/ojluni/src/main/java/java/util/stream/TEST_MAPPING
@@ -1,5 +1,5 @@
 {
-  "presubmit": [
+  "presubmit-large": [
     {
       "name": "CtsLibcoreOjTestCases",
       "options": [
@@ -15,4 +15,4 @@
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/ojluni/src/main/java/java/util/zip/ZipEntry.java b/ojluni/src/main/java/java/util/zip/ZipEntry.java
index 0de6756..b9c1440 100644
--- a/ojluni/src/main/java/java/util/zip/ZipEntry.java
+++ b/ojluni/src/main/java/java/util/zip/ZipEntry.java
@@ -164,11 +164,12 @@
      */
     ZipEntry() {}
 
-    // Android-added: Add dataOffset for internal use.
+    // BEGIN Android-added: Add dataOffset for internal use.
     /** @hide */
     public long getDataOffset() {
         return dataOffset;
     }
+    // END Android-added: Add dataOffset for internal use.
 
     /**
      * Returns the name of the entry.
diff --git a/ojluni/src/main/java/java/util/zip/ZipFile.java b/ojluni/src/main/java/java/util/zip/ZipFile.java
index 851aab1..e06fb6d 100644
--- a/ojluni/src/main/java/java/util/zip/ZipFile.java
+++ b/ojluni/src/main/java/java/util/zip/ZipFile.java
@@ -81,7 +81,7 @@
     private final boolean locsig;  // if zip file starts with LOCSIG (usually true)
     private volatile boolean closeRequested = false;
 
-    // Android-added: CloseGuard support
+    // Android-added: CloseGuard support.
     private final CloseGuard guard = CloseGuard.get();
 
     // Android-added: Do not use unlink() to implement OPEN_DELETE.
@@ -243,7 +243,7 @@
                                                Integer.toHexString(mode));
         }
         String name = file.getPath();
-        // Android-removed: SecurityManager is always null
+        // Android-removed: SecurityManager is always null.
         /*
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
@@ -260,16 +260,16 @@
         if (charset == null)
             throw new NullPointerException("charset is null");
         this.zc = ZipCoder.get(charset);
-        // Android-removed: Skip perf counters
+        // Android-removed: Skip perf counters.
         // long t0 = System.nanoTime();
         jzfile = open(name, mode, file.lastModified(), usemmap);
-        // Android-removed: 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);
-        // Android-added: CloseGuard support
+        // Android-added: CloseGuard support.
         guard.open("close");
     }
 
@@ -668,7 +668,7 @@
     public void close() throws IOException {
         if (closeRequested)
             return;
-        // Android-added: CloseGuard support
+        // Android-added: CloseGuard support.
         if (guard != null) {
             guard.close();
         }
@@ -739,7 +739,7 @@
      * @see    java.util.zip.ZipFile#close()
      */
     protected void finalize() throws IOException {
-        // Android-added: CloseGuard support
+        // Android-added: CloseGuard support.
         if (guard != null) {
             guard.warnIfOpen();
         }
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index c3e3c30..9d5a738 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -30,7 +30,6 @@
 import java.net.HttpURLConnection;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
-import libcore.api.CorePlatformApi;
 
 /**
  * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
@@ -324,16 +323,18 @@
 
     // BEGIN Android-added: Core platform API to obtain a strict hostname verifier
     /**
-     * Obtains a stricter <code>HostnameVerifier</code>.
+     * Obtains a stricter {@code HostnameVerifier}.
      *
-     * The <code>HostnameVerifier</code> returned by this method will reject certificates
+     * The {@code HostnameVerifier} returned by this method will reject certificates
      * with wildcards for top-level domains such "*.com".
      *
+     * This is a vendor hook (called from Zygote init code) to allow stricter hostname
+     * checking on NIAP-certified devices.
+     *
      * @see com.squareup.okhttp.internal.tls.OkHostnameVerifier
      *
      * @hide
      */
-    @CorePlatformApi
     public static HostnameVerifier getStrictHostnameVerifier() {
         try {
             return (HostnameVerifier) Class
diff --git a/ojluni/src/main/java/sun/misc/Cleaner.java b/ojluni/src/main/java/sun/misc/Cleaner.java
index 5e92f35..e4826f6 100644
--- a/ojluni/src/main/java/sun/misc/Cleaner.java
+++ b/ojluni/src/main/java/sun/misc/Cleaner.java
@@ -55,7 +55,6 @@
  *
  * @author Mark Reinhold
  */
-
 public class Cleaner
     extends PhantomReference<Object>
 {
diff --git a/ojluni/src/main/java/sun/misc/SharedSecrets.java b/ojluni/src/main/java/sun/misc/SharedSecrets.java
index 45cd489..226dbf7 100644
--- a/ojluni/src/main/java/sun/misc/SharedSecrets.java
+++ b/ojluni/src/main/java/sun/misc/SharedSecrets.java
@@ -35,7 +35,7 @@
     for this purpose, namely the loss of compile-time checking. */
 
 public class SharedSecrets {
-    // BEGIN Android-removed: Pruned unused access interfaces
+    // BEGIN Android-removed: Pruned unused access interfaces.
     /*
     private static final Unsafe unsafe = Unsafe.getUnsafe();
     private static JavaUtilJarAccess javaUtilJarAccess;
@@ -46,9 +46,9 @@
     private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
     private static JavaNioAccess javaNioAccess;
     */
-    // END Android-removed: Pruned unused access interfaces
+    // END Android-removed: Pruned unused access interfaces.
     private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
-    // BEGIN Android-removed: Pruned unused access interfaces
+    // BEGIN Android-removed: Pruned unused access interfaces.
     /*
     private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess;
     private static JavaSecurityAccess javaSecurityAccess;
@@ -129,7 +129,7 @@
         return javaIOAccess;
     }
     */
-    // END Android-removed: Pruned unused access interfaces
+    // END Android-removed: Pruned unused access interfaces.
 
     public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
         javaIOFileDescriptorAccess = jiofda;
@@ -150,7 +150,7 @@
         return javaIOFileDescriptorAccess;
     }
 
-    // BEGIN Android-removed: Pruned unused access interfaces
+    // BEGIN Android-removed: Pruned unused access interfaces.
     /*
     public static void setJavaOISAccess(JavaOISAccess access) {
         javaOISAccess = access;
@@ -221,5 +221,5 @@
         javaObjectInputStreamAccess = access;
     }
     */
-    // END Android-removed: Pruned unused access interfaces
+    // END Android-removed: Pruned unused access interfaces.
 }
diff --git a/ojluni/src/main/java/sun/misc/URLClassPath.java b/ojluni/src/main/java/sun/misc/URLClassPath.java
index e9a89bc..0961d7a 100644
--- a/ojluni/src/main/java/sun/misc/URLClassPath.java
+++ b/ojluni/src/main/java/sun/misc/URLClassPath.java
@@ -360,7 +360,7 @@
         lookupCacheEnabled = false;
     }
 
-    // BEGIN Android-changed: No lookup chache support
+    // BEGIN Android-changed: No lookup cache support.
     /*
     private static native URL[] getLookupCacheURLs(ClassLoader loader);
     private static native int[] getLookupCacheForClassLoader(ClassLoader loader,
@@ -380,7 +380,7 @@
                                             String className) {
         return false;
     }
-    // END Android-changed: No lookup chache support
+    // END Android-changed: No lookup cache support.
 
 
     synchronized boolean knownToNotExist(String className) {
@@ -816,7 +816,7 @@
         private final HashMap<String, Loader> lmap;
         private final AccessControlContext acc;
         private boolean closed = false;
-        // Android-changed: Not needed, called directly
+        // Android-changed: Not needed, called directly.
         // private static final sun.misc.JavaUtilZipFileAccess zipAccess =
         //      sun.misc.SharedSecrets.getJavaUtilZipFileAccess();
 
diff --git a/ojluni/src/main/java/sun/misc/Unsafe.java b/ojluni/src/main/java/sun/misc/Unsafe.java
index 2473f65..e538b73 100644
--- a/ojluni/src/main/java/sun/misc/Unsafe.java
+++ b/ojluni/src/main/java/sun/misc/Unsafe.java
@@ -73,7 +73,7 @@
      * Gets the raw byte offset from the start of an object's memory to
      * the memory used to store the indicated instance field.
      *
-     * @param field non-null; the field in question, which must be an
+     * @param field non-{@code null}; the field in question, which must be an
      * instance field
      * @return the offset to the field
      */
@@ -88,7 +88,7 @@
      * Gets the offset from the start of an array object's memory to
      * the memory used to store its initial (zeroeth) element.
      *
-     * @param clazz non-null; class in question; must be an array class
+     * @param clazz non-{@code null}; class in question; must be an array class
      * @return the offset to the initial element
      */
     public int arrayBaseOffset(Class clazz) {
@@ -102,7 +102,7 @@
     /**
      * Gets the size of each element of the given array class.
      *
-     * @param clazz non-null; class in question; must be an array class
+     * @param clazz non-{@code null}; class in question; must be an array class
      * @return &gt; 0; the size of each element of the array
      */
     public int arrayIndexScale(Class clazz) {
@@ -119,114 +119,114 @@
     private static native int getArrayIndexScaleForComponentType(Class component_class);
 
     /**
-     * Performs a compare-and-set operation on an <code>int</code>
+     * Performs a compare-and-set operation on an {@code int}
      * field within the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param expectedValue expected value of the field
      * @param newValue new value to store in the field if the contents are
      * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
+     * @return {@code true} if the new value was in fact stored, and
+     * {@code false} if not
      */
     @FastNative
     public native boolean compareAndSwapInt(Object obj, long offset,
             int expectedValue, int newValue);
 
     /**
-     * Performs a compare-and-set operation on a <code>long</code>
+     * Performs a compare-and-set operation on a {@code long}
      * field within the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param expectedValue expected value of the field
      * @param newValue new value to store in the field if the contents are
      * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
+     * @return {@code true} if the new value was in fact stored, and
+     * {@code false} if not
      */
     @FastNative
     public native boolean compareAndSwapLong(Object obj, long offset,
             long expectedValue, long newValue);
 
     /**
-     * Performs a compare-and-set operation on an <code>Object</code>
+     * Performs a compare-and-set operation on an {@code obj}
      * field (that is, a reference field) within the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param expectedValue expected value of the field
      * @param newValue new value to store in the field if the contents are
      * as expected
-     * @return <code>true</code> if the new value was in fact stored, and
-     * <code>false</code> if not
+     * @return {@code true} if the new value was in fact stored, and
+     * {@code false} if not
      */
     @FastNative
     public native boolean compareAndSwapObject(Object obj, long offset,
             Object expectedValue, Object newValue);
 
     /**
-     * Gets an <code>int</code> field from the given object,
-     * using <code>volatile</code> semantics.
+     * Gets an {@code int} field from the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native int getIntVolatile(Object obj, long offset);
 
     /**
-     * Stores an <code>int</code> field into the given object,
-     * using <code>volatile</code> semantics.
+     * Stores an {@code int} field into the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
     public native void putIntVolatile(Object obj, long offset, int newValue);
 
     /**
-     * Gets a <code>long</code> field from the given object,
-     * using <code>volatile</code> semantics.
+     * Gets a {@code long} field from the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native long getLongVolatile(Object obj, long offset);
 
     /**
-     * Stores a <code>long</code> field into the given object,
-     * using <code>volatile</code> semantics.
+     * Stores a {@code long} field into the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
     public native void putLongVolatile(Object obj, long offset, long newValue);
 
     /**
-     * Gets an <code>Object</code> field from the given object,
-     * using <code>volatile</code> semantics.
+     * Gets an {@code obj} field from the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native Object getObjectVolatile(Object obj, long offset);
 
     /**
-     * Stores an <code>Object</code> field into the given object,
-     * using <code>volatile</code> semantics.
+     * Stores an {@code obj} field into the given object,
+     * using {@code volatile} semantics.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
@@ -234,20 +234,20 @@
             Object newValue);
 
     /**
-     * Gets an <code>int</code> field from the given object.
+     * Gets an {@code int} field from the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing int field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native int getInt(Object obj, long offset);
 
     /**
-     * Stores an <code>int</code> field into the given object.
+     * Stores an {@code int} field into the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing int field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
@@ -255,25 +255,29 @@
 
     /**
      * Lazy set an int field.
+     *
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
      */
     @FastNative
     public native void putOrderedInt(Object obj, long offset, int newValue);
 
     /**
-     * Gets a <code>long</code> field from the given object.
+     * Gets a {@code long} field from the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native long getLong(Object obj, long offset);
 
     /**
-     * Stores a <code>long</code> field into the given object.
+     * Stores a {@code long} field into the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
@@ -281,25 +285,29 @@
 
     /**
      * Lazy set a long field.
+     *
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
      */
     @FastNative
     public native void putOrderedLong(Object obj, long offset, long newValue);
 
     /**
-     * Gets an <code>Object</code> field from the given object.
+     * Gets an {@code obj} field from the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @return the retrieved value
      */
     @FastNative
     public native Object getObject(Object obj, long offset);
 
     /**
-     * Stores an <code>Object</code> field into the given object.
+     * Stores an {@code obj} field into the given object.
      *
-     * @param obj non-null; object containing the field
-     * @param offset offset to the field within <code>obj</code>
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
      * @param newValue the value to store
      */
     @FastNative
@@ -307,34 +315,132 @@
 
     /**
      * Lazy set an object field.
+     *
+     * @param obj non-{@code null}; object containing the field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
      */
     @FastNative
     public native void putOrderedObject(Object obj, long offset,
             Object newValue);
 
-
+    /**
+     * Gets a {@code boolean} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing boolean field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native boolean getBoolean(Object obj, long offset);
+
+    /**
+     * Stores a {@code boolean} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing boolean field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putBoolean(Object obj, long offset, boolean newValue);
+
+    /**
+     * Gets a {@code byte} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing byte field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native byte getByte(Object obj, long offset);
+
+    /**
+     * Stores a {@code byte} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing byte field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putByte(Object obj, long offset, byte newValue);
+
+    /**
+     * Gets a {@code char} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing char field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native char getChar(Object obj, long offset);
+
+    /**
+     * Stores a {@code char} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing char field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putChar(Object obj, long offset, char newValue);
+
+    /**
+     * Gets a {@code short} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing short field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native short getShort(Object obj, long offset);
+
+    /**
+     * Stores a {@code short} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing short field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putShort(Object obj, long offset, short newValue);
+
+    /**
+     * Gets a {@code float} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing float field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native float getFloat(Object obj, long offset);
+
+    /**
+     * Stores a {@code float} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing float field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putFloat(Object obj, long offset, float newValue);
+
+    /**
+     * Gets a {@code double} field from the given object.
+     *
+     * @param obj non-{@code null}; object containing double field
+     * @param offset offset to the field within {@code obj}
+     * @return the retrieved value
+     */
     @FastNative
     public native double getDouble(Object obj, long offset);
+
+    /**
+     * Stores a {@code double} field into the given object.
+     *
+     * @param obj non-{@code null}; object containing double field
+     * @param offset offset to the field within {@code obj}
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putDouble(Object obj, long offset, double newValue);
 
@@ -349,10 +455,11 @@
      * in-depth information of the behavior of this method.</p>
      *
      * @param absolute whether the given time value is absolute
-     * milliseconds-since-the-epoch (<code>true</code>) or relative
-     * nanoseconds-from-now (<code>false</code>)
+     * milliseconds-since-the-epoch ({@code true}) or relative
+     * nanoseconds-from-now ({@code false})
      * @param time the (absolute millis or relative nanos) time value
      */
+
     public native void park(boolean absolute, long time);
     /**
      * Unparks the given object, which must be a {@link Thread}.
@@ -360,81 +467,219 @@
      * <p>See {@link java.util.concurrent.locks.LockSupport} for more
      * in-depth information of the behavior of this method.</p>
      *
-     * @param obj non-null; the object to unpark
+     * @param obj non-{@code null}; the object to unpark
      */
     @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.
      */
     public native Object allocateInstance(Class<?> c);
 
+    /**
+     * Gets the size of the address value, in bytes.
+     *
+     * @return the size of the address, in bytes
+     */
     @FastNative
     public native int addressSize();
 
+    /**
+     * Gets the size of the memory page, in bytes.
+     *
+     * @return the size of the page
+     */
     @FastNative
     public native int pageSize();
 
+    /**
+     * Allocates a memory block of size {@code bytes}.
+     *
+     * @param bytes size of the memory block
+     * @return address of the allocated memory
+     */
     @FastNative
     public native long allocateMemory(long bytes);
 
+    /**
+     * Frees previously allocated memory at given address.
+     *
+     * @param address address of the freed memory
+     */
     @FastNative
     public native void freeMemory(long address);
 
+    /**
+     * Fills given memory block with a given value.
+     *
+     * @param address address of the memoory block
+     * @param bytes length of the memory block, in bytes
+     * @param value fills memory with this value
+     */
     @FastNative
     public native void setMemory(long address, long bytes, byte value);
 
+    /**
+     * Gets {@code byte} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code byte} value
+     */
     @FastNative
     public native byte getByte(long address);
 
+    /**
+     * Stores a {@code byte} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putByte(long address, byte x);
 
+    /**
+     * Gets {@code short} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code short} value
+     */
     @FastNative
     public native short getShort(long address);
 
+    /**
+     * Stores a {@code short} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putShort(long address, short x);
 
+    /**
+     * Gets {@code char} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code char} value
+     */
     @FastNative
     public native char getChar(long address);
 
+    /**
+     * Stores a {@code char} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putChar(long address, char x);
 
+    /**
+     * Gets {@code int} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code int} value
+     */
     @FastNative
     public native int getInt(long address);
 
+    /**
+     * Stores a {@code int} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putInt(long address, int x);
 
+
+    /**
+     * Gets {@code long} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code long} value
+     */
     @FastNative
     public native long getLong(long address);
 
+    /**
+     * Stores a {@code long} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putLong(long address, long x);
 
+    /**
+     * Gets {@code long} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code long} value
+     */
     @FastNative
     public native float getFloat(long address);
 
+    /**
+     * Stores a {@code float} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putFloat(long address, float x);
 
+    /**
+     * Gets {@code double} from given address in memory.
+     *
+     * @param address address in memory
+     * @return {@code double} value
+     */
     @FastNative
     public native double getDouble(long address);
 
+    /**
+     * Stores a {@code double} into the given memory address.
+     *
+     * @param address address in memory where to store the value
+     * @param newValue the value to store
+     */
     @FastNative
     public native void putDouble(long address, double x);
 
+    /**
+     * Copies given memory block to a primitive array.
+     *
+     * @param srcAddr address to copy memory from
+     * @param dst address to copy memory to
+     * @param dstOffset offset in {@code dst}
+     * @param bytes number of bytes to copy
+     */
     @FastNative
     public native void copyMemoryToPrimitiveArray(long srcAddr,
             Object dst, long dstOffset, long bytes);
 
+    /**
+     * Treat given primitive array as a continuous memory block and
+     * copy it to given memory address.
+     *
+     * @param src primitive array to copy data from
+     * @param srcOffset offset in {@code src} to copy from
+     * @param dstAddr memory address to copy data to
+     * @param bytes number of bytes to copy
+     */
     @FastNative
     public native void copyMemoryFromPrimitiveArray(Object src, long srcOffset,
             long dstAddr, long bytes);
 
+    /**
+     * Sets all bytes in a given block of memory to a copy of another block.
+     *
+     * @param srcAddr address of the source memory to be copied from
+     * @param dstAddr address of the destination memory to copy to
+     * @param bytes number of bytes to copy
+     */
     @FastNative
     public native void copyMemory(long srcAddr, long dstAddr, long bytes);
 
diff --git a/ojluni/src/main/java/sun/misc/VM.java b/ojluni/src/main/java/sun/misc/VM.java
index f9060ba..0c5c4e5 100644
--- a/ojluni/src/main/java/sun/misc/VM.java
+++ b/ojluni/src/main/java/sun/misc/VM.java
@@ -93,7 +93,7 @@
         return STATE_GREEN;
     }
 
-    // Android-removed: Not used
+    // Android-removed: Not used.
     /** @deprecated */
     // @Deprecated
     // public static void registerVMNotification(VMNotification n) { }
@@ -233,7 +233,7 @@
         return allowArraySyntax;
     }
 
-    // BEGIN Android-removed: Not used on android
+    // BEGIN Android-removed: Not used on android.
     /**
      * Returns true if the given class loader is in the system domain
      * in which all permissions are granted.
@@ -241,7 +241,7 @@
     // public static boolean isSystemDomainLoader(ClassLoader loader) {
     //     return loader == null;
     // }
-    // END Android-removed: Not used on android
+    // END Android-removed: Not used on android.
 
     /**
      * Returns the system property of the specified key saved at
@@ -403,7 +403,7 @@
     private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
     private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
 
-    // BEGIN Android-removed: latestUserDefinedLoader()/initialize() not supported
+    // BEGIN Android-removed: latestUserDefinedLoader()/initialize() not supported.
     // /*
     //  * Returns the first non-null class loader up the execution stack,
     //  * or null if only code from the null class loader is on the stack.
@@ -414,5 +414,5 @@
     //     initialize();
     // }
     // private native static void initialize();
-    // END Android-removed: latestUserDefinedLoader()/initialize() not supported
+    // END Android-removed: latestUserDefinedLoader()/initialize() not supported.
 }
diff --git a/ojluni/src/main/java/sun/nio/fs/UnixChannelFactory.java b/ojluni/src/main/java/sun/nio/fs/UnixChannelFactory.java
index 9491fd9..c6f074e 100644
--- a/ojluni/src/main/java/sun/nio/fs/UnixChannelFactory.java
+++ b/ojluni/src/main/java/sun/nio/fs/UnixChannelFactory.java
@@ -47,13 +47,6 @@
     private static final JavaIOFileDescriptorAccess fdAccess =
         SharedSecrets.getJavaIOFileDescriptorAccess();
 
-    static {
-        // b/151107960. This class is on the preloaded-classes-blacklist.
-        // It would be instantiated during AOT now without this magic
-        // function call and consequently fail 'atest PreloadCheck'.
-        dalvik.system.VMRuntime.doNotInitializeInAot();
-    }
-
     protected UnixChannelFactory() {
     }
 
diff --git a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
index b4fdf70..6af86d5 100644
--- a/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
+++ b/ojluni/src/main/java/sun/reflect/misc/ReflectUtil.java
@@ -116,7 +116,7 @@
         return false;
     }
 
-    // Android-removed: Dead code: Unused method conservativeCheckMemberAccess()
+    // Android-removed: Dead code: Unused method conservativeCheckMemberAccess().
 
     /**
      * Checks package access on the given class.
@@ -262,6 +262,6 @@
         return Proxy.isProxyClass(cls) && !pkg.isEmpty();
     }
 
-    // Android-removed: Dead code: unused method checkProxyMethod()
-    // Android-removed: Dead code: unused method isVMAnonymousClass()
+    // Android-removed: Dead code: unused method checkProxyMethod().
+    // Android-removed: Dead code: unused method isVMAnonymousClass().
 }
diff --git a/ojluni/src/main/java/sun/security/jca/Providers.java b/ojluni/src/main/java/sun/security/jca/Providers.java
index a9634f0..dbd40ee 100644
--- a/ojluni/src/main/java/sun/security/jca/Providers.java
+++ b/ojluni/src/main/java/sun/security/jca/Providers.java
@@ -140,8 +140,10 @@
     /**
      * Start JAR verification. This sets a special provider list for
      * the current thread. You MUST save the return value from this
-     * method and you MUST call stopJarVerification() with that object
+     * method and you MUST call {@link #stopJarVerification(Object)} with that object
      * once you are done.
+     *
+     * @return old thread-local provider
      */
     public static Object startJarVerification() {
         ProviderList currentList = getProviderList();
@@ -151,7 +153,11 @@
     }
 
     /**
-     * Stop JAR verification. Call once you have completed JAR verification.
+     * Stop JAR verification. Call once you have completed JAR verification,
+     * passing previously saved return value of {@link #startJarVerification()}.
+     *
+     * @param obj previously saved from {@link #startJarVerification()} old
+     *            thread-local provider list
      */
     public static void stopJarVerification(Object obj) {
         // restore old thread-local provider list
@@ -348,194 +354,11 @@
     }
 
     // The set of algorithms that are deprecated.  This list is created using
-    // libcore/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java, with
-    // additional Ciphers added manually (see comment below).
+    // libcore/tools/crypto/src/java/libcore/java/security/ProviderOverlap.java.
     private static final Set<String> DEPRECATED_ALGORITHMS = new HashSet<String>();
     static {
         DEPRECATED_ALGORITHMS.addAll(Arrays.asList(
-                "ALGORITHMPARAMETERS.1.2.840.113549.3.7",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.2",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.22",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.26",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.42",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.46",
-                "ALGORITHMPARAMETERS.2.16.840.1.101.3.4.1.6",
-                "ALGORITHMPARAMETERS.AES",
-                "ALGORITHMPARAMETERS.DESEDE",
-                "ALGORITHMPARAMETERS.EC",
-                "ALGORITHMPARAMETERS.GCM",
-                "ALGORITHMPARAMETERS.OAEP",
-                "ALGORITHMPARAMETERS.TDEA",
-                "CERTIFICATEFACTORY.X.509",
-                "CERTIFICATEFACTORY.X509",
-                // List of Ciphers produced by ProviderOverlap:
-                "CIPHER.1.2.840.113549.3.4",
-                "CIPHER.2.16.840.1.101.3.4.1.26",
-                "CIPHER.2.16.840.1.101.3.4.1.46",
-                "CIPHER.2.16.840.1.101.3.4.1.6",
-                "CIPHER.AES/GCM/NOPADDING",
-                "CIPHER.ARC4",
-                "CIPHER.ARCFOUR",
-                "CIPHER.OID.1.2.840.113549.3.4",
-                "CIPHER.RC4",
-                // End of Ciphers produced by ProviderOverlap
-                // Additional ciphers transformations that will resolve to the same things as
-                // the automatically-produced overlap due to the Cipher transformation rules.
-                // These have been added manually.
-                "CIPHER.ARC4/ECB/NOPADDING",
-                "CIPHER.ARC4/NONE/NOPADDING",
-                "CIPHER.ARCFOUR/ECB/NOPADDING",
-                "CIPHER.ARCFOUR/NONE/NOPADDING",
-                "CIPHER.RC4/ECB/NOPADDING",
-                "CIPHER.RC4/NONE/NOPADDING",
-                // End of additional Ciphers
-                "KEYAGREEMENT.ECDH",
-                "KEYFACTORY.1.2.840.10045.2.1",
-                "KEYFACTORY.1.2.840.113549.1.1.1",
-                "KEYFACTORY.1.2.840.113549.1.1.7",
-                "KEYFACTORY.1.3.133.16.840.63.0.2",
-                "KEYFACTORY.2.5.8.1.1",
-                "KEYFACTORY.EC",
-                "KEYFACTORY.RSA",
-                "KEYGENERATOR.1.2.840.113549.2.10",
-                "KEYGENERATOR.1.2.840.113549.2.11",
-                "KEYGENERATOR.1.2.840.113549.2.7",
-                "KEYGENERATOR.1.2.840.113549.2.8",
-                "KEYGENERATOR.1.2.840.113549.2.9",
-                "KEYGENERATOR.1.3.6.1.5.5.8.1.1",
-                "KEYGENERATOR.1.3.6.1.5.5.8.1.2",
-                "KEYGENERATOR.2.16.840.1.101.3.4.2.1",
-                "KEYGENERATOR.AES",
-                "KEYGENERATOR.DESEDE",
-                "KEYGENERATOR.HMAC-MD5",
-                "KEYGENERATOR.HMAC-SHA1",
-                "KEYGENERATOR.HMAC-SHA224",
-                "KEYGENERATOR.HMAC-SHA256",
-                "KEYGENERATOR.HMAC-SHA384",
-                "KEYGENERATOR.HMAC-SHA512",
-                "KEYGENERATOR.HMAC/MD5",
-                "KEYGENERATOR.HMAC/SHA1",
-                "KEYGENERATOR.HMAC/SHA224",
-                "KEYGENERATOR.HMAC/SHA256",
-                "KEYGENERATOR.HMAC/SHA384",
-                "KEYGENERATOR.HMAC/SHA512",
-                "KEYGENERATOR.HMACMD5",
-                "KEYGENERATOR.HMACSHA1",
-                "KEYGENERATOR.HMACSHA224",
-                "KEYGENERATOR.HMACSHA256",
-                "KEYGENERATOR.HMACSHA384",
-                "KEYGENERATOR.HMACSHA512",
-                "KEYGENERATOR.TDEA",
-                "KEYPAIRGENERATOR.1.2.840.10045.2.1",
-                "KEYPAIRGENERATOR.1.2.840.113549.1.1.1",
-                "KEYPAIRGENERATOR.1.2.840.113549.1.1.7",
-                "KEYPAIRGENERATOR.1.3.133.16.840.63.0.2",
-                "KEYPAIRGENERATOR.2.5.8.1.1",
-                "KEYPAIRGENERATOR.EC",
-                "KEYPAIRGENERATOR.RSA",
-                "MAC.1.2.840.113549.2.10",
-                "MAC.1.2.840.113549.2.11",
-                "MAC.1.2.840.113549.2.7",
-                "MAC.1.2.840.113549.2.8",
-                "MAC.1.2.840.113549.2.9",
-                "MAC.1.3.6.1.5.5.8.1.1",
-                "MAC.1.3.6.1.5.5.8.1.2",
-                "MAC.2.16.840.1.101.3.4.2.1",
-                "MAC.HMAC-MD5",
-                "MAC.HMAC-SHA1",
-                "MAC.HMAC-SHA224",
-                "MAC.HMAC-SHA256",
-                "MAC.HMAC-SHA384",
-                "MAC.HMAC-SHA512",
-                "MAC.HMAC/MD5",
-                "MAC.HMAC/SHA1",
-                "MAC.HMAC/SHA224",
-                "MAC.HMAC/SHA256",
-                "MAC.HMAC/SHA384",
-                "MAC.HMAC/SHA512",
-                "MAC.HMACMD5",
-                "MAC.HMACSHA1",
-                "MAC.HMACSHA224",
-                "MAC.HMACSHA256",
-                "MAC.HMACSHA384",
-                "MAC.HMACSHA512",
-                "MAC.PBEWITHHMACSHA224",
-                "MAC.PBEWITHHMACSHA256",
-                "MAC.PBEWITHHMACSHA384",
-                "MAC.PBEWITHHMACSHA512",
-                "MESSAGEDIGEST.1.2.840.113549.2.5",
-                "MESSAGEDIGEST.1.3.14.3.2.26",
-                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.1",
-                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.2",
-                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.3",
-                "MESSAGEDIGEST.2.16.840.1.101.3.4.2.4",
-                "MESSAGEDIGEST.MD5",
-                "MESSAGEDIGEST.SHA",
-                "MESSAGEDIGEST.SHA-1",
-                "MESSAGEDIGEST.SHA-224",
-                "MESSAGEDIGEST.SHA-256",
-                "MESSAGEDIGEST.SHA-384",
-                "MESSAGEDIGEST.SHA-512",
-                "MESSAGEDIGEST.SHA1",
-                "MESSAGEDIGEST.SHA224",
-                "MESSAGEDIGEST.SHA256",
-                "MESSAGEDIGEST.SHA384",
-                "MESSAGEDIGEST.SHA512",
-                "SECRETKEYFACTORY.DESEDE",
-                "SECRETKEYFACTORY.TDEA",
-                "SIGNATURE.1.2.840.10045.4.1",
-                "SIGNATURE.1.2.840.10045.4.3.1",
-                "SIGNATURE.1.2.840.10045.4.3.2",
-                "SIGNATURE.1.2.840.10045.4.3.3",
-                "SIGNATURE.1.2.840.10045.4.3.4",
-                "SIGNATURE.1.2.840.113549.1.1.11",
-                "SIGNATURE.1.2.840.113549.1.1.12",
-                "SIGNATURE.1.2.840.113549.1.1.13",
-                "SIGNATURE.1.2.840.113549.1.1.14",
-                "SIGNATURE.1.2.840.113549.1.1.4",
-                "SIGNATURE.1.2.840.113549.1.1.5",
-                "SIGNATURE.1.3.14.3.2.29",
-                "SIGNATURE.ECDSA",
-                "SIGNATURE.ECDSAWITHSHA1",
-                "SIGNATURE.MD5/RSA",
-                "SIGNATURE.MD5WITHRSA",
-                "SIGNATURE.MD5WITHRSAENCRYPTION",
-                "SIGNATURE.NONEWITHECDSA",
-                "SIGNATURE.OID.1.2.840.10045.4.3.1",
-                "SIGNATURE.OID.1.2.840.10045.4.3.2",
-                "SIGNATURE.OID.1.2.840.10045.4.3.3",
-                "SIGNATURE.OID.1.2.840.10045.4.3.4",
-                "SIGNATURE.OID.1.2.840.113549.1.1.11",
-                "SIGNATURE.OID.1.2.840.113549.1.1.12",
-                "SIGNATURE.OID.1.2.840.113549.1.1.13",
-                "SIGNATURE.OID.1.2.840.113549.1.1.14",
-                "SIGNATURE.OID.1.2.840.113549.1.1.4",
-                "SIGNATURE.OID.1.2.840.113549.1.1.5",
-                "SIGNATURE.OID.1.3.14.3.2.29",
-                "SIGNATURE.SHA1/RSA",
-                "SIGNATURE.SHA1WITHECDSA",
-                "SIGNATURE.SHA1WITHRSA",
-                "SIGNATURE.SHA1WITHRSAENCRYPTION",
-                "SIGNATURE.SHA224/ECDSA",
-                "SIGNATURE.SHA224/RSA",
-                "SIGNATURE.SHA224WITHECDSA",
-                "SIGNATURE.SHA224WITHRSA",
-                "SIGNATURE.SHA224WITHRSAENCRYPTION",
-                "SIGNATURE.SHA256/ECDSA",
-                "SIGNATURE.SHA256/RSA",
-                "SIGNATURE.SHA256WITHECDSA",
-                "SIGNATURE.SHA256WITHRSA",
-                "SIGNATURE.SHA256WITHRSAENCRYPTION",
-                "SIGNATURE.SHA384/ECDSA",
-                "SIGNATURE.SHA384/RSA",
-                "SIGNATURE.SHA384WITHECDSA",
-                "SIGNATURE.SHA384WITHRSA",
-                "SIGNATURE.SHA384WITHRSAENCRYPTION",
-                "SIGNATURE.SHA512/ECDSA",
-                "SIGNATURE.SHA512/RSA",
-                "SIGNATURE.SHA512WITHECDSA",
-                "SIGNATURE.SHA512WITHRSA",
-                "SIGNATURE.SHA512WITHRSAENCRYPTION"
+            "KEYFACTORY.RSA"
         ));
     }
 
diff --git a/ojluni/src/main/java/sun/security/pkcs/ContentInfo.java b/ojluni/src/main/java/sun/security/pkcs/ContentInfo.java
index bc78d0f..a5f5bc7 100644
--- a/ojluni/src/main/java/sun/security/pkcs/ContentInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/ContentInfo.java
@@ -34,7 +34,6 @@
  *
  * @author Benjamin Renaud
  */
-
 public class ContentInfo {
 
     // pkcs7 pre-defined content types
@@ -199,6 +198,8 @@
     /**
      * Returns a byte array representation of the data held in
      * the content field.
+     * @return             byte array representation of data held in content field
+     * @throws IOException if content bytes are invalid
      */
     public byte[] getContentBytes() throws IOException {
         if (content == null)
diff --git a/ojluni/src/main/java/sun/security/pkcs/PKCS7.java b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
index d3cd7e0..6038616 100644
--- a/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
+++ b/ojluni/src/main/java/sun/security/pkcs/PKCS7.java
@@ -61,6 +61,8 @@
  *
  * @author Benjamin Renaud
  */
+// Android-added: stable CorePlatformAPI
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class PKCS7 {
 
     private ObjectIdentifier contentType;
@@ -113,9 +115,10 @@
      * encoded bytes from the InputStream.
      *
      * @param in an input stream holding at least one PKCS7 block.
-     * @exception ParsingException on parsing errors.
-     * @exception IOException on other errors.
+     * @throws ParsingException on parsing errors.
+     * @throws IOException on other errors.
      */
+
     public PKCS7(InputStream in) throws ParsingException, IOException {
         DataInputStream dis = new DataInputStream(in);
         byte[] data = new byte[dis.available()];
@@ -142,6 +145,7 @@
      * @param bytes the encoded bytes.
      * @exception ParsingException on parsing errors.
      */
+
     public PKCS7(byte[] bytes) throws ParsingException {
         try {
             DerInputStream derin = new DerInputStream(bytes);
@@ -614,6 +618,7 @@
      * @exception NoSuchAlgorithmException on unrecognized algorithms.
      * @exception SignatureException on signature handling errors.
      */
+
     public SignerInfo verify(SignerInfo info, InputStream dataInputStream)
     throws NoSuchAlgorithmException, SignatureException, IOException {
         return info.verify(this, dataInputStream);
@@ -628,6 +633,7 @@
      * @exception NoSuchAlgorithmException on unrecognized algorithms.
      * @exception SignatureException on signature handling errors.
      */
+
     public SignerInfo[] verify(byte[] bytes)
     throws NoSuchAlgorithmException, SignatureException {
 
@@ -689,6 +695,7 @@
      * @return a clone of the array of X.509 certificates or null if
      *         none are specified for the content type.
      */
+
     public X509Certificate[] getCertificates() {
         if (certificates != null)
             return certificates.clone();
@@ -713,6 +720,7 @@
      * @return the array of Signer Infos or null if none are specified
      *         for the content type.
      */
+
     public SignerInfo[] getSignerInfos() {
         return signerInfos;
     }
diff --git a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
index 88fcf06..ea12395 100644
--- a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
@@ -251,10 +251,12 @@
         out.write(tmp.toByteArray());
     }
 
-
-
-    /*
-     * Returns the (user) certificate pertaining to this SignerInfo.
+    /**
+     * Returns the (user) certificate pertaining to this {@link SignerInfo}.
+     *
+     * @param block block of encrypted data
+     * @return certificate pertaining to the {@link SignerInfo}
+     * @throws IOException on decoding error
      */
     public X509Certificate getCertificate(PKCS7 block)
         throws IOException
@@ -262,8 +264,12 @@
         return block.getCertificate(certificateSerialNumber, issuerName);
     }
 
-    /*
-     * Returns the certificate chain pertaining to this SignerInfo.
+    /**
+     * Returns the certificate chain pertaining to this {@link #SignerInfo}.
+     *
+     * @param block block of encrypted data
+     * @return certificate chain pertaining to this {@link #SignerInfo}.
+     * @throws IOException on decoding error
      */
     public ArrayList<X509Certificate> getCertificateChain(PKCS7 block)
         throws IOException
@@ -427,10 +433,13 @@
             }
 
             X509Certificate cert = getCertificate(block);
-            PublicKey key = cert.getPublicKey();
+            // Android-changed: Null pointer fix from later upstream revision
+            // PublicKey key = cert.getPublicKey();
             if (cert == null) {
                 return null;
             }
+            // Android-changed: Null pointer fix from later upstream revision
+            PublicKey key = cert.getPublicKey();
 
             // check if the public key is restricted
             if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
diff --git a/ojluni/src/main/java/sun/security/util/DerInputStream.java b/ojluni/src/main/java/sun/security/util/DerInputStream.java
index 6608676..7f42bb0 100644
--- a/ojluni/src/main/java/sun/security/util/DerInputStream.java
+++ b/ojluni/src/main/java/sun/security/util/DerInputStream.java
@@ -325,7 +325,7 @@
      *          (used to initialize an auto-growing data structure)
      * @return array of the values in the sequence
      */
-    // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation
+    // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation.
     public DerValue[] getSequence(int startLen,
             boolean originalEncodedFormRetained) throws IOException {
         tag = (byte)buffer.read();
@@ -348,8 +348,8 @@
         return getSequence(
                 startLen,
                 false); // no need to retain original encoded form
-        // END Android-changed: Original encoded form needed for APKs parsing/validation
     }
+    // END Android-changed: Original encoded form needed for APKs parsing/validation.
 
     /**
      * Return a set of encoded entities.  ASN.1 sets are unordered,
@@ -381,7 +381,7 @@
      */
     public DerValue[] getSet(int startLen, boolean implicit)
         throws IOException {
-        // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation
+        // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation.
         return getSet(
             startLen,
             implicit,
@@ -398,7 +398,7 @@
             }
         }
         return (readVector(startLen, originalEncodedFormRetained));
-        // END Android-changed: Original encoded form needed for APKs parsing/validation
+        // END Android-changed: Original encoded form needed for APKs parsing/validation.
     }
 
     /*
@@ -407,7 +407,7 @@
      * this same helper routine.
      */
     protected DerValue[] readVector(int startLen) throws IOException {
-        // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation
+        // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation.
         return readVector(
             startLen,
             false); // no need to retain original encoded form
@@ -420,7 +420,7 @@
      */
     protected DerValue[] readVector(int startLen,
             boolean originalEncodedFormRetained) throws IOException {
-        // END Android-changed: Original encoded form needed for APKs parsing/validation
+        // END Android-changed: Original encoded form needed for APKs parsing/validation.
         DerInputStream  newstr;
 
         byte lenByte = (byte)buffer.read();
@@ -465,7 +465,7 @@
         DerValue value;
 
         do {
-            // Android-changed: Original encoded form needed for APKs parsing/validation
+            // Android-changed: Original encoded form needed for APKs parsing/validation.
             value = new DerValue(newstr.buffer, originalEncodedFormRetained);
             vec.addElement(value);
         } while (newstr.available() > 0);
diff --git a/ojluni/src/main/java/sun/security/util/DerValue.java b/ojluni/src/main/java/sun/security/util/DerValue.java
index 3045995..7828820 100644
--- a/ojluni/src/main/java/sun/security/util/DerValue.java
+++ b/ojluni/src/main/java/sun/security/util/DerValue.java
@@ -72,13 +72,13 @@
 
     private int                 length;
 
-    // BEGIN Android-added: Original encoded form needed for APKs parsing/validation
+    // BEGIN Android-added: Original encoded form needed for APKs parsing/validation.
     /**
      * The original encoded form of the whole value (tag, length, and value)
      * or null if the form was not provided or was not retained during parsing.
      */
     private byte[]              originalEncodedForm;
-    // END Android-added: Original encoded form needed for APKs parsing/validation
+    // END Android-added: Original encoded form needed for APKs parsing/validation.
 
     /*
      * The type starts at the first byte of the encoding, and
@@ -251,7 +251,7 @@
     /*
      * package private
      */
-    // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation
+    // BEGIN Android-changed: Original encoded form needed for APKs parsing/validation.
     DerValue(DerInputBuffer in, boolean originalEncodedFormRetained)
             throws IOException {
         // XXX must also parse BER-encoded constructed
@@ -297,7 +297,7 @@
             int consumed = in.getPos() - startPosInInput;
             originalEncodedForm = in.getSlice(startPosInInput, consumed);
         }
-    // END Android-changed: Original encoded form needed for APKs parsing/validation
+    // END Android-changed: Original encoded form needed for APKs parsing/validation.
     }
 
     /**
@@ -838,7 +838,7 @@
         }
     }
 
-    // BEGIN Android-added: Original encoded form needed for APKs parsing/validation
+    // BEGIN Android-added: Original encoded form needed for APKs parsing/validation.
     /**
      * Returns the original encoded form or {@code null} if the form was not
      * retained or is not available.
@@ -847,7 +847,7 @@
         return (originalEncodedForm != null)
                 ? originalEncodedForm.clone() : null;
     }
-    // END Android-added: Original encoded form needed for APKs parsing/validation
+    // END Android-added: Original encoded form needed for APKs parsing/validation.
 
     /**
      * Returns a DER-encoded value, such that if it's passed to the
diff --git a/ojluni/src/main/java/sun/security/util/ObjectIdentifier.java b/ojluni/src/main/java/sun/security/util/ObjectIdentifier.java
index 58f26c3..c713fde 100644
--- a/ojluni/src/main/java/sun/security/util/ObjectIdentifier.java
+++ b/ojluni/src/main/java/sun/security/util/ObjectIdentifier.java
@@ -49,7 +49,8 @@
  * @author Amit Kapoor
  * @author Hemma Prafullchandra
  */
-
+// Android-added: stable CorePlatformAPI
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 final public
 class ObjectIdentifier implements Serializable
 {
@@ -139,6 +140,8 @@
      * Constructs, from a string.  This string should be of the form 1.23.56.
      * Validity check included.
      */
+    // Android-added: stable CorePlatformAPI
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public ObjectIdentifier (String oid) throws IOException
     {
         int ch = '.';
diff --git a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
index 260d4aa..cbd3a63 100644
--- a/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
+++ b/ojluni/src/main/java/sun/security/x509/AlgorithmId.java
@@ -56,6 +56,8 @@
  * @author Amit Kapoor
  * @author Hemma Prafullchandra
  */
+// Android-added: stable CorePlatformAPI
+@libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
 public class AlgorithmId implements Serializable, DerEncoder {
 
     /** use serialVersionUID from JDK 1.1. for interoperability */
@@ -135,6 +137,9 @@
 
     /**
      * Marshal a DER-encoded "AlgorithmID" sequence on the DER stream.
+     *
+     * @param out {@link DerInputStream} to write encoded data to
+     * @throws IOException on encoding error
      */
     public final void encode(DerOutputStream out) throws IOException {
         derEncode(out);
@@ -225,7 +230,11 @@
      * return a name such as "MD5withRSA" for a signature algorithm on
      * some systems.  It also returns names like "OID.1.2.3.4", when
      * no particular name for the algorithm is known.
+     *
+     * @return name of the algorithm
      */
+    // Android-added: stable CorePlatformAPI
+    @libcore.api.CorePlatformApi(status = libcore.api.CorePlatformApi.Status.STABLE)
     public String getName() {
         String algName = nameTable.get(algid);
         if (algName != null) {
diff --git a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
index 57a8f71..f15b998 100644
--- a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
+++ b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
@@ -192,7 +192,7 @@
         }
     }
 
-    // BEGIN Android-removed: unused code
+    // BEGIN Android-removed: unused code.
     /*
     /**
      * unmarshals an X.509 certificate from an input stream.  If the
@@ -280,7 +280,7 @@
         return der;
     }
     */
-    // END Android-removed: unused code
+    // END Android-removed: unused code.
 
     /**
      * Construct an initialized X509 Certificate. The certificate is stored
@@ -310,7 +310,7 @@
         }
     }
 
-    // BEGIN Android-added: Ctor to retain original encoded form for APKs parsing
+    // BEGIN Android-added: Ctor to retain original encoded form for APKs parsing.
     /**
      * Unmarshal a certificate from its encoded form, parsing a DER value.
      * This form of constructor is used by agents which need to examine
@@ -328,7 +328,7 @@
             throw new CertificateException("Unable to initialize, " + e, e);
         }
     }
-    // END Android-added: Ctor to retain original encoded form for APKs parsing
+    // END Android-added: Ctor to retain original encoded form for APKs parsing.
 
     /**
      * Appends the certificate to an output stream.
@@ -1814,7 +1814,7 @@
             throw new CertificateParsingException(
                       "invalid DER-encoded certificate data");
 
-        // Android-changed: Needed for providing encoded form of cert
+        // Android-changed: Needed for providing encoded form of cert.
         // signedCert = val.toByteArray();
         signedCert =
                 (originalEncodedForm != null)
@@ -1972,12 +1972,12 @@
     private ConcurrentHashMap<String,String> fingerprints =
             new ConcurrentHashMap<>(2);
 
-// BEGIN Android-removed
+// BEGIN Android-removed: unused code.
 //    public String getFingerprint(String algorithm) {
 //        return fingerprints.computeIfAbsent(algorithm,
 //                x -> getFingerprint(x, this));
 //    }
-// END Android-removed
+// END Android-removed: unused code.
 
     /**
      * Gets the requested finger print of the certificate. The result
diff --git a/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java b/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
index 70fabc7..37eb416 100644
--- a/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
+++ b/ojluni/src/main/java/sun/util/locale/LocaleMatcher.java
@@ -212,7 +212,7 @@
             if (range.equals("*")) {
                 continue;
             }
-            // Android-changed: backport OpenJDK 9 fix for JDK-8166994
+            // Android-changed: backport OpenJDK 9 fix for JDK-8166994.
             String rangeForRegex = range.replace("*", "\\p{Alnum}*");
             while (rangeForRegex.length() > 0) {
                 for (String tag : tags) {
@@ -242,7 +242,7 @@
     }
 
     public static List<LanguageRange> parse(String ranges) {
-        // Android-changed: backport OpenJDK 9 fix for JDK-8166994
+        // Android-changed: backport OpenJDK 9 fix for JDK-8166994.
         ranges = ranges.replace(" ", "").toLowerCase();
         if (ranges.startsWith("accept-language:")) {
             ranges = ranges.substring(16); // delete unnecessary prefix
@@ -332,7 +332,7 @@
         return list;
     }
 
-    // BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994
+    // BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994.
     /**
      * A faster alternative approach to String.replaceFirst(), if the given
      * string is a literal String, not a regex.
@@ -347,7 +347,7 @@
                     + range.substring(pos + substr.length());
         }
     }
-    // END Android-added: backport OpenJDK 9 fix for JDK-8166994
+    // END Android-added: backport OpenJDK 9 fix for JDK-8166994.
 
     private static String[] getEquivalentsForLanguage(String range) {
         String r = range;
@@ -357,7 +357,7 @@
                 String equiv = LocaleEquivalentMaps.singleEquivMap.get(r);
                 // Return immediately for performance if the first matching
                 // subtag is found.
-// BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994
+// BEGIN Android-added: backport OpenJDK 9 fix for JDK-8166994.
 // Upstream bug: https://bugs.openjdk.java.net/browse/JDK-8166994
 // Upstream fix: http://hg.openjdk.java.net/jdk9/dev/jdk/rev/60837db5d445
                 return new String[]{replaceFirstSubStringMatch(range,
@@ -370,7 +370,7 @@
                             r, equivs[i]);
                 }
                 return result;
-// END Android-added: backport OpenJDK 9 fix for JDK-8166994
+// END Android-added: backport OpenJDK 9 fix for JDK-8166994.
             }
 
             // Truncate the last subtag simply.
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 b067413..eed420b 100644
--- a/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java
+++ b/ojluni/src/main/java/sun/util/locale/provider/CalendarDataUtility.java
@@ -30,6 +30,8 @@
 
 import static java.util.Calendar.*;
 
+import libcore.util.NonNull;
+
 import java.util.Calendar;
 import java.util.LinkedHashMap;
 import java.util.Locale;
@@ -206,7 +208,9 @@
     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.
+        // Android maps BCP-47 calendar types to LDML defined calendar types, because it uses
+        // ICU directly while the upstream does the opposite because the upstream uses different
+        // data sources. See android.icu.text.DateFormatSymbols.CALENDAR_CLASSES for reference.
         // if (requestID.equals("gregorian") || requestID.equals("iso8601")) {
         //    type = "gregory";
         // } else if (requestID.startsWith("islamic")) {
@@ -285,9 +289,11 @@
         }
     }
 
-    private static DateFormatSymbols getDateFormatSymbols(String id, Locale locale) {
+    private static DateFormatSymbols getDateFormatSymbols(@NonNull String id, Locale locale) {
         String calendarType = normalizeCalendarType(id);
-        return new DateFormatSymbols(ULocale.forLocale(locale), calendarType);
+        ULocale uLocale = ULocale.forLocale(locale)
+                .setKeywordValue("calendar", calendarType);
+        return new DateFormatSymbols(uLocale);
     }
 
     /**
diff --git a/ojluni/src/main/native/Android.bp b/ojluni/src/main/native/Android.bp
index 45a5c98..162a73c 100644
--- a/ojluni/src/main/native/Android.bp
+++ b/ojluni/src/main/native/Android.bp
@@ -12,6 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_ojluni_license":
+    //   SPDX-license-identifier-GPL-2.0
+    default_applicable_licenses: ["libcore_ojluni_license"],
+}
+
 filegroup {
     name: "libopenjdk_native_srcs",
     visibility: [
diff --git a/ojluni/src/main/native/Character.cpp b/ojluni/src/main/native/Character.cpp
index 9fb24c3..3e27c67 100644
--- a/ojluni/src/main/native/Character.cpp
+++ b/ojluni/src/main/native/Character.cpp
@@ -24,7 +24,6 @@
 #include <nativehelper/JNIHelp.h>
 #include "nativehelper/jni_macros.h"
 #include "unicode/uchar.h"
-#include "unicode/uscript.h"
 #include <math.h>
 #include <stdio.h> // For BUFSIZ
 
diff --git a/ojluni/src/main/native/FileDescriptor_md.c b/ojluni/src/main/native/FileDescriptor_md.c
index 0404263..880f5ea 100644
--- a/ojluni/src/main/native/FileDescriptor_md.c
+++ b/ojluni/src/main/native/FileDescriptor_md.c
@@ -63,9 +63,11 @@
 }
 
 JNIEXPORT jboolean JNICALL FileDescriptor_isSocket(JNIEnv *env, jclass ignored, jint fd) {
-    int error;
-    socklen_t error_length = sizeof(error);
-    return TEMP_FAILURE_RETRY(getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &error_length)) == 0;
+    // BEGIN Android-changed: isSocket - do not clear socket error code
+    int domain;
+    socklen_t domain_length = sizeof(domain);
+    return TEMP_FAILURE_RETRY(getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &domain, &domain_length)) == 0;
+    // END Android-changed: isSocket - do not clear socket error code
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h b/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h
deleted file mode 100644
index fb1b78d..0000000
--- a/ojluni/src/main/native/java_net_PlainDatagramSocketImpl.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* This file was generated from java/net/PlainDatagramSocketImpl.java and is
- * licensed under the same terms. The copyright and license information for
- * java/net/PlainDatagramSocketImpl.java follows.
- *
- * Copyright (c) 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.
- */
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class java_net_PlainDatagramSocketImpl */
-
-#ifndef _Included_java_net_PlainDatagramSocketImpl
-#define _Included_java_net_PlainDatagramSocketImpl
-#ifdef __cplusplus
-extern "C" {
-#endif
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    bind0
- * Signature: (ILjava/net/InetAddress;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_bind0
-  (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    send
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_send
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    peek
- * Signature: (Ljava/net/InetAddress;)I
- */
-JNIEXPORT jint JNICALL PlainDatagramSocketImpl_peek
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    peekData
- * Signature: (Ljava/net/DatagramPacket;)I
- */
-JNIEXPORT jint JNICALL PlainDatagramSocketImpl_peekData
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    receive0
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_receive0
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    setTimeToLive
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_setTimeToLive
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    getTimeToLive
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL PlainDatagramSocketImpl_getTimeToLive
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    setTTL
- * Signature: (B)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_setTTL
-  (JNIEnv *, jobject, jbyte);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    getTTL
- * Signature: ()B
- */
-JNIEXPORT jbyte JNICALL PlainDatagramSocketImpl_getTTL
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    join
- * Signature: (Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_join
-  (JNIEnv *, jobject, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    leave
- * Signature: (Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_leave
-  (JNIEnv *, jobject, jobject, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    datagramSocketCreate
- * Signature: ()V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_datagramSocketCreate
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    datagramSocketClose
- * Signature: ()V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_datagramSocketClose
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    socketSetOption
- * Signature: (ILjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_socketSetOption
-  (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    socketGetOption
- * Signature: (I)Ljava/lang/Object;
- */
-JNIEXPORT jobject JNICALL PlainDatagramSocketImpl_socketGetOption
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    connect0
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_connect0
-  (JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    disconnect0
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_disconnect0
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL PlainDatagramSocketImpl_init
-  (JNIEnv *, jclass);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/ojluni/src/main/native/java_net_PlainSocketImpl.h b/ojluni/src/main/native/java_net_PlainSocketImpl.h
deleted file mode 100644
index b094a41..0000000
--- a/ojluni/src/main/native/java_net_PlainSocketImpl.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* This file was generated from java/net/PlainSocketImpl.java and is
- * licensed under the same terms. The copyright and license information for
- * java/net/PlainSocketImpl.java follows.
- *
- * 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.
- */
-/* DO NOT EDIT THIS FILE - it is machine generated */
-#include <jni.h>
-/* Header for class java_net_PlainSocketImpl */
-
-#ifndef _Included_java_net_PlainSocketImpl
-#define _Included_java_net_PlainSocketImpl
-#ifdef __cplusplus
-extern "C" {
-#endif
-#undef java_net_PlainSocketImpl_SHUT_RD
-#define java_net_PlainSocketImpl_SHUT_RD 0L
-#undef java_net_PlainSocketImpl_SHUT_WR
-#define java_net_PlainSocketImpl_SHUT_WR 1L
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketCreate
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketCreate
-  (JNIEnv *, jobject, jboolean);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketConnect
- * Signature: (Ljava/net/InetAddress;II)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketConnect
-  (JNIEnv *, jobject, jobject, jint, jint);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketBind
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketBind
-  (JNIEnv *, jobject, jobject, jint);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketListen
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketListen
-  (JNIEnv *, jobject, jint);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketAccept
- * Signature: (Ljava/net/SocketImpl;)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketAccept
-  (JNIEnv *, jobject, jobject);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketAvailable
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL PlainSocketImpl_socketAvailable
-  (JNIEnv *, jobject);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketClose0
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketClose0
-  (JNIEnv *, jobject, jboolean);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketShutdown
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketShutdown
-  (JNIEnv *, jobject, jint);
-
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketSetOption
- * Signature: (IZLjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketSetOption
-  (JNIEnv *, jobject, jint, jboolean, jobject);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketGetOption
- * Signature: (ILjava/lang/Object;)I
- */
-JNIEXPORT jint JNICALL PlainSocketImpl_socketGetOption
-  (JNIEnv *, jobject, jint, jobject);
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketSendUrgentData
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL PlainSocketImpl_socketSendUrgentData
-  (JNIEnv *, jobject, jint);
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/ojluni/src/main/native/socket_tagger_util.cpp b/ojluni/src/main/native/socket_tagger_util.cpp
index cdac52b..0d833f5 100644
--- a/ojluni/src/main/native/socket_tagger_util.cpp
+++ b/ojluni/src/main/native/socket_tagger_util.cpp
@@ -19,7 +19,8 @@
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include <nativehelper/JNIHelp.h>
+#include <nativehelper/JNIPlatformHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
 
 #include "JniConstants.h"
 
@@ -28,6 +29,11 @@
       return fd;
     }
 
+    jobject fileDescriptor = jniCreateFileDescriptor(env, fd);
+    if (fileDescriptor == nullptr) {
+      return fd;
+    }
+
     jclass socketTaggerClass = JniConstants::GetSocketTaggerClass(env);
     jmethodID get = env->GetStaticMethodID(socketTaggerClass,
                                            "get",
@@ -35,7 +41,6 @@
     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 6c02d2b..aa9c5ce 100644
--- a/ojluni/src/main/native/zip_util.c
+++ b/ojluni/src/main/native/zip_util.c
@@ -156,7 +156,7 @@
      * JVM_IO_INTR is tricky and could cause undesired side effect. So we decided
      * to simply call "read" on Solaris/Linux. See details in bug 6304463.
      */
-    return pread(zfd, buf, nbytes, offset);
+    return pread64(zfd, buf, nbytes, offset);
 #endif
 }
 
diff --git a/ojluni/src/test/java/awt/font/NumericShaper/EasternArabicTest.java b/ojluni/src/test/java/awt/font/NumericShaper/EasternArabicTest.java
new file mode 100644
index 0000000..2b9c1e4
--- /dev/null
+++ b/ojluni/src/test/java/awt/font/NumericShaper/EasternArabicTest.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6941948
+ * @summary Make sure that EASTERN_ARABIC works with the enum interface.
+ */
+
+package test.java.awt.font.NumericShaper;
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+import org.testng.annotations.Test;
+
+public class EasternArabicTest {
+    static NumericShaper ns_old, ns_new;
+    static boolean err = false;
+
+    static String[][] testData = {
+        // Arabic "October 10"
+        {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
+         "\u0623\u0643\u062a\u0648\u0628\u0631 \u06f1\u06f0"}, // EASTERN_ARABIC digits
+
+        // Tamil "Year 2009"
+        {"\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 2009",
+         "\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 \u0be8\u0be6\u0be6\u0bef"},
+        // "\u0be800\u0bef is returned by pre-JDK7 because Tamil zero was not
+        //  included in Unicode 4.0.0.
+
+        // Ethiopic "Syllable<HA> 2009"
+        {"\u1200 2009",
+         "\u1200 \u136a00\u1371"},
+        // Ethiopic zero doesn't exist even in Unicode 5.1.0.
+    };
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        ns_old = getContextualShaper(TAMIL|ETHIOPIC|EASTERN_ARABIC|ARABIC|THAI|LAO,
+                                     EUROPEAN);
+        ns_new = getContextualShaper(EnumSet.of(Range.THAI,
+                                                Range.TAMIL,
+                                                Range.ETHIOPIC,
+                                                Range.EASTERN_ARABIC,
+                                                Range.ARABIC,
+                                                Range.LAO),
+                                     Range.EUROPEAN);
+
+
+        StringBuilder cData = new StringBuilder();
+        StringBuilder cExpected = new StringBuilder();
+        for (int i = 0; i < testData.length; i++) {
+            String data = testData[i][0];
+            String expected = testData[i][1];
+            test(data, expected);
+            cData.append(data).append(' ');
+            cExpected.append(expected).append(' ');
+        }
+        test(cData.toString(), cExpected.toString());
+
+        if (err) {
+            throw new RuntimeException("shape() returned unexpected value.");
+        }
+    }
+
+    private static void test(String data, String expected) {
+        char[] text = data.toCharArray();
+        ns_old.shape(text, 0, text.length);
+        String got = new String(text);
+
+        if (!expected.equals(got)) {
+            err = true;
+            System.err.println("Error with traditional range.");
+            System.err.println("  text = " + data);
+            System.err.println("  got = " + got);
+            System.err.println("  expected = " + expected);
+        } else {
+            System.err.println("OK with traditional range.");
+            System.err.println("  text = " + data);
+            System.err.println("  got = " + got);
+            System.err.println("  expected = " + expected);
+        }
+
+        text = data.toCharArray();
+        ns_new.shape(text, 0, text.length);
+        got = new String(text);
+
+        if (!expected.equals(got)) {
+            err = true;
+            System.err.println("Error with new Enum range.");
+            System.err.println("  text = " + data);
+            System.err.println("  got = " + got);
+            System.err.println("  expected = " + expected);
+        } else {
+            System.err.println("OK with new Enum range.");
+            System.err.println("  text = " + data);
+            System.err.println("  got = " + got);
+            System.err.println("  expected = " + expected);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/awt/font/NumericShaper/EqualsTest.java b/ojluni/src/test/java/awt/font/NumericShaper/EqualsTest.java
new file mode 100644
index 0000000..ed1307e
--- /dev/null
+++ b/ojluni/src/test/java/awt/font/NumericShaper/EqualsTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557
+ * @summary confirm that an instance which is created with new Enum ranges is
+ * equivalent to another instance which is created with equivalent traditional
+ * ranges or the same Enum ranges.
+ */
+
+package test.java.awt.font.NumericShaper;
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+import org.testng.annotations.Test;
+
+public class EqualsTest {
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        NumericShaper ns1 = getContextualShaper(ARABIC | TAMIL, TAMIL);
+        NumericShaper ns2 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.TAMIL);
+        NumericShaper ns3 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.TAMIL);
+        NumericShaper ns4 = getContextualShaper(
+                                EnumSet.of(Range.ARABIC, Range.TAMIL),
+                                Range.ARABIC);
+
+        if (!ns1.equals(ns2)) {
+            throw new RuntimeException("ns1 != ns2: ns1=" + ns1 + ", ns2=" + ns2);
+        }
+        if (!ns2.equals(ns1)) {
+            throw new RuntimeException("ns2 != ns1: ns1=" + ns1 + ", ns2=" + ns2);
+        }
+        if (!ns2.equals(ns3)) {
+            throw new RuntimeException("ns2 != ns3: ns2=" + ns2 + ", ns3=" + ns3);
+        }
+        if (ns1.equals(ns4)) {
+            throw new RuntimeException("ns1 == ns4: ns1=" + ns1 + ", ns4=" + ns4);
+        }
+        if (ns2.equals(ns4)) {
+            throw new RuntimeException("ns2 == ns4: ns2=" + ns2 + ", ns4=" + ns4);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/awt/font/NumericShaper/MTTest.java b/ojluni/src/test/java/awt/font/NumericShaper/MTTest.java
new file mode 100644
index 0000000..fb91728
--- /dev/null
+++ b/ojluni/src/test/java/awt/font/NumericShaper/MTTest.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6843181 6943963
+ * @summary Confirm that NumericShaper is thread-safe.
+ * @run main/timeout=300/othervm MTTest
+ */
+
+package test.java.awt.font.NumericShaper;
+
+import java.awt.font.NumericShaper;
+import java.util.Arrays;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+import org.testng.annotations.Test;
+
+public class MTTest {
+    static volatile boolean runrun = true;
+    static volatile boolean err = false;
+
+    final static String text = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -456 (Thai) \u0e01\u0e33 01.23";
+    final static char[] expected1 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u06f4\u06f5\u06f6 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for EASTERN_ARABIC
+    final static char[] expected2 = "-123 (English) 456.00 (Arabic) \u0641\u0642\u0643 -\u0664\u0665\u0666 (Thai) \u0e01\u0e33 \u0e50\u0e51.\u0e52\u0e53".toCharArray(); // for ARABIC
+
+    static NumericShaper ns1, ns2, ns3, ns4;
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        System.out.println("original: " + text);
+        ns1 = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC, Range.THAI),
+                                  Range.EUROPEAN);
+        ns2 = getContextualShaper(EnumSet.of(Range.ARABIC, Range.THAI),
+                                  Range.EUROPEAN);
+        System.out.println("expected for Eastern-Arabic & Thai: " +
+                           String.valueOf(expected1));
+        System.out.println("expected for Arabic & Thai: " +
+                           String.valueOf(expected2));
+
+        ns3 = getContextualShaper(EASTERN_ARABIC|THAI, EUROPEAN);
+        ns4 = getContextualShaper(ARABIC|THAI, EUROPEAN);
+
+        Thread th1 = new Thread(new Work(ns1, expected1));
+        Thread th2 = new Thread(new Work(ns2, expected2));
+        Thread th3 = new Thread(new Work(ns1, expected1));
+        Thread th4 = new Thread(new Work(ns2, expected2));
+        Thread th5 = new Thread(new Work(ns3, expected1));
+        Thread th6 = new Thread(new Work(ns4, expected2));
+        Thread th7 = new Thread(new Work(ns3, expected1));
+        Thread th8 = new Thread(new Work(ns4, expected2));
+
+        th1.start();
+        th2.start();
+        th3.start();
+        th4.start();
+        th5.start();
+        th6.start();
+        th7.start();
+        th8.start();
+
+        try {
+            // Android-changed: Shorten the test from 180s to 15s. http://b/183290003
+            // for (int i = 0; runrun && i < 180; i++) {
+            for (int i = 0; runrun && i < 15; i++) {
+                Thread.sleep(1000); // 1 seconds
+            }
+            runrun = false;
+            th1.join();
+            th2.join();
+            th3.join();
+            th4.join();
+            th5.join();
+            th6.join();
+            th7.join();
+            th8.join();
+        }
+        catch (InterruptedException e) {
+        }
+
+        if (err) {
+            throw new RuntimeException("Thread-safe test failed.");
+        }
+    }
+
+    private static class Work implements Runnable {
+        NumericShaper ns;
+        char[] expectedText;
+
+        Work(NumericShaper ns, char[] expectedText) {
+            this.ns = ns;
+            this.expectedText = expectedText;
+
+        }
+
+        public void run() {
+            int count = 0;
+            while (runrun) {
+                char[] t = text.toCharArray();
+                count++;
+                try {
+                    ns.shape(t, 0, t.length);
+                } catch (Exception e) {
+                    System.err.println("Error: Unexpected exception: " + e);
+                    runrun = false;
+                    err = true;
+                    return;
+                }
+                if (!Arrays.equals(t, expectedText)) {
+                    System.err.println("Error: shape() returned unexpected value: ");
+                    System.err.println("count = " + count);
+                    System.err.println("   expected: " + String.valueOf(expectedText));
+                    System.err.println("        got: " + String.valueOf(t));
+                    runrun = false;
+                    err = true;
+                    return;
+                }
+            }
+        }
+    }
+}
diff --git a/ojluni/src/test/java/awt/font/NumericShaper/ShapingTest.java b/ojluni/src/test/java/awt/font/NumericShaper/ShapingTest.java
new file mode 100644
index 0000000..62bcefb
--- /dev/null
+++ b/ojluni/src/test/java/awt/font/NumericShaper/ShapingTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6842557 6943963 6959267
+ * @summary confirm that shaping works as expected. (Mainly for new characters which were added in Unicode 5 and 6)
+ * used where appropriate.
+ */
+
+package test.java.awt.font.NumericShaper;
+
+import java.awt.font.NumericShaper;
+import java.util.EnumSet;
+import static java.awt.font.NumericShaper.*;
+
+import org.testng.annotations.Test;
+
+public class ShapingTest {
+
+    private static boolean err = false;
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        test6842557();
+        test6943963();
+        test6903266();
+
+        if (err) {
+            throw new RuntimeException("shape() returned unexpected value.");
+        }
+    }
+
+    private static void test6842557() {
+        NumericShaper ns_old = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+                                   EUROPEAN);
+        NumericShaper ns_new = getContextualShaper(EnumSet.of(
+                                   Range.ARABIC, Range.TAMIL, Range.ETHIOPIC),
+                                   Range.EUROPEAN);
+
+        String[][] data = {
+           // Arabic "October 10"
+          {"\u0623\u0643\u062a\u0648\u0628\u0631 10",
+           "\u0623\u0643\u062a\u0648\u0628\u0631 \u0661\u0660"},
+
+           // Tamil "Year 2009"
+          {"\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 2009",
+           "\u0b86\u0ba3\u0bcd\u0b9f\u0bc1 \u0be8\u0be6\u0be6\u0bef"},
+           // "\u0be800\u0bef is returned by pre-JDK7 because Tamil zero was not
+           //  included in Unicode 4.0.0.
+
+           // Ethiopic "Syllable<HA> 2009"
+          {"\u1200 2009",
+           "\u1200 \u136a00\u1371"},
+           // Ethiopic zero doesn't exist even in Unicode 5.1.0.
+        };
+
+        for (int i = 0; i < data.length; i++) {
+            checkResult("ARABIC | TAMIL | ETHIOPIC",
+                        ns_old, data[i][0], data[i][1]);
+
+            checkResult("Range.ARABIC, Range.TAMIL, Range.ETHIOPIC",
+                        ns_new, data[i][0], data[i][1]);
+        }
+    }
+
+    private static void test6943963() {
+        // Needed to reproduce this bug.
+        NumericShaper ns_dummy = getContextualShaper(ARABIC | TAMIL | ETHIOPIC,
+                                   EUROPEAN);
+        char[] c = "\u1200 1".toCharArray();
+        ns_dummy.shape(c, 0, c.length);
+
+
+        String given = "\u0627\u0628 456";
+        String expected_ARABIC = "\u0627\u0628 \u0664\u0665\u0666";
+        String expected_EASTERN_ARABIC = "\u0627\u0628 \u06f4\u06f5\u06f6";
+
+        NumericShaper ns = getContextualShaper(ARABIC);
+        checkResult("ARABIC", ns, given, expected_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.ARABIC));
+        checkResult("Range.ARABIC", ns, given, expected_ARABIC);
+
+        ns = getContextualShaper(EASTERN_ARABIC);
+        checkResult("EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.EASTERN_ARABIC));
+        checkResult("Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(ARABIC | EASTERN_ARABIC);
+        checkResult("ARABIC | EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+
+        ns = getContextualShaper(EnumSet.of(Range.ARABIC, Range.EASTERN_ARABIC));
+        checkResult("Range.ARABIC, Range.EASTERN_ARABIC", ns, given, expected_EASTERN_ARABIC);
+    }
+
+    private static void test6903266() {
+        NumericShaper ns = getContextualShaper(EnumSet.of(Range.TAI_THAM_HORA));
+        String given = "\u1a20 012";
+        String expected = "\u1a20 \u1a80\u1a81\u1a82";
+        checkResult("Range.TAI_THAM_HORA", ns, given, expected);
+
+        ns = getContextualShaper(EnumSet.of(Range.TAI_THAM_HORA,
+                                            Range.TAI_THAM_THAM));
+        given = "\u1a20 012";
+        expected = "\u1a20 \u1a90\u1a91\u1a92"; // Tham digits are prioritized.
+        checkResult("Range.TAI_THAM_HORA, Range.TAI_THAM_THAM", ns, given, expected);
+
+        ns = getContextualShaper(EnumSet.of(Range.JAVANESE));
+        given = "\ua984 012";
+        expected = "\ua984 \ua9d0\ua9d1\ua9d2";
+        checkResult("Range.JAVANESE", ns, given, expected);
+
+        ns = getContextualShaper(EnumSet.of(Range.TAI_THAM_THAM));
+        given = "\u1a20 012";
+        expected = "\u1a20 \u1a90\u1a91\u1a92";
+        checkResult("Range.TAI_THAM_THAM", ns, given, expected);
+
+        ns = getContextualShaper(EnumSet.of(Range.MEETEI_MAYEK));
+        given = "\uabc0 012";
+        expected = "\uabc0 \uabf0\uabf1\uabf2";
+        checkResult("Range.MEETEI_MAYEK", ns, given, expected);
+    }
+
+    private static void checkResult(String ranges, NumericShaper ns,
+                                    String given, String expected) {
+        char[] text = given.toCharArray();
+        ns.shape(text, 0, text.length);
+        String got = new String(text);
+
+        if (!expected.equals(got)) {
+            err = true;
+            System.err.println("Error with range(s) <" + ranges + ">.");
+            System.err.println("  text     = " + given);
+            System.err.println("  got      = " + got);
+            System.err.println("  expected = " + expected);
+        } else {
+            System.out.println("OK with range(s) <" + ranges + ">.");
+            System.out.println("  text     = " + given);
+            System.out.println("  got      = " + got);
+            System.out.println("  expected = " + expected);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/lang/Math/DivModTests.java b/ojluni/src/test/java/lang/Math/DivModTests.java
new file mode 100644
index 0000000..7e9fb61
--- /dev/null
+++ b/ojluni/src/test/java/lang/Math/DivModTests.java
@@ -0,0 +1,544 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.lang.Math;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+/**
+ * @test Test Math and StrictMath Floor Div / Modulo operations.
+ * @bug 6282196
+ * @summary Basic tests for Floor division and modulo methods for both Math
+ * and StrictMath for int and long datatypes.
+ */
+public class DivModTests {
+
+    /**
+     * Report a test failure and increment the error count.
+     * @param message the formatting string
+     * @param args the variable number of arguments for the message.
+     */
+    static void fail(String message, Object... args) {
+        final String formattedMessage = String.format(message, args);
+        Assert.fail(formattedMessage);
+    }
+
+    /**
+     * Test the integer floorDiv and floorMod methods.
+     * Math and StrictMath tested and the same results are expected for both.
+     */
+    @Test
+    public void testIntFloorDivMod() {
+        testIntFloorDivMod(4, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
+        testIntFloorDivMod(4, 3, 1, 1);
+        testIntFloorDivMod(3, 3, 1, 0);
+        testIntFloorDivMod(2, 3, 0, 2);
+        testIntFloorDivMod(1, 3, 0, 1);
+        testIntFloorDivMod(0, 3, 0, 0);
+        testIntFloorDivMod(4, -3, -2, -2);
+        testIntFloorDivMod(3, -3, -1, 0);
+        testIntFloorDivMod(2, -3, -1, -1);
+        testIntFloorDivMod(1, -3, -1, -2);
+        testIntFloorDivMod(0, -3, 0, 0);
+        testIntFloorDivMod(-1, 3, -1, 2);
+        testIntFloorDivMod(-2, 3, -1, 1);
+        testIntFloorDivMod(-3, 3, -1, 0);
+        testIntFloorDivMod(-4, 3, -2, 2);
+        testIntFloorDivMod(-1, -3, 0, -1);
+        testIntFloorDivMod(-2, -3, 0, -2);
+        testIntFloorDivMod(-3, -3, 1, 0);
+        testIntFloorDivMod(-4, -3, 1, -1);
+        testIntFloorDivMod(Integer.MAX_VALUE, 1, Integer.MAX_VALUE, 0);
+        testIntFloorDivMod(Integer.MAX_VALUE, -1, -Integer.MAX_VALUE, 0);
+        testIntFloorDivMod(Integer.MAX_VALUE, 3, 715827882, 1);
+        testIntFloorDivMod(Integer.MAX_VALUE - 1, 3, 715827882, 0);
+        testIntFloorDivMod(Integer.MIN_VALUE, 3, -715827883, 1);
+        testIntFloorDivMod(Integer.MIN_VALUE + 1, 3, -715827883, 2);
+        testIntFloorDivMod(Integer.MIN_VALUE + 1, -1, Integer.MAX_VALUE, 0);
+        // Special case of integer overflow
+        testIntFloorDivMod(Integer.MIN_VALUE, -1, Integer.MIN_VALUE, 0);
+    }
+
+    /**
+     * Test FloorDiv and then FloorMod with int data.
+     */
+    static void testIntFloorDivMod(int x, int y, Object divExpected, Object modExpected) {
+        testIntFloorDiv(x, y, divExpected);
+        testIntFloorMod(x, y, modExpected);
+    }
+
+    /**
+     * Test FloorDiv with int data.
+     */
+    static void testIntFloorDiv(int x, int y, Object expected) {
+        Object result = doFloorDiv(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorDiv(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+    }
+
+    /**
+     * Test FloorMod with int data.
+     */
+    static void testIntFloorMod(int x, int y, Object expected) {
+        Object result = doFloorMod(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorMod(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+
+        try {
+            // Verify result against double precision floor function
+            int tmp = x / y;     // Force ArithmeticException for divide by zero
+            double ff = x - Math.floor((double)x / (double)y) * y;
+            int fr = (int)ff;
+            boolean t = (fr == ((Integer)result));
+            if (!result.equals(fr)) {
+                fail("FAIL: Math.floorMod(%d, %d) = %s differs from Math.floor(x, y): %d%n", x, y, result, fr);
+            }
+        } catch (ArithmeticException ae) {
+            if (y != 0) {
+                fail("FAIL: Math.floorMod(%d, %d); unexpected %s%n", x, y, ae);
+            }
+        }
+    }
+
+    /**
+     * Test the floorDiv and floorMod methods for primitive long.
+     */
+    @Test
+    public void testLongFloorDivMod() {
+        testLongFloorDivMod(4L, 0L, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
+        testLongFloorDivMod(4L, 3L, 1L, 1L);
+        testLongFloorDivMod(3L, 3L, 1L, 0L);
+        testLongFloorDivMod(2L, 3L, 0L, 2L);
+        testLongFloorDivMod(1L, 3L, 0L, 1L);
+        testLongFloorDivMod(0L, 3L, 0L, 0L);
+        testLongFloorDivMod(4L, -3L, -2L, -2L);
+        testLongFloorDivMod(3L, -3L, -1L, 0l);
+        testLongFloorDivMod(2L, -3L, -1L, -1L);
+        testLongFloorDivMod(1L, -3L, -1L, -2L);
+        testLongFloorDivMod(0L, -3L, 0L, 0L);
+        testLongFloorDivMod(-1L, 3L, -1L, 2L);
+        testLongFloorDivMod(-2L, 3L, -1L, 1L);
+        testLongFloorDivMod(-3L, 3L, -1L, 0L);
+        testLongFloorDivMod(-4L, 3L, -2L, 2L);
+        testLongFloorDivMod(-1L, -3L, 0L, -1L);
+        testLongFloorDivMod(-2L, -3L, 0L, -2L);
+        testLongFloorDivMod(-3L, -3L, 1L, 0L);
+        testLongFloorDivMod(-4L, -3L, 1L, -1L);
+
+        testLongFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0L);
+        testLongFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0L);
+        testLongFloorDivMod(Long.MAX_VALUE, 3L, Long.MAX_VALUE / 3L, 1L);
+        testLongFloorDivMod(Long.MAX_VALUE - 1L, 3L, (Long.MAX_VALUE - 1L) / 3L, 0L);
+        testLongFloorDivMod(Long.MIN_VALUE, 3L, Long.MIN_VALUE / 3L - 1L, 1L);
+        testLongFloorDivMod(Long.MIN_VALUE + 1L, 3L, Long.MIN_VALUE / 3L - 1L, 2L);
+        testLongFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0L);
+        // Special case of integer overflow
+        testLongFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0L);
+    }
+
+    /**
+     * Test the long floorDiv and floorMod methods.
+     * Math and StrictMath are tested and the same results are expected for both.
+     */
+    static void testLongFloorDivMod(long x, long y, Object divExpected, Object modExpected) {
+        testLongFloorDiv(x, y, divExpected);
+        testLongFloorMod(x, y, modExpected);
+    }
+
+    /**
+     * Test FloorDiv with long arguments against expected value.
+     * The expected value is usually a Long but in some cases  is
+     * an ArithmeticException.
+     *
+     * @param x dividend
+     * @param y modulus
+     * @param expected expected value,
+     */
+    static void testLongFloorDiv(long x, long y, Object expected) {
+        Object result = doFloorDiv(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: long Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorDiv(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: long StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+    }
+
+    /**
+     * Test FloorMod of long arguments against expected value.
+     * The expected value is usually a Long but in some cases  is
+     * an ArithmeticException.
+     *
+     * @param x dividend
+     * @param y modulus
+     * @param expected expected value
+     */
+    static void testLongFloorMod(long x, long y, Object expected) {
+        Object result = doFloorMod(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: long Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorMod(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: long StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+
+        try {
+            // Verify the result against BigDecimal rounding mode.
+            BigDecimal xD = new BigDecimal(x);
+            BigDecimal yD = new BigDecimal(y);
+            BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR);
+            resultD = resultD.multiply(yD);
+            resultD = xD.subtract(resultD);
+            long fr = resultD.longValue();
+            if (!result.equals(fr)) {
+                fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
+
+            }
+        } catch (ArithmeticException ae) {
+            if (y != 0) {
+                fail("FAIL: long Math.floorMod(%d, %d); unexpected ArithmeticException from bigdecimal");
+            }
+        }
+    }
+
+    /**
+     * Test the floorDiv and floorMod methods for mixed long and int.
+     */
+    @Test
+    public void testLongIntFloorDivMod() {
+        testLongIntFloorDivMod(4L, 0, new ArithmeticException(), new ArithmeticException()); // Should throw ArithmeticException
+        testLongIntFloorDivMod(4L, 3, 1L, 1);
+        testLongIntFloorDivMod(3L, 3, 1L, 0);
+        testLongIntFloorDivMod(2L, 3, 0L, 2);
+        testLongIntFloorDivMod(1L, 3, 0L, 1);
+        testLongIntFloorDivMod(0L, 3, 0L, 0);
+        testLongIntFloorDivMod(4L, -3, -2L, -2);
+        testLongIntFloorDivMod(3L, -3, -1L, 0);
+        testLongIntFloorDivMod(2L, -3, -1L, -1);
+        testLongIntFloorDivMod(1L, -3, -1L, -2);
+        testLongIntFloorDivMod(0L, -3, 0L, 0);
+        testLongIntFloorDivMod(-1L, 3, -1L, 2);
+        testLongIntFloorDivMod(-2L, 3, -1L, 1);
+        testLongIntFloorDivMod(-3L, 3, -1L, 0);
+        testLongIntFloorDivMod(-4L, 3, -2L, 2);
+        testLongIntFloorDivMod(-1L, -3, 0L, -1);
+        testLongIntFloorDivMod(-2L, -3, 0L, -2);
+        testLongIntFloorDivMod(-3L, -3, 1L, 0);
+        testLongIntFloorDivMod(-4L, -3, 1L, -1);
+
+        testLongIntFloorDivMod(Long.MAX_VALUE, 1, Long.MAX_VALUE, 0);
+        testLongIntFloorDivMod(Long.MAX_VALUE, -1, -Long.MAX_VALUE, 0);
+        testLongIntFloorDivMod(Long.MAX_VALUE, 3, Long.MAX_VALUE / 3L, 1);
+        testLongIntFloorDivMod(Long.MAX_VALUE - 1L, 3, (Long.MAX_VALUE - 1L) / 3L, 0);
+        testLongIntFloorDivMod(Long.MIN_VALUE, 3, Long.MIN_VALUE / 3L - 1L, 1);
+        testLongIntFloorDivMod(Long.MIN_VALUE + 1L, 3, Long.MIN_VALUE / 3L - 1L, 2);
+        testLongIntFloorDivMod(Long.MIN_VALUE + 1, -1, Long.MAX_VALUE, 0);
+        // Special case of integer overflow
+        testLongIntFloorDivMod(Long.MIN_VALUE, -1, Long.MIN_VALUE, 0);
+    }
+
+    /**
+     * Test the integer floorDiv and floorMod methods.
+     * Math and StrictMath are tested and the same results are expected for both.
+     */
+    static void testLongIntFloorDivMod(long x, int y, Object divExpected, Object modExpected) {
+        testLongIntFloorDiv(x, y, divExpected);
+        testLongIntFloorMod(x, y, modExpected);
+    }
+
+    /**
+     * Test FloorDiv with long arguments against expected value.
+     * The expected value is usually a Long but in some cases  is
+     * an ArithmeticException.
+     *
+     * @param x dividend
+     * @param y modulus
+     * @param expected expected value,
+     */
+    static void testLongIntFloorDiv(long x, int y, Object expected) {
+        Object result = doFloorDiv(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: long Math.floorDiv(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorDiv(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: long StrictMath.floorDiv(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+    }
+
+    /**
+     * Test FloorMod of long arguments against expected value.
+     * The expected value is usually a Long but in some cases  is
+     * an ArithmeticException.
+     *
+     * @param x dividend
+     * @param y modulus
+     * @param expected expected value
+     */
+    static void testLongIntFloorMod(long x, int y, Object expected) {
+        Object result = doFloorMod(x, y);
+        if (!resultEquals(result, expected)) {
+            fail("FAIL: long Math.floorMod(%d, %d) = %s; expected %s%n", x, y, result, expected);
+        }
+
+        Object strict_result = doStrictFloorMod(x, y);
+        if (!resultEquals(strict_result, expected)) {
+            fail("FAIL: long StrictMath.floorMod(%d, %d) = %s; expected %s%n", x, y, strict_result, expected);
+        }
+
+        try {
+            // Verify the result against BigDecimal rounding mode.
+            BigDecimal xD = new BigDecimal(x);
+            BigDecimal yD = new BigDecimal(y);
+            BigDecimal resultD = xD.divide(yD, RoundingMode.FLOOR);
+            resultD = resultD.multiply(yD);
+            resultD = xD.subtract(resultD);
+            // Android-changed: compare with int value for int Math.floorMod(long, int)
+            // long fr = resultD.longValue();
+            int fr = resultD.intValue();
+            if (!result.equals(fr)) {
+                fail("FAIL: Long.floorMod(%d, %d) = %d is different than BigDecimal result: %d%n", x, y, result, fr);
+            }
+        } catch (ArithmeticException ae) {
+            if (y != 0) {
+                fail("FAIL: long Math.floorMod(%d, %d); unexpected ArithmeticException from bigdecimal");
+            }
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorDiv(int x, int y) {
+        try {
+            return Math.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorDiv(long x, int y) {
+        try {
+            return Math.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorDiv(long x, long y) {
+        try {
+            return Math.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorMod(int x, int y) {
+        try {
+            return Math.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorMod(long x, int y) {
+        try {
+            return Math.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doFloorMod(long x, long y) {
+        try {
+            return Math.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorDiv(int x, int y) {
+        try {
+            return StrictMath.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorDiv(long x, int y) {
+        try {
+            return StrictMath.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorDiv(long x, long y) {
+        try {
+            return StrictMath.floorDiv(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorMod(int x, int y) {
+        try {
+            return StrictMath.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorMod(long x, int y) {
+        try {
+            return StrictMath.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Invoke floorDiv and return the result or any exception.
+     * @param x the x value
+     * @param y the y value
+     * @return the result Integer or an exception.
+     */
+    static Object doStrictFloorMod(long x, long y) {
+        try {
+            return StrictMath.floorMod(x, y);
+        } catch (ArithmeticException ae) {
+            return ae;
+        }
+    }
+
+    /**
+     * Returns a boolean by comparing the result and the expected value.
+     * The equals method is not defined for ArithmeticException but it is
+     * desirable to have equals return true if the expected and the result
+     * both threw the same exception (class and message.)
+     *
+     * @param result the result from testing the method
+     * @param expected the expected value
+     * @return true if the result is equal to the expected values; false otherwise.
+     */
+    static boolean resultEquals(Object result, Object expected) {
+        if (result.getClass() != expected.getClass()) {
+            fail("FAIL: Result type mismatch, %s; expected: %s%n",
+                    result.getClass().getName(), expected.getClass().getName());
+            return false;
+        }
+
+        if (result.equals(expected)) {
+            return true;
+        }
+        // Handle special case to compare ArithmeticExceptions
+        if (result instanceof ArithmeticException && expected instanceof ArithmeticException) {
+            return true;
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/ojluni/src/test/java/lang/Math/ExactArithTests.java b/ojluni/src/test/java/lang/Math/ExactArithTests.java
new file mode 100644
index 0000000..3109d41
--- /dev/null
+++ b/ojluni/src/test/java/lang/Math/ExactArithTests.java
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.lang.Math;
+
+import java.math.BigInteger;
+
+import org.testng.annotations.Test;
+import org.testng.Assert;
+
+import static org.testng.Assert.fail;
+
+// Android-changed: Added test annotations, remove main() method.
+/**
+ * @test Test for Math.*Exact integer and long methods.
+ * @bug 6708398
+ * @summary Basic tests for Math exact arithmetic operations.
+ *
+ * @author Roger Riggs
+ */
+public class ExactArithTests {
+
+    /**
+     * Test Math.addExact, multiplyExact, subtractExact, toIntValue methods
+     * with {@code int} arguments.
+     */
+    @Test
+    public void testIntegerExact() {
+        testIntegerExact(0, 0);
+        testIntegerExact(1, 1);
+        testIntegerExact(1, -1);
+        testIntegerExact(-1, 1);
+        testIntegerExact(1000, 2000);
+
+        testIntegerExact(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        testIntegerExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testIntegerExact(Integer.MIN_VALUE, 1);
+        testIntegerExact(Integer.MAX_VALUE, 1);
+        testIntegerExact(Integer.MIN_VALUE, 2);
+        testIntegerExact(Integer.MAX_VALUE, 2);
+        testIntegerExact(Integer.MIN_VALUE, -1);
+        testIntegerExact(Integer.MAX_VALUE, -1);
+        testIntegerExact(Integer.MIN_VALUE, -2);
+        testIntegerExact(Integer.MAX_VALUE, -2);
+
+    }
+
+    /**
+     * Test exact arithmetic by comparing with the same operations using long
+     * and checking that the result is the same as the integer truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testIntegerExact(int x, int y) {
+        try {
+            // Test addExact
+            int sum = Math.addExact(x, y);
+            long sum2 = (long) x + (long) y;
+            if ((int) sum2 != sum2) {
+                fail("FAIL: int Math.addExact(" + x + " + " + y + ") = " + sum + "; expected Arithmetic exception");
+            } else if (sum != sum2) {
+                fail("FAIL: long Math.addExact(" + x + " + " + y + ") = " + sum + "; expected: " + sum2);
+            }
+        } catch (ArithmeticException ex) {
+            long sum2 = (long) x + (long) y;
+            if ((int) sum2 == sum2) {
+                fail("FAIL: int Math.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);
+
+            }
+        }
+
+        try {
+            // Test subtractExact
+            int diff = Math.subtractExact(x, y);
+            long diff2 = (long) x - (long) y;
+            if ((int) diff2 != diff2) {
+                fail("FAIL: int Math.subtractExact(" + x + " - " + y + ") = " + diff + "; expected: " + diff2);
+            }
+
+        } catch (ArithmeticException ex) {
+            long diff2 = (long) x - (long) y;
+            if ((int) diff2 == diff2) {
+                fail("FAIL: int Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test multiplyExact
+            int product = Math.multiplyExact(x, y);
+            long m2 = (long) x * (long) y;
+            if ((int) m2 != m2) {
+                fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ") = " + product + "; expected: " + m2);
+            }
+        } catch (ArithmeticException ex) {
+            long m2 = (long) x * (long) y;
+            if ((int) m2 == m2) {
+                fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test incrementExact
+            int inc = Math.incrementExact(x);
+            long inc2 = (long) x + 1L;
+            if ((int) inc2 != inc2) {
+                fail("FAIL: int Math.incrementExact(" + x + ") = " + inc + "; expected Arithmetic exception");
+            } else if (inc != inc2) {
+                fail("FAIL: long Math.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);
+            }
+        } catch (ArithmeticException ex) {
+            long inc2 = (long) x + 1L;
+            if ((int) inc2 == inc2) {
+                fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+
+            }
+        }
+
+        try {
+            // Test decrementExact
+            int dec = Math.decrementExact(x);
+            long dec2 = (long) x - 1L;
+            if ((int) dec2 != dec2) {
+                fail("FAIL: int Math.decrementExact(" + x + ") = " + dec + "; expected Arithmetic exception");
+            } else if (dec != dec2) {
+                fail("FAIL: long Math.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);
+            }
+        } catch (ArithmeticException ex) {
+            long dec2 = (long) x - 1L;
+            if ((int) dec2 == dec2) {
+                fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+
+            }
+        }
+
+        try {
+            // Test negateExact
+            int neg = Math.negateExact(x);
+            long neg2 = -((long)x) ;
+            if ((int) neg2 != neg2) {
+                fail("FAIL: int Math.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");
+            } else if (neg != neg2) {
+                fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
+            }
+        } catch (ArithmeticException ex) {
+            long neg2 = (long) x - 1L;
+            if ((int) neg2 == neg2) {
+                fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
+
+            }
+        }
+    }
+
+    /**
+     * Test Math.addExact, multiplyExact, subtractExact, toIntExact methods
+     * with {@code long} arguments.
+     */
+    @Test
+    static void testLongExact() {
+        testLongExactTwice(0, 0);
+        testLongExactTwice(1, 1);
+        testLongExactTwice(1, -1);
+        testLongExactTwice(1000, 2000);
+
+        testLongExactTwice(Long.MIN_VALUE, Long.MIN_VALUE);
+        testLongExactTwice(Long.MAX_VALUE, Long.MAX_VALUE);
+        testLongExactTwice(Long.MIN_VALUE, 1);
+        testLongExactTwice(Long.MAX_VALUE, 1);
+        testLongExactTwice(Long.MIN_VALUE, 2);
+        testLongExactTwice(Long.MAX_VALUE, 2);
+        testLongExactTwice(Long.MIN_VALUE, -1);
+        testLongExactTwice(Long.MAX_VALUE, -1);
+        testLongExactTwice(Long.MIN_VALUE, -2);
+        testLongExactTwice(Long.MAX_VALUE, -2);
+        testLongExactTwice(Long.MIN_VALUE/2, 2);
+        testLongExactTwice(Long.MAX_VALUE, 2);
+        testLongExactTwice(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testLongExactTwice(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+        testLongExactTwice(Integer.MAX_VALUE+1, Integer.MAX_VALUE+1);
+        testLongExactTwice(Integer.MAX_VALUE+1, -Integer.MAX_VALUE+1);
+        testLongExactTwice(Integer.MIN_VALUE-1, Integer.MIN_VALUE-1);
+        testLongExactTwice(Integer.MIN_VALUE-1, -Integer.MIN_VALUE-1);
+        testLongExactTwice(Integer.MIN_VALUE/2, 2);
+
+    }
+
+    /**
+     * Test each of the exact operations with the arguments and
+     * with the arguments reversed.
+     * @param x
+     * @param y
+     */
+    static void testLongExactTwice(long x, long y) {
+        testLongExact(x, y);
+        testLongExact(y, x);
+    }
+
+
+    /**
+     * Test long exact arithmetic by comparing with the same operations using BigInteger
+     * and checking that the result is the same as the long truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testLongExact(long x, long y) {
+        BigInteger resultBig = null;
+        final BigInteger xBig = BigInteger.valueOf(x);
+        final BigInteger yBig = BigInteger.valueOf(y);
+        try {
+            // Test addExact
+            resultBig = xBig.add(yBig);
+            long sum = Math.addExact(x, y);
+            checkResult("long Math.addExact", x, y, sum, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.addExact(" + x + " + " + y + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test subtractExact
+            resultBig = xBig.subtract(yBig);
+            long diff = Math.subtractExact(x, y);
+            checkResult("long Math.subtractExact", x, y, diff, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test multiplyExact
+            resultBig = xBig.multiply(yBig);
+            long product = Math.multiplyExact(x, y);
+            checkResult("long Math.multiplyExact", x, y, product, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test incrementExact
+            resultBig = xBig.add(BigInteger.ONE);
+            long inc = Math.incrementExact(x);
+            checkResult("long Math.incrementExact", x, 1L, inc, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test decrementExact
+            resultBig = xBig.subtract(BigInteger.ONE);
+            long dec = Math.decrementExact(x);
+            checkResult("long Math.decrementExact", x, 1L, dec, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test negateExact
+            resultBig = xBig.negate();
+            long dec = Math.negateExact(x);
+            checkResult("long Math.negateExact", x, 0L, dec, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test toIntExact
+            int value = Math.toIntExact(x);
+            if ((long)value != x) {
+                fail("FAIL: " + "long Math.toIntExact" + "(" + x + ") = " + value + "; expected an arithmetic exception: ");
+            }
+        } catch (ArithmeticException ex) {
+            if (resultBig.bitLength() <= 32) {
+                fail("FAIL: long Math.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+    }
+
+    /**
+     * Compare the expected and actual results.
+     * @param message message for the error
+     * @param x first argument
+     * @param y second argument
+     * @param result actual result value
+     * @param expected expected result value
+     */
+    static void checkResult(String message, long x, long y, long result, BigInteger expected) {
+        BigInteger resultBig = BigInteger.valueOf(result);
+        if (!inLongRange(expected)) {
+            fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected an arithmetic exception: ");
+        } else if (!resultBig.equals(expected)) {
+            fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected " + expected);
+        }
+    }
+
+    /**
+     * Check if the value fits in 64 bits (a long).
+     * @param value
+     * @return true if the value fits in 64 bits (including the sign).
+     */
+    static boolean inLongRange(BigInteger value) {
+        return value.bitLength() <= 63;
+    }
+
+    /**
+     * Test Math.multiplyExact method with {@code long} and {@code int}
+     * arguments.
+     */
+    @Test
+    static void testLongIntExact() {
+        testLongIntExact(0, 0);
+        testLongIntExact(1, 1);
+        testLongIntExact(1, -1);
+        testLongIntExact(1000, 2000);
+
+        testLongIntExact(Long.MIN_VALUE, Integer.MIN_VALUE);
+        testLongIntExact(Long.MAX_VALUE, Integer.MAX_VALUE);
+        testLongIntExact(Long.MIN_VALUE, 1);
+        testLongIntExact(Long.MAX_VALUE, 1);
+        testLongIntExact(Long.MIN_VALUE, 2);
+        testLongIntExact(Long.MAX_VALUE, 2);
+        testLongIntExact(Long.MIN_VALUE, -1);
+        testLongIntExact(Long.MAX_VALUE, -1);
+        testLongIntExact(Long.MIN_VALUE, -2);
+        testLongIntExact(Long.MAX_VALUE, -2);
+        testLongIntExact(Long.MIN_VALUE/2, 2);
+        testLongIntExact(Long.MAX_VALUE, 2);
+        testLongIntExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testLongIntExact(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+        testLongIntExact((long)Integer.MAX_VALUE+1L, Integer.MAX_VALUE);
+        testLongIntExact((long)Integer.MAX_VALUE+1L, -Integer.MAX_VALUE+1);
+        testLongIntExact((long)Integer.MIN_VALUE-1L, Integer.MIN_VALUE);
+        testLongIntExact((long)Integer.MIN_VALUE-1, Integer.MAX_VALUE);
+        testLongIntExact(Integer.MIN_VALUE/2, 2);
+    }
+
+    /**
+     * Test long-int exact arithmetic by comparing with the same operations using BigInteger
+     * and checking that the result is the same as the long truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testLongIntExact(long x, int y) {
+        BigInteger resultBig = null;
+        final BigInteger xBig = BigInteger.valueOf(x);
+        final BigInteger yBig = BigInteger.valueOf(y);
+
+        try {
+            // Test multiplyExact
+            resultBig = xBig.multiply(yBig);
+            long product = Math.multiplyExact(x, y);
+            checkResult("long Math.multiplyExact", x, y, product, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/ojluni/src/test/java/lang/Math/MultiplicationTests.java b/ojluni/src/test/java/lang/Math/MultiplicationTests.java
new file mode 100644
index 0000000..5bd17a6
--- /dev/null
+++ b/ojluni/src/test/java/lang/Math/MultiplicationTests.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.lang.Math;
+
+import java.math.BigInteger;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+
+// Android-removed: Private constructor, main() method, randomness tests.
+public class MultiplicationTests {
+
+    // Calculate high 64 bits of 128 product using BigInteger.
+    private static long multiplyHighBigInt(long x, long y) {
+        return BigInteger.valueOf(x).multiply(BigInteger.valueOf(y))
+            .shiftRight(64).longValue();
+    }
+
+    @Test
+    public void testMultiplyHigh() {
+        // check some boundary cases
+        long[][] v = new long[][]{
+            {0L, 0L},
+            {-1L, 0L},
+            {0L, -1L},
+            {1L, 0L},
+            {0L, 1L},
+            {-1L, -1L},
+            {-1L, 1L},
+            {1L, -1L},
+            {1L, 1L},
+            {Long.MAX_VALUE, Long.MAX_VALUE},
+            {Long.MAX_VALUE, -Long.MAX_VALUE},
+            {-Long.MAX_VALUE, Long.MAX_VALUE},
+            {-Long.MAX_VALUE, -Long.MAX_VALUE},
+            {Long.MAX_VALUE, Long.MIN_VALUE},
+            {Long.MIN_VALUE, Long.MAX_VALUE},
+            {Long.MIN_VALUE, Long.MIN_VALUE}
+        };
+
+        for (long[] xy : v) {
+            long x = xy[0];
+            long y = xy[1];
+            long p1 = multiplyHighBigInt(x, y);
+            long p2 = Math.multiplyHigh(x, y);
+            assertEquals(p1, p2);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/ojluni/src/test/java/lang/StrictMath/ExactArithTests.java b/ojluni/src/test/java/lang/StrictMath/ExactArithTests.java
new file mode 100644
index 0000000..0ce1306
--- /dev/null
+++ b/ojluni/src/test/java/lang/StrictMath/ExactArithTests.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.lang.StrictMath;
+
+import java.math.BigInteger;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.fail;
+
+/**
+ * @test Test for StrictMath.*Exact integer and long methods.
+ * @bug 6708398
+ * @summary Basic tests for StrictMath exact arithmetic operations.
+ *
+ * @author Roger Riggs
+ */
+public class ExactArithTests {
+
+    // BEGIN Android-removed: main(), error counter, replace fail() with testng.Assert.fail().
+    /**
+     * The count of test errors.
+     *
+    private static int errors = 0;
+
+    /**
+     * @param args the command line arguments
+     *
+    public static void main(String[] args) {
+        testIntegerExact();
+        testLongExact();
+
+        if (errors > 0) {
+            throw new RuntimeException(errors + " errors found in ExactArithTests.");
+        }
+    }
+
+    static void fail(String message) {
+        errors++;
+        System.err.println(message);
+    }
+    */
+    // END Android-removed: main(), error counter.
+
+    /**
+     * Test StrictMath.addExact, multiplyExact, subtractExact, toIntValue methods
+     * with {@code int} arguments.
+     */
+    // Android-added: @Test annotation.
+    @Test
+    static void testIntegerExact() {
+        testIntegerExact(0, 0);
+        testIntegerExact(1, 1);
+        testIntegerExact(1, -1);
+        testIntegerExact(-1, 1);
+        testIntegerExact(1000, 2000);
+
+        testIntegerExact(Integer.MIN_VALUE, Integer.MIN_VALUE);
+        testIntegerExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testIntegerExact(Integer.MIN_VALUE, 1);
+        testIntegerExact(Integer.MAX_VALUE, 1);
+        testIntegerExact(Integer.MIN_VALUE, 2);
+        testIntegerExact(Integer.MAX_VALUE, 2);
+        testIntegerExact(Integer.MIN_VALUE, -1);
+        testIntegerExact(Integer.MAX_VALUE, -1);
+        testIntegerExact(Integer.MIN_VALUE, -2);
+        testIntegerExact(Integer.MAX_VALUE, -2);
+
+    }
+
+    /**
+     * Test exact arithmetic by comparing with the same operations using long
+     * and checking that the result is the same as the integer truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testIntegerExact(int x, int y) {
+        try {
+            // Test addExact
+            int sum = StrictMath.addExact(x, y);
+            long sum2 = (long) x + (long) y;
+            if ((int) sum2 != sum2) {
+                fail("FAIL: int StrictMath.addExact(" + x + " + " + y + ") = " + sum + "; expected Arithmetic exception");
+            } else if (sum != sum2) {
+                fail("FAIL: long StrictMath.addExact(" + x + " + " + y + ") = " + sum + "; expected: " + sum2);
+            }
+        } catch (ArithmeticException ex) {
+            long sum2 = (long) x + (long) y;
+            if ((int) sum2 == sum2) {
+                fail("FAIL: int StrictMath.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);
+
+            }
+        }
+
+        try {
+            // Test subtractExact
+            int diff = StrictMath.subtractExact(x, y);
+            long diff2 = (long) x - (long) y;
+            if ((int) diff2 != diff2) {
+                fail("FAIL: int StrictMath.subtractExact(" + x + " - " + y + ") = " + diff + "; expected: " + diff2);
+            }
+
+        } catch (ArithmeticException ex) {
+            long diff2 = (long) x - (long) y;
+            if ((int) diff2 == diff2) {
+                fail("FAIL: int StrictMath.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test multiplyExact
+            int product = StrictMath.multiplyExact(x, y);
+            long m2 = (long) x * (long) y;
+            if ((int) m2 != m2) {
+                fail("FAIL: int StrictMath.multiplyExact(" + x + " * " + y + ") = " + product + "; expected: " + m2);
+            }
+        } catch (ArithmeticException ex) {
+            long m2 = (long) x * (long) y;
+            if ((int) m2 == m2) {
+                fail("FAIL: int StrictMath.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+    }
+
+    /**
+     * Test StrictMath.addExact, multiplyExact, subtractExact, toIntExact methods
+     * with {@code long} arguments.
+     */
+    // Android-added: @Test annotation.
+    @Test
+    static void testLongExact() {
+        testLongExactTwice(0, 0);
+        testLongExactTwice(1, 1);
+        testLongExactTwice(1, -1);
+        testLongExactTwice(1000, 2000);
+
+        testLongExactTwice(Long.MIN_VALUE, Long.MIN_VALUE);
+        testLongExactTwice(Long.MAX_VALUE, Long.MAX_VALUE);
+        testLongExactTwice(Long.MIN_VALUE, 1);
+        testLongExactTwice(Long.MAX_VALUE, 1);
+        testLongExactTwice(Long.MIN_VALUE, 2);
+        testLongExactTwice(Long.MAX_VALUE, 2);
+        testLongExactTwice(Long.MIN_VALUE, -1);
+        testLongExactTwice(Long.MAX_VALUE, -1);
+        testLongExactTwice(Long.MIN_VALUE, -2);
+        testLongExactTwice(Long.MAX_VALUE, -2);
+        testLongExactTwice(Long.MIN_VALUE/2, 2);
+        testLongExactTwice(Long.MAX_VALUE, 2);
+        testLongExactTwice(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testLongExactTwice(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+        testLongExactTwice(Integer.MAX_VALUE+1, Integer.MAX_VALUE+1);
+        testLongExactTwice(Integer.MAX_VALUE+1, -Integer.MAX_VALUE+1);
+        testLongExactTwice(Integer.MIN_VALUE-1, Integer.MIN_VALUE-1);
+        testLongExactTwice(Integer.MIN_VALUE-1, -Integer.MIN_VALUE-1);
+        testLongExactTwice(Integer.MIN_VALUE/2, 2);
+
+    }
+
+    /**
+     * Test each of the exact operations with the arguments and
+     * with the arguments reversed.
+     * @param x
+     * @param y
+     */
+    static void testLongExactTwice(long x, long y) {
+        testLongExact(x, y);
+        testLongExact(y, x);
+    }
+
+
+    /**
+     * Test long exact arithmetic by comparing with the same operations using BigInteger
+     * and checking that the result is the same as the long truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testLongExact(long x, long y) {
+        BigInteger resultBig = null;
+        final BigInteger xBig = BigInteger.valueOf(x);
+        final BigInteger yBig = BigInteger.valueOf(y);
+        try {
+            // Test addExact
+            resultBig = xBig.add(yBig);
+            long sum = StrictMath.addExact(x, y);
+            checkResult("long StrictMath.addExact", x, y, sum, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long StrictMath.addExact(" + x + " + " + y + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test subtractExact
+            resultBig = xBig.subtract(yBig);
+            long diff = StrictMath.subtractExact(x, y);
+            checkResult("long StrictMath.subtractExact", x, y, diff, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long StrictMath.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test multiplyExact
+            resultBig = xBig.multiply(yBig);
+            long product = StrictMath.multiplyExact(x, y);
+            checkResult("long StrictMath.multiplyExact", x, y, product, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long StrictMath.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test toIntExact
+            int value = StrictMath.toIntExact(x);
+            if ((long)value != x) {
+                fail("FAIL: " + "long StrictMath.toIntExact" + "(" + x + ") = " + value + "; expected an arithmetic exception: ");
+            }
+        } catch (ArithmeticException ex) {
+            if (resultBig.bitLength() <= 32) {
+                fail("FAIL: long StrictMath.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+    }
+
+    /**
+     * Compare the expected and actual results.
+     * @param message message for the error
+     * @param x first argument
+     * @param y second argument
+     * @param result actual result value
+     * @param expected expected result value
+     */
+    static void checkResult(String message, long x, long y, long result, BigInteger expected) {
+        BigInteger resultBig = BigInteger.valueOf(result);
+        if (!inLongRange(expected)) {
+            fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected an arithmetic exception: ");
+        } else if (!resultBig.equals(expected)) {
+            fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected " + expected);
+        }
+    }
+
+    /**
+     * Check if the value fits in 64 bits (a long).
+     * @param value
+     * @return true if the value fits in 64 bits (including the sign).
+     */
+    static boolean inLongRange(BigInteger value) {
+        return value.bitLength() <= 63;
+    }
+
+    // BEGIN Android-added: add multiplyExact(long, int) based on Math.ExactArithTests.
+    /**
+     * Test StrictMath.multiplyExact method with {@code long} and {@code int}
+     * arguments.
+     */
+    @Test
+    static void testLongIntExact() {
+        testLongIntExact(0, 0);
+        testLongIntExact(1, 1);
+        testLongIntExact(1, -1);
+        testLongIntExact(1000, 2000);
+
+        testLongIntExact(Long.MIN_VALUE, Integer.MIN_VALUE);
+        testLongIntExact(Long.MAX_VALUE, Integer.MAX_VALUE);
+        testLongIntExact(Long.MIN_VALUE, 1);
+        testLongIntExact(Long.MAX_VALUE, 1);
+        testLongIntExact(Long.MIN_VALUE, 2);
+        testLongIntExact(Long.MAX_VALUE, 2);
+        testLongIntExact(Long.MIN_VALUE, -1);
+        testLongIntExact(Long.MAX_VALUE, -1);
+        testLongIntExact(Long.MIN_VALUE, -2);
+        testLongIntExact(Long.MAX_VALUE, -2);
+        testLongIntExact(Long.MIN_VALUE/2, 2);
+        testLongIntExact(Long.MAX_VALUE, 2);
+        testLongIntExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
+        testLongIntExact(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+        testLongIntExact((long)Integer.MAX_VALUE+1L, Integer.MAX_VALUE);
+        testLongIntExact((long)Integer.MAX_VALUE+1L, -Integer.MAX_VALUE+1);
+        testLongIntExact((long)Integer.MIN_VALUE-1L, Integer.MIN_VALUE);
+        testLongIntExact((long)Integer.MIN_VALUE-1, Integer.MAX_VALUE);
+        testLongIntExact(Integer.MIN_VALUE/2, 2);
+    }
+
+    /**
+     * Test long-int exact arithmetic by comparing with the same operations using BigInteger
+     * and checking that the result is the same as the long truncation.
+     * Errors are reported with {@link fail}.
+     *
+     * @param x first parameter
+     * @param y second parameter
+     */
+    static void testLongIntExact(long x, int y) {
+        BigInteger resultBig = null;
+        final BigInteger xBig = BigInteger.valueOf(x);
+        final BigInteger yBig = BigInteger.valueOf(y);
+
+        try {
+            // Test multiplyExact
+            resultBig = xBig.multiply(yBig);
+            long product = StrictMath.multiplyExact(x, y);
+            checkResult("long StrictMath.multiplyExact", x, y, product, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long StrictMath.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+    }
+    // END Android-added: add multiplyExact(long, int) based on Math.ExactArithTests.
+}
\ No newline at end of file
diff --git a/ojluni/src/test/java/lang/StrictMath/MultiplicationTests.java b/ojluni/src/test/java/lang/StrictMath/MultiplicationTests.java
new file mode 100644
index 0000000..3489eee
--- /dev/null
+++ b/ojluni/src/test/java/lang/StrictMath/MultiplicationTests.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @build jdk.test.lib.RandomFactory
+ * @run main MultiplicationTests
+ * @bug 5100935
+ * @summary Tests for multiplication methods (use -Dseed=X to set PRNG seed)
+ * @key randomness
+ */
+package test.java.lang.StrictMath;
+
+import java.math.BigInteger;
+// Android-removed: main(), randomness
+// import jdk.test.lib.RandomFactory;
+
+// Android-added: testng.
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import static org.testng.Assert.fail;
+
+public class MultiplicationTests {
+    private MultiplicationTests(){}
+
+    // BEGIN Android-removed: randomness, main().
+    /*
+    // Number of random products to test.
+    private static final int COUNT = 1 << 16;
+
+    // Initialize shared random number generator
+    private static java.util.Random rnd = RandomFactory.getRandom();
+    */
+    // END Android-removed: randomness, main().
+
+    // Calculate high 64 bits of 128 product using BigInteger.
+    private static long multiplyHighBigInt(long x, long y) {
+        return BigInteger.valueOf(x).multiply(BigInteger.valueOf(y))
+                .shiftRight(64).longValue();
+    }
+
+    // Check Math.multiplyHigh(x,y) against multiplyHighBigInt(x,y)
+    private static boolean check(long x, long y) {
+        long p1 = multiplyHighBigInt(x, y);
+        long p2 = StrictMath.multiplyHigh(x, y);
+        if (p1 != p2) {
+            // Android-changed: use testng fail().
+            //System.err.printf("Error - x:%d y:%d p1:%d p2:%d\n", x, y, p1, p2);
+            fail(String.format("Error - x:%d y:%d p1:%d p2:%d\n", x, y, p1, p2));
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    // Android-changed: testng, return void instead of int.
+    @Test
+    public static void testMultiplyHigh() {
+        int failures = 0;
+
+        // check some boundary cases
+        long[][] v = new long[][]{
+                {0L, 0L},
+                {-1L, 0L},
+                {0L, -1L},
+                {1L, 0L},
+                {0L, 1L},
+                {-1L, -1L},
+                {-1L, 1L},
+                {1L, -1L},
+                {1L, 1L},
+                {Long.MAX_VALUE, Long.MAX_VALUE},
+                {Long.MAX_VALUE, -Long.MAX_VALUE},
+                {-Long.MAX_VALUE, Long.MAX_VALUE},
+                {Long.MAX_VALUE, Long.MIN_VALUE},
+                {Long.MIN_VALUE, Long.MAX_VALUE},
+                {Long.MIN_VALUE, Long.MIN_VALUE}
+        };
+
+        for (long[] xy : v) {
+            if(!check(xy[0], xy[1])) {
+                failures++;
+            }
+        }
+
+        // Android-added: assert error counter.
+        Assert.assertEquals(failures, 0);
+
+        // BEGIN Android-removed: error counter, randomness, main().
+        /*
+        // check some random values
+        for (int i = 0; i < COUNT; i++) {
+            if (!check(rnd.nextLong(), rnd.nextLong())) {
+                failures++;
+            }
+        }
+
+        return failures;
+        */
+        // END Android-removed: error counter, randomness, main().
+    }
+
+    // BEGIN Android-removed: error counter, randomness, main().
+    /*
+    public static void main(String argv[]) {
+        int failures = testMultiplyHigh();
+
+        if (failures > 0) {
+            System.err.println("Multiplication testing encountered "
+                    + failures + " failures.");
+            throw new RuntimeException();
+        } else {
+            System.out.println("MultiplicationTests succeeded");
+        }
+    }
+    */
+}
\ No newline at end of file
diff --git a/ojluni/src/test/java/time/tck/java/time/TCKDuration.java b/ojluni/src/test/java/time/tck/java/time/TCKDuration.java
index c12e914..fb11a30 100644
--- a/ojluni/src/test/java/time/tck/java/time/TCKDuration.java
+++ b/ojluni/src/test/java/time/tck/java/time/TCKDuration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,9 +65,11 @@
 import static java.time.temporal.ChronoUnit.MICROS;
 import static java.time.temporal.ChronoUnit.MILLIS;
 import static java.time.temporal.ChronoUnit.MINUTES;
+import static java.time.temporal.ChronoUnit.MONTHS;
 import static java.time.temporal.ChronoUnit.NANOS;
 import static java.time.temporal.ChronoUnit.SECONDS;
 import static java.time.temporal.ChronoUnit.WEEKS;
+import static java.time.temporal.ChronoUnit.YEARS;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
@@ -2266,6 +2268,133 @@
     }
 
     //-----------------------------------------------------------------------
+    //  truncated(TemporalUnit)
+    //-----------------------------------------------------------------------
+    TemporalUnit NINETY_MINS = new TemporalUnit() {
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(90);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isDateBased() {
+            return false;
+        }
+        @Override
+        public boolean isTimeBased() {
+            return true;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public String toString() {
+            return "NinetyMins";
+        }
+    };
+
+    TemporalUnit NINETY_FIVE_MINS = new TemporalUnit() {
+        @Override
+        public Duration getDuration() {
+            return Duration.ofMinutes(95);
+        }
+        @Override
+        public boolean isDurationEstimated() {
+            return false;
+        }
+        @Override
+        public boolean isDateBased() {
+            return false;
+        }
+        @Override
+        public boolean isTimeBased() {
+            return false;
+        }
+        @Override
+        public boolean isSupportedBy(Temporal temporal) {
+            return false;
+        }
+        @Override
+        public <R extends Temporal> R addTo(R temporal, long amount) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public long between(Temporal temporal1, Temporal temporal2) {
+            throw new UnsupportedOperationException();
+        }
+        @Override
+        public String toString() {
+            return "NinetyFiveMins";
+        }
+    };
+
+    @DataProvider(name="truncatedToValid")
+    Object[][] data_truncatedToValid() {
+        return new Object[][] {
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), NANOS, Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), MICROS, Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_000)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), MILLIS, Duration.ofSeconds(86400 + 3600 + 60 + 1, 1230_00_000)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), SECONDS, Duration.ofSeconds(86400 + 3600 + 60 + 1, 0)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), MINUTES, Duration.ofSeconds(86400 + 3600 + 60, 0)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), HOURS, Duration.ofSeconds(86400 + 3600, 0)},
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), DAYS, Duration.ofSeconds(86400, 0)},
+
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 123_456_789), NINETY_MINS, Duration.ofSeconds(86400 + 0, 0)},
+                {Duration.ofSeconds(86400 + 7200 + 60 + 1, 123_456_789), NINETY_MINS, Duration.ofSeconds(86400 + 5400, 0)},
+                {Duration.ofSeconds(86400 + 10800 + 60 + 1, 123_456_789), NINETY_MINS, Duration.ofSeconds(86400 + 10800, 0)},
+
+                {Duration.ofSeconds(-86400 - 3600 - 60 - 1, 123_456_789), MINUTES, Duration.ofSeconds(-86400 - 3600 - 60, 0 )},
+                {Duration.ofSeconds(-86400 - 3600 - 60 - 1, 123_456_789), MICROS, Duration.ofSeconds(-86400 - 3600 - 60 - 1, 123_457_000)},
+
+                {Duration.ofSeconds(86400 + 3600 + 60 + 1, 0), SECONDS, Duration.ofSeconds(86400 + 3600 + 60 + 1, 0)},
+                {Duration.ofSeconds(-86400 - 3600 - 120, 0), MINUTES, Duration.ofSeconds(-86400 - 3600 - 120, 0)},
+
+                {Duration.ofSeconds(-1, 0), SECONDS, Duration.ofSeconds(-1, 0)},
+                {Duration.ofSeconds(-1, 123_456_789), SECONDS, Duration.ofSeconds(0, 0)},
+                {Duration.ofSeconds(-1, 123_456_789), NANOS, Duration.ofSeconds(0, -876_543_211)},
+                {Duration.ofSeconds(0, 123_456_789), SECONDS, Duration.ofSeconds(0, 0)},
+                {Duration.ofSeconds(0, 123_456_789), NANOS, Duration.ofSeconds(0, 123_456_789)},
+        };
+    }
+
+    @Test(dataProvider="truncatedToValid")
+    public void test_truncatedTo_valid(Duration input, TemporalUnit unit, Duration expected) {
+        assertEquals(input.truncatedTo(unit), expected);
+    }
+
+    @DataProvider(name="truncatedToInvalid")
+    Object[][] data_truncatedToInvalid() {
+        return new Object[][] {
+                {Duration.ofSeconds(1, 123_456_789), NINETY_FIVE_MINS},
+                {Duration.ofSeconds(1, 123_456_789), WEEKS},
+                {Duration.ofSeconds(1, 123_456_789), MONTHS},
+                {Duration.ofSeconds(1, 123_456_789), YEARS},
+        };
+    }
+
+    @Test(dataProvider="truncatedToInvalid", expectedExceptions=DateTimeException.class)
+    public void test_truncatedTo_invalid(Duration input, TemporalUnit unit) {
+        input.truncatedTo(unit);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_truncatedTo_null() {
+        Duration.ofSeconds(1234).truncatedTo(null);
+    }
+
+    //-----------------------------------------------------------------------
     // dividedBy()
     //-----------------------------------------------------------------------
     @DataProvider(name="DividedBy")
@@ -2372,6 +2501,65 @@
     }
 
     //-----------------------------------------------------------------------
+    // dividedbyDur()
+    //-----------------------------------------------------------------------
+
+    @DataProvider(name="dividedByDur_provider")
+    Object[][] provider_dividedByDur() {
+        return new Object[][] {
+            {Duration.ofSeconds(0, 0), Duration.ofSeconds(1, 0), 0},
+            {Duration.ofSeconds(1, 0), Duration.ofSeconds(1, 0), 1},
+            {Duration.ofSeconds(6, 0), Duration.ofSeconds(3, 0), 2},
+            {Duration.ofSeconds(3, 0), Duration.ofSeconds(6, 0), 0},
+            {Duration.ofSeconds(7, 0), Duration.ofSeconds(3, 0), 2},
+
+            {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 333_333_333), 1},
+            {Duration.ofSeconds(0, 666_666_666), Duration.ofSeconds(0, 333_333_333), 2},
+            {Duration.ofSeconds(0, 333_333_333), Duration.ofSeconds(0, 666_666_666), 0},
+            {Duration.ofSeconds(0, 777_777_777), Duration.ofSeconds(0, 333_333_333), 2},
+
+            {Duration.ofSeconds(-7, 0), Duration.ofSeconds(3, 0), -2},
+            {Duration.ofSeconds(0, 7), Duration.ofSeconds(0, -3), -2},
+            {Duration.ofSeconds(0, -777_777_777), Duration.ofSeconds(0, 333_333_333), -2},
+
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), 29},
+            {Duration.ofSeconds(-432000L, 777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, 333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(14400L, -333_333_333L), -30},
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, 333_333_333L), -30},
+            {Duration.ofSeconds(432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), -29},
+            {Duration.ofSeconds(-432000L, -777_777_777L), Duration.ofSeconds(-14400L, -333_333_333L), 29},
+
+            {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(1, 0), Long.MAX_VALUE},
+            {Duration.ofSeconds(Long.MAX_VALUE, 0), Duration.ofSeconds(Long.MAX_VALUE, 0), 1},
+        };
+    }
+
+    @Test(dataProvider="dividedByDur_provider")
+    public void test_dividedByDur(Duration dividend, Duration divisor, long expected) {
+        assertEquals(dividend.dividedBy(divisor), expected);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_dividedByDur_zero() {
+       Duration t = Duration.ofSeconds(1, 0);
+       t.dividedBy(Duration.ZERO);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void test_dividedByDur_null() {
+       Duration t = Duration.ofSeconds(1, 0);
+       t.dividedBy(null);
+    }
+
+    @Test(expectedExceptions=ArithmeticException.class)
+    public void test_dividedByDur_overflow() {
+       Duration dur1 = Duration.ofSeconds(Long.MAX_VALUE, 0);
+       Duration dur2 = Duration.ofNanos(1);
+       dur1.dividedBy(dur2);
+    }
+
+    //-----------------------------------------------------------------------
     // negated()
     //-----------------------------------------------------------------------
     @Test
@@ -2454,6 +2642,147 @@
     }
 
     //-----------------------------------------------------------------------
+    // toSeconds()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toSeconds_provider")
+    Object[][] provider_toSeconds() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 31556926L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -31556927L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, 123_456_789), -31556926L},
+            {Duration.ofSeconds(0), 0L},
+            {Duration.ofSeconds(0, 123_456_789), 0L},
+            {Duration.ofSeconds(0, -123_456_789), -1L},
+            {Duration.ofSeconds(Long.MAX_VALUE), 9223372036854775807L},
+            {Duration.ofSeconds(Long.MIN_VALUE), -9223372036854775808L},
+        };
+    }
+
+    @Test(dataProvider="toSeconds_provider")
+    public void test_toSeconds(Duration dur, long seconds) {
+        assertEquals(dur.toSeconds(), seconds);
+    }
+
+    //-----------------------------------------------------------------------
+    // toDaysPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toDaysPart_provider")
+    Object[][] provider_toDaysPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 365L},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -365L},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 123_456_789), 0L},
+            {Duration.ofDays(365), 365L},
+            {Duration.ofHours(2), 0L},
+            {Duration.ofHours(-2), 0L},
+        };
+    }
+
+    @Test(dataProvider="toDaysPart_provider")
+    public void test_toDaysPart(Duration dur, long days) {
+        assertEquals(dur.toDaysPart(), days);
+    }
+
+    //-----------------------------------------------------------------------
+    // toHoursPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toHoursPart_provider")
+    Object[][] provider_toHoursPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 5},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -5},
+            {Duration.ofSeconds(48 * 60 + 46, 123_456_789), 0},
+            {Duration.ofHours(2), 2},
+            {Duration.ofHours(-2), -2},
+        };
+    }
+
+    @Test(dataProvider="toHoursPart_provider")
+    public void test_toHoursPart(Duration dur, int hours) {
+        assertEquals(dur.toHoursPart(), hours);
+    }
+
+    //-----------------------------------------------------------------------
+    // toMinutesPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toMinutesPart_provider")
+    Object[][] provider_toMinutesPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 48},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -48},
+            {Duration.ofSeconds(46, 123_456_789),0},
+            {Duration.ofMinutes(48), 48},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2),0},
+        };
+    }
+
+    @Test(dataProvider="toMinutesPart_provider")
+    public void test_toMinutesPart(Duration dur, int minutes) {
+        assertEquals(dur.toMinutesPart(), minutes);
+    }
+
+    //-----------------------------------------------------------------------
+    // toSecondsPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toSecondsPart_provider")
+    Object[][] provider_toSecondsPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 46},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), -47},
+            {Duration.ofSeconds(0, 123_456_789), 0},
+            {Duration.ofSeconds(46), 46},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toSecondsPart_provider")
+    public void test_toSecondsPart(Duration dur, int seconds) {
+        assertEquals(dur.toSecondsPart(), seconds);
+    }
+
+    //-----------------------------------------------------------------------
+    // toMillisPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toMillisPart_provider")
+    Object[][] provider_toMillisPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0},
+            {Duration.ofMillis(123), 123},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toMillisPart_provider")
+    public void test_toMillisPart(Duration dur, int millis) {
+        assertEquals(dur.toMillisPart(), millis);
+    }
+
+    //-----------------------------------------------------------------------
+    // toNanosPart()
+    //-----------------------------------------------------------------------
+    @DataProvider(name="toNanosPart_provider")
+    Object[][] provider_toNanosPart() {
+        return new Object[][] {
+            {Duration.ofSeconds(365 * 86400 + 5 * 3600 + 48 * 60 + 46, 123_456_789), 123_456_789},
+            {Duration.ofSeconds(-365 * 86400 - 5 * 3600 - 48 * 60 - 46, -123_456_789), 876_543_211},
+            {Duration.ofSeconds(5 * 3600 + 48 * 60 + 46, 0), 0},
+            {Duration.ofNanos(123_456_789), 123_456_789},
+            {Duration.ofHours(2), 0},
+            {Duration.ofHours(-2), 0},
+        };
+    }
+
+    @Test(dataProvider="toNanosPart_provider")
+    public void test_toNanosPart(Duration dur, int nanos) {
+        assertEquals(dur.toNanosPart(), nanos);
+    }
+
+    //-----------------------------------------------------------------------
     // compareTo()
     //-----------------------------------------------------------------------
     @Test
diff --git a/ojluni/src/test/java/time/tck/java/time/TCKLocalTime.java b/ojluni/src/test/java/time/tck/java/time/TCKLocalTime.java
index 9297510..f669a7c 100644
--- a/ojluni/src/test/java/time/tck/java/time/TCKLocalTime.java
+++ b/ojluni/src/test/java/time/tck/java/time/TCKLocalTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -102,6 +102,7 @@
 import java.time.OffsetDateTime;
 import java.time.OffsetTime;
 import java.time.Period;
+import java.time.Year;
 import java.time.ZoneId;
 import java.time.ZoneOffset;
 import java.time.ZonedDateTime;
@@ -137,6 +138,7 @@
 public class TCKLocalTime extends AbstractDateTimeTest {
 
     private static final ZoneOffset OFFSET_PTWO = ZoneOffset.ofHours(2);
+    private static final ZoneOffset OFFSET_MTWO = ZoneOffset.ofHours(-2);
     private static final ZoneId ZONE_PARIS = ZoneId.of("Europe/Paris");
 
     // Android-changed: This was originally non-static and initialized in @BeforeMethod,
@@ -422,6 +424,38 @@
         LocalTime.of(0, 0, 0, 1000000000);
     }
 
+     //-----------------------------------------------------------------------
+     // ofInstant()
+     //-----------------------------------------------------------------------
+     @DataProvider(name="instantFactory")
+     Object[][] data_instantFactory() {
+         return new Object[][] {
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), ZONE_PARIS, LocalTime.of(2, 2, 4, 500)},
+                 {Instant.ofEpochSecond(86400 + 3600 + 120 + 4, 500), OFFSET_MTWO, LocalTime.of(23, 2, 4, 500)},
+                 {Instant.ofEpochSecond(-86400 + 4, 500), OFFSET_PTWO, LocalTime.of(2, 0, 4, 500)},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MIN_VALUE, 1, 1, 0, 0), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalTime.MIN},
+                 {OffsetDateTime.of(LocalDateTime.of(Year.MAX_VALUE, 12, 31, 23, 59, 59, 999_999_999), ZoneOffset.UTC).toInstant(),
+                         ZoneOffset.UTC, LocalTime.MAX},
+         };
+     }
+
+     @Test(dataProvider="instantFactory")
+     public void factory_ofInstant(Instant instant, ZoneId zone, LocalTime expected) {
+         LocalTime test = LocalTime.ofInstant(instant, zone);
+         assertEquals(test, expected);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullInstant() {
+         LocalTime.ofInstant((Instant) null, ZONE_PARIS);
+     }
+
+     @Test(expectedExceptions=NullPointerException.class)
+     public void factory_ofInstant_nullZone() {
+         LocalTime.ofInstant(Instant.EPOCH, (ZoneId) null);
+     }
+
     //-----------------------------------------------------------------------
     // ofSecondOfDay(long)
     //-----------------------------------------------------------------------
@@ -2401,6 +2435,32 @@
         }
     }
 
+    //-----------------------------------------------------------------------
+    // toEpochSecond()
+    //--------------------------------------------------------------------------
+    @DataProvider(name="epochSecond")
+    Object[][] provider__toEpochSecond() {
+        return new Object[][] {
+        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO), -7200L},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1965, 12, 31), OFFSET_PTWO), -126282600L},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1995, 5, 3), OFFSET_MTWO), 799507800L},
+        {LocalTime.of(0, 0).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+                Instant.ofEpochSecond(-7200).getEpochSecond()},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1969, 12, 31), OFFSET_MTWO),
+                Instant.ofEpochSecond(-37800L).getEpochSecond()},
+        {LocalTime.of(11, 30).toEpochSecond(LocalDate.of(1970, 1, 1), OFFSET_PTWO),
+                LocalDateTime.of(1970, 1, 1, 11, 30).toEpochSecond(OFFSET_PTWO)},
+        };
+    }
+
+    @Test(dataProvider="epochSecond")
+    public void test_toEpochSecond(long actual, long expected) {
+        assertEquals(actual, expected);
+    }
+
+    //-----------------------------------------------------------------------
+    // toSecondOfDay_fromNanoOfDay_symmetry()
+    //-----------------------------------------------------------------------
     @Test
     public void test_toSecondOfDay_fromNanoOfDay_symmetry() {
         LocalTime t = LocalTime.of(0, 0);
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
index a13630a..326aed9 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestDateTimeFormatterBuilder.java
@@ -921,7 +921,9 @@
             // French Locale and ISO Chronology
             {FormatStyle.FULL, FormatStyle.FULL, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y 'à' HH:mm:ss zzzz"},
             {FormatStyle.LONG, FormatStyle.LONG, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y 'à' HH:mm:ss z"},
-            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y 'à' HH:mm:ss"},
+            // Android-changed: Since ICU 68, medium format uses ',' instead of 'à', to separate the date and time in French.
+            // {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y 'à' HH:mm:ss"},
+            {FormatStyle.MEDIUM, FormatStyle.MEDIUM, IsoChronology.INSTANCE, Locale.FRENCH, "d MMM y, HH:mm:ss"},
             {FormatStyle.SHORT, FormatStyle.SHORT, IsoChronology.INSTANCE, Locale.FRENCH, "dd/MM/y HH:mm"},
             {FormatStyle.FULL, null, IsoChronology.INSTANCE, Locale.FRENCH, "EEEE d MMMM y"},
             {FormatStyle.LONG, null, IsoChronology.INSTANCE, Locale.FRENCH, "d MMMM y"},
@@ -950,11 +952,15 @@
             {FormatStyle.FULL, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE zzzz ah:mm:ss"},
             {FormatStyle.LONG, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 z ah:mm:ss"},
             {FormatStyle.MEDIUM, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5 ah:mm:ss"},
-            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+            // Android-changed: Since ICU 68, use single 'y' to represent year in short form like other format styles
+            // {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d ah:mm"},
+            {FormatStyle.SHORT, FormatStyle.SHORT, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy/M/d ah:mm"},
             {FormatStyle.FULL, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5EEEE"},
             {FormatStyle.LONG, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
             {FormatStyle.MEDIUM, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy\u5e74M\u6708d\u65e5"},
-            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+            // Android-changed: Since ICU 68, use single 'y' to represent year in short form like other format styles
+            // {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gyy/M/d"},
+            {FormatStyle.SHORT, null, MinguoChronology.INSTANCE, Locale.CHINESE, "Gy/M/d"},
             {null, FormatStyle.FULL, MinguoChronology.INSTANCE, Locale.CHINESE, "zzzz ah:mm:ss"},
             {null, FormatStyle.LONG, MinguoChronology.INSTANCE, Locale.CHINESE, "z ah:mm:ss"},
             {null, FormatStyle.MEDIUM, MinguoChronology.INSTANCE, Locale.CHINESE, "ah:mm:ss"},
diff --git a/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java b/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
index bc0944f..619889b 100644
--- a/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
+++ b/ojluni/src/test/java/time/test/java/time/format/TestZoneTextPrinterParser.java
@@ -46,7 +46,6 @@
 
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
-import android.icu.impl.ZoneMeta;
 
 /*
  * @test
@@ -91,7 +90,7 @@
                     }
                     // Android-changed (http://b/33197219): TimeZone.getDisplayName() for
                     // non-canonical time zones are not correct.
-                    if (!zid.equals(ZoneMeta.getCanonicalCLDRID(zid))) {
+                    if (!zid.equals(getSystemCanonicalID(zid))) {
                         continue;
                     }
                     zdt = zdt.withZoneSameLocal(ZoneId.of(zid));
@@ -110,6 +109,20 @@
         }
     }
 
+    // BEGIN Android-added: Get non-custom system canonical time zone Id from ICU.
+    private static String getSystemCanonicalID(String zid) {
+        if (android.icu.util.TimeZone.UNKNOWN_ZONE_ID.equals(zid)) {
+            return zid;
+        }
+        boolean[] isSystemID = { false };
+        String canonicalID = android.icu.util.TimeZone.getCanonicalID(zid, isSystemID);
+        if (canonicalID == null || !isSystemID[0]) {
+            return null;
+        }
+        return canonicalID;
+    }
+    // END Android-added: Get non-custom system canonical time zone Id from ICU.
+
     private void printText(Locale locale, ZonedDateTime zdt, TextStyle style, TimeZone zone, String expected) {
         String result = getFormatter(locale, style).format(zdt);
         // Android-changed: TimeZone.getDisplayName() will never return "GMT".
diff --git a/ojluni/src/test/java/util/Collection/SetFactories.java b/ojluni/src/test/java/util/Collection/SetFactories.java
new file mode 100644
index 0000000..653f419
--- /dev/null
+++ b/ojluni/src/test/java/util/Collection/SetFactories.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.util.Collection;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Set.
+ * @run testng SetFactories
+ */
+
+@Test
+public class SetFactories {
+
+    Set<Integer> genSet() {
+        return new HashSet<>(Arrays.asList(1, 2, 3));
+    }
+
+    @Test
+    public void copyOfResultsEqual() {
+        Set<Integer> orig = genSet();
+        Set<Integer> copy = Set.copyOf(orig);
+
+        assertEquals(orig, copy);
+        assertEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfModifiedUnequal() {
+        Set<Integer> orig = genSet();
+        Set<Integer> copy = Set.copyOf(orig);
+        orig.add(4);
+
+        assertNotEquals(orig, copy);
+        assertNotEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfIdentity() {
+        Set<Integer> orig = genSet();
+        Set<Integer> copy1 = Set.copyOf(orig);
+        Set<Integer> copy2 = Set.copyOf(copy1);
+
+        assertNotSame(orig, copy1);
+        assertSame(copy1, copy2);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullCollection() {
+        Set<Integer> set = Set.copyOf(null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullElements() {
+        Set<Integer> set = Set.copyOf(Arrays.asList(1, null, 3));
+    }
+
+    @Test
+    public void copyOfAcceptsDuplicates() {
+        Set<Integer> set = Set.copyOf(Arrays.asList(1, 1, 2, 3, 3, 3));
+        assertEquals(set, Set.of(1, 2, 3));
+    }
+}
diff --git a/ojluni/src/test/java/util/List/ListFactories.java b/ojluni/src/test/java/util/List/ListFactories.java
new file mode 100644
index 0000000..3aee752
--- /dev/null
+++ b/ojluni/src/test/java/util/List/ListFactories.java
@@ -0,0 +1,373 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.util.List;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.Arrays.asList;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330 8203184
+ * @summary Test convenience static factory methods on List.
+ * @run testng ListFactories
+ */
+@Test
+public class ListFactories {
+
+    static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
+    static final String[] stringArray;
+    static {
+        String[] sa = new String[NUM_STRINGS];
+        for (int i = 0; i < NUM_STRINGS; i++) {
+            sa[i] = String.valueOf((char)('a' + i));
+        }
+        stringArray = sa;
+    }
+
+    // returns array of [actual, expected]
+    static Object[] a(List<String> act, List<String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            a(List.of(), asList())
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    public Iterator<Object[]> nonempty() {
+        return asList(
+            a(List.of("a"),
+               asList("a")),
+            a(List.of("a", "b"),
+               asList("a", "b")),
+            a(List.of("a", "b", "c"),
+               asList("a", "b", "c")),
+            a(List.of("a", "b", "c", "d"),
+               asList("a", "b", "c", "d")),
+            a(List.of("a", "b", "c", "d", "e"),
+               asList("a", "b", "c", "d", "e")),
+            a(List.of("a", "b", "c", "d", "e", "f"),
+               asList("a", "b", "c", "d", "e", "f")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g"),
+               asList("a", "b", "c", "d", "e", "f", "g")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(List.of(stringArray),
+               asList(stringArray))
+        ).iterator();
+    }
+
+    @DataProvider(name="sublists")
+    public Iterator<Object[]> sublists() {
+        return asList(
+            a(List.<String>of().subList(0,0),
+               asList()),
+            a(List.of("a").subList(0,0),
+               asList("a").subList(0,0)),
+            a(List.of("a", "b").subList(0,1),
+               asList("a", "b").subList(0,1)),
+            a(List.of("a", "b", "c").subList(1,3),
+               asList("a", "b", "c").subList(1,3)),
+            a(List.of("a", "b", "c", "d").subList(0,4),
+               asList("a", "b", "c", "d").subList(0,4)),
+            a(List.of("a", "b", "c", "d", "e").subList(0,3),
+               asList("a", "b", "c", "d", "e").subList(0,3)),
+            a(List.of("a", "b", "c", "d", "e", "f").subList(3, 5),
+               asList("a", "b", "c", "d", "e", "f").subList(3, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g").subList(0, 7),
+               asList("a", "b", "c", "d", "e", "f", "g").subList(0, 7)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0),
+               asList("a", "b", "c", "d", "e", "f", "g", "h").subList(0, 0)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i").subList(4, 5)),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j").subList(1,10)),
+            a(List.of(stringArray).subList(5, NUM_STRINGS),
+               asList(Arrays.copyOfRange(stringArray, 5, NUM_STRINGS)))
+                ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        sublists().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @DataProvider(name="nonsublists")
+    public Iterator<Object[]> nonsublists() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddLast(List<String> act, List<String> exp) {
+        act.add("x");
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddFirst(List<String> act, List<String> exp) {
+        act.add(0, "x");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(List<String> act, List<String> exp) {
+        act.remove(0);
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotSet(List<String> act, List<String> exp) {
+        act.set(0, "x");
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(List<String> act, List<String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed1() {
+        List.of((Object)null); // force one-arg overload
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2a() {
+        List.of("a", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2b() {
+        List.of(null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed3() {
+        List.of("a", "b", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed4() {
+        List.of("a", "b", "c", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed5() {
+        List.of("a", "b", "c", "d", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed6() {
+        List.of("a", "b", "c", "d", "e", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed7() {
+        List.of("a", "b", "c", "d", "e", "f", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed8() {
+        List.of("a", "b", "c", "d", "e", "f", "g", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed9() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed10() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = null;
+        List.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        List.of((Object[])null);
+    }
+
+    @Test
+    public void ensureArrayCannotModifyList() {
+        String[] array = stringArray.clone();
+        List<String> list = List.of(array);
+        array[0] = "xyzzy";
+        assertEquals(list, Arrays.asList(stringArray));
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void containsNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.contains(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void indexOfNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.indexOf(null);
+    }
+
+    @Test(dataProvider="all", expectedExceptions=NullPointerException.class)
+    public void lastIndexOfNullShouldThrowNPE(List<String> act, List<String> exp) {
+        act.lastIndexOf(null);
+    }
+
+    // List.of().subList views should not be Serializable
+    @Test(dataProvider="sublists")
+    public void isNotSerializable(List<String> act, List<String> exp) {
+        assertFalse(act instanceof Serializable);
+    }
+
+    // ... but List.of() should be
+    @Test(dataProvider="nonsublists")
+    public void serialEquality(List<String> act, List<String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        List<String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
+                oos.writeObject(obj);
+            }
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    List<Integer> genList() {
+        return new ArrayList<>(Arrays.asList(1, 2, 3));
+    }
+
+    @Test
+    public void copyOfResultsEqual() {
+        List<Integer> orig = genList();
+        List<Integer> copy = List.copyOf(orig);
+
+        assertEquals(orig, copy);
+        assertEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfModifiedUnequal() {
+        List<Integer> orig = genList();
+        List<Integer> copy = List.copyOf(orig);
+        orig.add(4);
+
+        assertNotEquals(orig, copy);
+        assertNotEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfIdentity() {
+        List<Integer> orig = genList();
+        List<Integer> copy1 = List.copyOf(orig);
+        List<Integer> copy2 = List.copyOf(copy1);
+
+        assertNotSame(orig, copy1);
+        assertSame(copy1, copy2);
+    }
+
+    @Test
+    public void copyOfSubList() {
+        List<Integer> orig = List.of(0, 1, 2, 3);
+        List<Integer> sub = orig.subList(0, 3);
+        List<Integer> copy = List.copyOf(sub);
+
+        assertNotSame(sub, copy);
+    }
+
+    @Test
+    public void copyOfSubSubList() {
+        List<Integer> orig = List.of(0, 1, 2, 3);
+        List<Integer> sub = orig.subList(0, 3).subList(0, 2);
+        List<Integer> copy = List.copyOf(sub);
+
+        assertNotSame(sub, copy);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullCollection() {
+        List<Integer> list = List.copyOf(null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullElements() {
+        List<Integer> list = List.copyOf(Arrays.asList(1, null, 3));
+    }
+
+    @Test
+    public void iteratorShouldNotBeListIterator() {
+        List<Integer> list = List.of(1, 2, 3, 4, 5);
+        Iterator<Integer> it = list.iterator();
+        it.next();
+        try {
+            ((ListIterator<Integer>) it).previous();
+            fail("ListIterator operation succeeded on Iterator");
+        } catch (ClassCastException|UnsupportedOperationException ignore) { }
+    }
+}
diff --git a/ojluni/src/test/java/util/Map/MapFactories.java b/ojluni/src/test/java/util/Map/MapFactories.java
new file mode 100644
index 0000000..7fe14e4
--- /dev/null
+++ b/ojluni/src/test/java/util/Map/MapFactories.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2015, 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package test.java.util.Map;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
+import static org.testng.Assert.assertSame;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Map.
+ * @run testng MapFactories
+ */
+
+public class MapFactories {
+
+    Map<Integer, String> genMap() {
+        Map<Integer, String> map = new HashMap<>();
+        map.put(1, "a");
+        map.put(2, "b");
+        map.put(3, "c");
+        return map;
+    }
+
+    @Test
+    public void copyOfResultsEqual() {
+        Map<Integer, String> orig = genMap();
+        Map<Integer, String> copy = Map.copyOf(orig);
+
+        assertEquals(orig, copy);
+        assertEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfModifiedUnequal() {
+        Map<Integer, String> orig = genMap();
+        Map<Integer, String> copy = Map.copyOf(orig);
+        orig.put(4, "d");
+
+        assertNotEquals(orig, copy);
+        assertNotEquals(copy, orig);
+    }
+
+    @Test
+    public void copyOfIdentity() {
+        Map<Integer, String> orig = genMap();
+        Map<Integer, String> copy1 = Map.copyOf(orig);
+        Map<Integer, String> copy2 = Map.copyOf(copy1);
+
+        assertNotSame(orig, copy1);
+        assertSame(copy1, copy2);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullMap() {
+        Map<Integer, String> map = Map.copyOf(null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullKey() {
+        Map<Integer, String> map = genMap();
+        map.put(null, "x");
+        Map<Integer, String> copy = Map.copyOf(map);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void copyOfRejectsNullValue() {
+        Map<Integer, String> map = genMap();
+        map.put(-1, null);
+        Map<Integer, String> copy = Map.copyOf(map);
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractExecutorServiceTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractExecutorServiceTest.java
new file mode 100644
index 0000000..7074509
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractExecutorServiceTest.java
@@ -0,0 +1,636 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.AbstractExecutorService;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AbstractExecutorServiceTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AbstractExecutorServiceTest.class);
+    }
+
+    /**
+     * A no-frills implementation of AbstractExecutorService, designed
+     * to test the submit methods only.
+     */
+    static class DirectExecutorService extends AbstractExecutorService {
+        public void execute(Runnable r) { r.run(); }
+        public void shutdown() { shutdown = true; }
+        public List<Runnable> shutdownNow() {
+            shutdown = true;
+            return Collections.EMPTY_LIST;
+        }
+        public boolean isShutdown() { return shutdown; }
+        public boolean isTerminated() { return isShutdown(); }
+        public boolean awaitTermination(long timeout, TimeUnit unit) {
+            return isShutdown();
+        }
+        private volatile boolean shutdown = false;
+    }
+
+    /**
+     * execute(runnable) runs it to completion
+     */
+    public void testExecuteRunnable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        final AtomicBoolean done = new AtomicBoolean(false);
+        Future<?> future = e.submit(new CheckedRunnable() {
+            public void realRun() {
+                done.set(true);
+            }});
+        assertNull(future.get());
+        assertNull(future.get(0, MILLISECONDS));
+        assertTrue(done.get());
+        assertTrue(future.isDone());
+        assertFalse(future.isCancelled());
+    }
+
+    /**
+     * Completed submit(callable) returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<String> future = e.submit(new StringTask());
+        String result = future.get();
+        assertSame(TEST_STRING, result);
+    }
+
+    /**
+     * Completed submit(runnable) returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<?> future = e.submit(new NoOpRunnable());
+        future.get();
+        assertTrue(future.isDone());
+    }
+
+    /**
+     * Completed submit(runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        ExecutorService e = new DirectExecutorService();
+        Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+        String result = future.get();
+        assertSame(TEST_STRING, result);
+    }
+
+    /**
+     * A submitted privileged action runs to completion
+     */
+    public void testSubmitPrivilegedAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedAction() {
+                    public Object run() {
+                        return TEST_STRING;
+                    }}));
+
+                assertSame(TEST_STRING, future.get());
+            }};
+
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"),
+                           new RuntimePermission("modifyThread"));
+    }
+
+    /**
+     * A submitted privileged exception action runs to completion
+     */
+    public void testSubmitPrivilegedExceptionAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+                    public Object run() {
+                        return TEST_STRING;
+                    }}));
+
+                assertSame(TEST_STRING, future.get());
+            }};
+
+        runWithPermissions(r);
+    }
+
+    /**
+     * A submitted failed privileged exception action reports exception
+     */
+    public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                ExecutorService e = new DirectExecutorService();
+                Future future = e.submit(Executors.callable(new PrivilegedExceptionAction() {
+                    public Object run() throws Exception {
+                        throw new IndexOutOfBoundsException();
+                    }}));
+
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
+                }}};
+
+        runWithPermissions(r);
+    }
+
+    /**
+     * execute(null runnable) throws NPE
+     */
+    public void testExecuteNullRunnable() {
+        ExecutorService e = new DirectExecutorService();
+        try {
+            e.submit((Runnable) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * submit(null callable) throws NPE
+     */
+    public void testSubmitNullCallable() {
+        ExecutorService e = new DirectExecutorService();
+        try {
+            e.submit((Callable) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * submit(callable).get() throws InterruptedException if interrupted
+     */
+    public void testInterruptedSubmit() throws InterruptedException {
+        final CountDownLatch submitted    = new CountDownLatch(1);
+        final CountDownLatch quittingTime = new CountDownLatch(1);
+        final Callable<Void> awaiter = new CheckedCallable<Void>() {
+            public Void realCall() throws InterruptedException {
+                assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
+                return null;
+            }};
+        final ExecutorService p
+            = new ThreadPoolExecutor(1,1,60, TimeUnit.SECONDS,
+                                     new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
+            Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+                public void realRun() throws Exception {
+                    Future<Void> future = p.submit(awaiter);
+                    submitted.countDown();
+                    future.get();
+                }});
+
+            await(submitted);
+            t.interrupt();
+            awaitTermination(t);
+        }
+    }
+
+    /**
+     * get of submit(callable) throws ExecutionException if callable
+     * throws exception
+     */
+    public void testSubmitEE() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            Callable c = new Callable() {
+                public Object call() { throw new ArithmeticException(); }};
+            try {
+                p.submit(c).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof ArithmeticException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<Long>> l = new ArrayList<>();
+            l.add(new Callable<Long>() {
+                      public Long call() { throw new ArithmeticException(); }});
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task in c completes
+     */
+    public void testInvokeAny4() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task in c if at least one completes
+     */
+    public void testInvokeAny5() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of returned element of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks in c
+     */
+    public void testInvokeAll5() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(null time unit) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<Long>> l = new ArrayList<>();
+            l.add(new Callable<Long>() {
+                      public Long call() { throw new ArithmeticException(); }});
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task in c
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(null time unit) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws InterruptedException {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of returned element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks in c
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAll cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        final ExecutorService e = new DirectExecutorService();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            for (long timeout = timeoutMillis();;) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(Executors.callable(possiblyInterruptedRunnable(timeout),
+                                             TEST_STRING));
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    e.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals(TEST_STRING, futures.get(1).get());
+                } catch (CancellationException retryWithLongerTimeout) {
+                    // unusual delay before starting second task
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                    continue;
+                }
+                assertTrue(futures.get(2).isCancelled());
+                break;
+            }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractQueueTest.java
new file mode 100644
index 0000000..c7bb03c
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractQueueTest.java
@@ -0,0 +1,206 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.AbstractQueue;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AbstractQueueTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AbstractQueueTest.class);
+    }
+
+    static class Succeed extends AbstractQueue<Integer> {
+        public boolean offer(Integer x) {
+            if (x == null) throw new NullPointerException();
+            return true;
+        }
+        public Integer peek() { return one; }
+        public Integer poll() { return one; }
+        public int size() { return 0; }
+        public Iterator iterator() { return null; } // not needed
+    }
+
+    static class Fail extends AbstractQueue<Integer> {
+        public boolean offer(Integer x) {
+            if (x == null) throw new NullPointerException();
+            return false;
+        }
+        public Integer peek() { return null; }
+        public Integer poll() { return null; }
+        public int size() { return 0; }
+        public Iterator iterator() { return null; } // not needed
+    }
+
+    /**
+     * add returns true if offer succeeds
+     */
+    public void testAddS() {
+        Succeed q = new Succeed();
+        assertTrue(q.add(two));
+    }
+
+    /**
+     * add throws ISE true if offer fails
+     */
+    public void testAddF() {
+        Fail q = new Fail();
+        try {
+            q.add(one);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * add throws NPE if offer does
+     */
+    public void testAddNPE() {
+        Succeed q = new Succeed();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove returns normally if poll succeeds
+     */
+    public void testRemoveS() {
+        Succeed q = new Succeed();
+        q.remove();
+    }
+
+    /**
+     * remove throws NSEE if poll returns null
+     */
+    public void testRemoveF() {
+        Fail q = new Fail();
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * element returns normally if peek succeeds
+     */
+    public void testElementS() {
+        Succeed q = new Succeed();
+        q.element();
+    }
+
+    /**
+     * element throws NSEE if peek returns null
+     */
+    public void testElementF() {
+        Fail q = new Fail();
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        Succeed q = new Succeed();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        Succeed q = new Succeed();
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        Succeed q = new Succeed();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        Succeed q = new Succeed();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll throws ISE if an add fails
+     */
+    public void testAddAll4() {
+        Fail q = new Fail();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java
new file mode 100644
index 0000000..438ea56
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedLongSynchronizerTest.java
@@ -0,0 +1,1286 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedLongSynchronizer.ConditionObject;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AbstractQueuedLongSynchronizerTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AbstractQueuedLongSynchronizerTest.class);
+    }
+
+    /**
+     * A simple mutex class, adapted from the class javadoc.  Exclusive
+     * acquire tests exercise this as a sample user extension.
+     */
+    static class Mutex extends AbstractQueuedLongSynchronizer {
+        /** An eccentric value > 32 bits for locked synchronizer state. */
+        static final long LOCKED = (1L << 63) | (1L << 15);
+
+        static final long UNLOCKED = 0;
+
+        public boolean isHeldExclusively() {
+            long state = getState();
+            assertTrue(state == UNLOCKED || state == LOCKED);
+            return state == LOCKED;
+        }
+
+        public boolean tryAcquire(long acquires) {
+            assertEquals(LOCKED, acquires);
+            return compareAndSetState(UNLOCKED, LOCKED);
+        }
+
+        public boolean tryRelease(long releases) {
+            if (getState() != LOCKED) throw new IllegalMonitorStateException();
+            setState(UNLOCKED);
+            return true;
+        }
+
+        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
+            return tryAcquireNanos(LOCKED, nanos);
+        }
+
+        public boolean tryAcquire() {
+            return tryAcquire(LOCKED);
+        }
+
+        public boolean tryRelease() {
+            return tryRelease(LOCKED);
+        }
+
+        public void acquire() {
+            acquire(LOCKED);
+        }
+
+        public void acquireInterruptibly() throws InterruptedException {
+            acquireInterruptibly(LOCKED);
+        }
+
+        public void release() {
+            release(LOCKED);
+        }
+
+        public ConditionObject newCondition() {
+            return new ConditionObject();
+        }
+    }
+
+    /**
+     * A simple latch class, to test shared mode.
+     */
+    static class BooleanLatch extends AbstractQueuedLongSynchronizer {
+        public boolean isSignalled() { return getState() != 0; }
+
+        public long tryAcquireShared(long ignore) {
+            return isSignalled() ? 1 : -1;
+        }
+
+        public boolean tryReleaseShared(long ignore) {
+            setState(1L << 62);
+            return true;
+        }
+    }
+
+    /**
+     * A runnable calling acquireInterruptibly that does not expect to
+     * be interrupted.
+     */
+    class InterruptibleSyncRunnable extends CheckedRunnable {
+        final Mutex sync;
+        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly();
+        }
+    }
+
+    /**
+     * A runnable calling acquireInterruptibly that expects to be
+     * interrupted.
+     */
+    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
+        final Mutex sync;
+        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly();
+        }
+    }
+
+    /** A constant to clarify calls to checking methods below. */
+    static final Thread[] NO_THREADS = new Thread[0];
+
+    /**
+     * Spin-waits until sync.isQueued(t) becomes true.
+     */
+    void waitForQueuedThread(AbstractQueuedLongSynchronizer sync,
+                             Thread t) {
+        long startTime = System.nanoTime();
+        while (!sync.isQueued(t)) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+        assertTrue(t.isAlive());
+    }
+
+    /**
+     * Checks that sync has exactly the given queued threads.
+     */
+    void assertHasQueuedThreads(AbstractQueuedLongSynchronizer sync,
+                                Thread... expected) {
+        Collection<Thread> actual = sync.getQueuedThreads();
+        assertEquals(expected.length > 0, sync.hasQueuedThreads());
+        assertEquals(expected.length, sync.getQueueLength());
+        assertEquals(expected.length, actual.size());
+        assertEquals(expected.length == 0, actual.isEmpty());
+        assertEquals(new HashSet<Thread>(actual),
+                     new HashSet<Thread>(Arrays.asList(expected)));
+        // Android-added: Since we check queued threads, also check queued predecessors
+        final boolean expectedQueuedPredecessors =
+            sync.getFirstQueuedThread() != Thread.currentThread() &&
+            sync.hasQueuedThreads();
+        assertEquals(expectedQueuedPredecessors, sync.hasQueuedPredecessors());
+    }
+
+    /**
+     * Checks that sync has exactly the given (exclusive) queued threads.
+     */
+    void assertHasExclusiveQueuedThreads(AbstractQueuedLongSynchronizer sync,
+                                         Thread... expected) {
+        assertHasQueuedThreads(sync, expected);
+        assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
+                     new HashSet<Thread>(sync.getQueuedThreads()));
+        assertEquals(0, sync.getSharedQueuedThreads().size());
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+    }
+
+    /**
+     * Checks that sync has exactly the given (shared) queued threads.
+     */
+    void assertHasSharedQueuedThreads(AbstractQueuedLongSynchronizer sync,
+                                      Thread... expected) {
+        assertHasQueuedThreads(sync, expected);
+        assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
+                     new HashSet<Thread>(sync.getQueuedThreads()));
+        assertEquals(0, sync.getExclusiveQueuedThreads().size());
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads,
+     * after acquiring mutex.
+     */
+    void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
+                                 Thread... threads) {
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, threads);
+        sync.release();
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads.
+     */
+    void assertHasWaitersLocked(Mutex sync, ConditionObject c,
+                                Thread... threads) {
+        assertEquals(threads.length > 0, sync.hasWaiters(c));
+        assertEquals(threads.length, sync.getWaitQueueLength(c));
+        assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
+        assertEquals(threads.length, sync.getWaitingThreads(c).size());
+        assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
+                     new HashSet<Thread>(Arrays.asList(threads)));
+    }
+
+    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
+
+    /**
+     * Awaits condition using the specified AwaitMethod.
+     */
+    void await(ConditionObject c, AwaitMethod awaitMethod)
+            throws InterruptedException {
+        long timeoutMillis = 2 * LONG_DELAY_MS;
+        switch (awaitMethod) {
+        case await:
+            c.await();
+            break;
+        case awaitTimed:
+            assertTrue(c.await(timeoutMillis, MILLISECONDS));
+            break;
+        case awaitNanos:
+            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(nanosTimeout);
+            assertTrue(nanosRemaining > 0);
+            break;
+        case awaitUntil:
+            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+            break;
+        default:
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Checks that awaiting the given condition times out (using the
+     * default timeout duration).
+     */
+    void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
+        final long timeoutMillis = timeoutMillis();
+        final long startTime;
+        try {
+            switch (awaitMethod) {
+            case awaitTimed:
+                startTime = System.nanoTime();
+                assertFalse(c.await(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+                break;
+            case awaitNanos:
+                startTime = System.nanoTime();
+                long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+                long nanosRemaining = c.awaitNanos(nanosTimeout);
+                assertTrue(nanosRemaining <= 0);
+                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+                break;
+            case awaitUntil:
+                // We shouldn't assume that nanoTime and currentTimeMillis
+                // use the same time source, so don't use nanoTime here.
+                java.util.Date delayedDate = delayedDate(timeoutMillis);
+                assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
+                break;
+            default:
+                throw new UnsupportedOperationException();
+            }
+        } catch (InterruptedException ie) { threadUnexpectedException(ie); }
+    }
+
+    /**
+     * isHeldExclusively is false upon construction
+     */
+    public void testIsHeldExclusively() {
+        Mutex sync = new Mutex();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * acquiring released sync succeeds
+     */
+    public void testAcquire() {
+        Mutex sync = new Mutex();
+        sync.acquire();
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * tryAcquire on a released sync succeeds
+     */
+    public void testTryAcquire() {
+        Mutex sync = new Mutex();
+        assertTrue(sync.tryAcquire());
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testHasQueuedThreads() {
+        final Mutex sync = new Mutex();
+        assertFalse(sync.hasQueuedThreads());
+        sync.acquire();
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.hasQueuedThreads());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.hasQueuedThreads());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.hasQueuedThreads());
+        sync.release();
+        awaitTermination(t2);
+        assertFalse(sync.hasQueuedThreads());
+    }
+
+    /**
+     * isQueued(null) throws NullPointerException
+     */
+    public void testIsQueuedNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.isQueued(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * isQueued reports whether a thread is queued
+     */
+    public void testIsQueued() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        sync.acquire();
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        sync.release();
+        awaitTermination(t2);
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+    }
+
+    /**
+     * getFirstQueuedThread returns first waiting thread or null if none
+     */
+    public void testGetFirstQueuedThread() {
+        final Mutex sync = new Mutex();
+        assertNull(sync.getFirstQueuedThread());
+        sync.acquire();
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertEquals(t2, sync.getFirstQueuedThread());
+        sync.release();
+        awaitTermination(t2);
+        assertNull(sync.getFirstQueuedThread());
+    }
+
+    /**
+     * hasContended reports false if no thread has ever blocked, else true
+     */
+    public void testHasContended() {
+        final Mutex sync = new Mutex();
+        assertFalse(sync.hasContended());
+        sync.acquire();
+        assertFalse(sync.hasContended());
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.hasContended());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.hasContended());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.hasContended());
+        sync.release();
+        awaitTermination(t2);
+        assertTrue(sync.hasContended());
+    }
+
+    /**
+     * getQueuedThreads returns all waiting threads
+     */
+    public void testGetQueuedThreads() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        sync.acquire();
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertHasExclusiveQueuedThreads(sync, t1);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertFalse(sync.getQueuedThreads().contains(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasExclusiveQueuedThreads(sync, t2);
+        sync.release();
+        awaitTermination(t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+    }
+
+    /**
+     * getExclusiveQueuedThreads returns all exclusive waiting threads
+     */
+    public void testGetExclusiveQueuedThreads() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        sync.acquire();
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertHasExclusiveQueuedThreads(sync, t1);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasExclusiveQueuedThreads(sync, t2);
+        sync.release();
+        awaitTermination(t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+    }
+
+    /**
+     * getSharedQueuedThreads does not include exclusively waiting threads
+     */
+    public void testGetSharedQueuedThreads_Exclusive() {
+        final Mutex sync = new Mutex();
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.acquire();
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.release();
+        awaitTermination(t2);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+    }
+
+    /**
+     * getSharedQueuedThreads returns all shared waiting threads
+     */
+    public void testGetSharedQueuedThreads_Shared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertHasSharedQueuedThreads(l, NO_THREADS);
+        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                l.acquireSharedInterruptibly(0);
+            }});
+        waitForQueuedThread(l, t1);
+        assertHasSharedQueuedThreads(l, t1);
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                l.acquireSharedInterruptibly(0);
+            }});
+        waitForQueuedThread(l, t2);
+        assertHasSharedQueuedThreads(l, t1, t2);
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasSharedQueuedThreads(l, t2);
+        assertTrue(l.releaseShared(0));
+        awaitTermination(t2);
+        assertHasSharedQueuedThreads(l, NO_THREADS);
+    }
+
+    /**
+     * tryAcquireNanos is interruptible
+     */
+    public void testTryAcquireNanos_Interruptible() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
+            }});
+
+        waitForQueuedThread(sync, t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * tryAcquire on exclusively held sync fails
+     */
+    public void testTryAcquireWhenSynced() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(sync.tryAcquire());
+            }});
+
+        awaitTermination(t);
+        sync.release();
+    }
+
+    /**
+     * tryAcquireNanos on an exclusively held sync times out
+     */
+    public void testAcquireNanos_Timeout() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                long nanos = MILLISECONDS.toNanos(timeoutMillis());
+                assertFalse(sync.tryAcquireNanos(nanos));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t);
+        sync.release();
+    }
+
+    /**
+     * getState is true when acquired and false when not
+     */
+    public void testGetState() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+
+        final BooleanLatch acquired = new BooleanLatch();
+        final BooleanLatch done = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(acquired.releaseShared(0));
+                done.acquireShared(0);
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        assertTrue(sync.isHeldExclusively());
+        assertTrue(done.releaseShared(0));
+        awaitTermination(t);
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * acquireInterruptibly succeeds when released, else is interruptible
+     */
+    public void testAcquireInterruptibly() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final BooleanLatch threadStarted = new BooleanLatch();
+        sync.acquireInterruptibly();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertTrue(threadStarted.releaseShared(0));
+                sync.acquireInterruptibly();
+            }});
+
+        threadStarted.acquireShared(0);
+        waitForQueuedThread(sync, t);
+        t.interrupt();
+        awaitTermination(t);
+        assertTrue(sync.isHeldExclusively());
+    }
+
+    /**
+     * owns is true for a condition created by sync else false
+     */
+    public void testOwns() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        assertTrue(sync.owns(c));
+        assertFalse(sync2.owns(c));
+    }
+
+    /**
+     * Calling await without holding sync throws IllegalMonitorStateException
+     */
+    public void testAwait_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+            long startTime = System.nanoTime();
+            try {
+                await(c, awaitMethod);
+                shouldThrow();
+            } catch (IllegalMonitorStateException success) {
+            } catch (InterruptedException e) { threadUnexpectedException(e); }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * Calling signal without holding sync throws IllegalMonitorStateException
+     */
+    public void testSignal_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            c.signal();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * Calling signalAll without holding sync throws IllegalMonitorStateException
+     */
+    public void testSignalAll_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            c.signalAll();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil without a signal times out
+     */
+    public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
+    public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
+    public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
+    public void testAwait_Timeout(AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertAwaitTimesOut(c, awaitMethod);
+        sync.release();
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil returns when signalled
+     */
+    public void testSignal_await()      { testSignal(AwaitMethod.await); }
+    public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
+    public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
+    public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
+    public void testSignal(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(acquired.releaseShared(0));
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        sync.release();
+        awaitTermination(t);
+    }
+
+    /**
+     * hasWaiters(null) throws NullPointerException
+     */
+    public void testHasWaitersNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.hasWaiters(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitQueueLength(null) throws NullPointerException
+     */
+    public void testGetWaitQueueLengthNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitQueueLength(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws NPE if null
+     */
+    public void testGetWaitingThreadsNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitingThreads(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalArgumentException if not owned
+     */
+    public void testHasWaitersIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * hasWaiters throws IllegalMonitorStateException if not synced
+     */
+    public void testHasWaitersIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitQueueLengthIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalMonitorStateException if not synced
+     */
+    public void testGetWaitQueueLengthIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitingThreadsIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads throws IllegalMonitorStateException if not synced
+     */
+    public void testGetWaitingThreadsIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * hasWaiters returns true when a thread is waiting, else false
+     */
+    public void testHasWaiters() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertFalse(sync.hasWaiters(c));
+                assertTrue(acquired.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertTrue(sync.hasWaiters(c));
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        assertFalse(sync.hasWaiters(c));
+        sync.release();
+
+        awaitTermination(t);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength returns number of waiting threads
+     */
+    public void testGetWaitQueueLength() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        final Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertEquals(0, sync.getWaitQueueLength(c));
+                assertTrue(acquired1.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+        acquired1.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1);
+        assertEquals(1, sync.getWaitQueueLength(c));
+        sync.release();
+
+        final Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, t1);
+                assertEquals(1, sync.getWaitQueueLength(c));
+                assertTrue(acquired2.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertEquals(2, sync.getWaitQueueLength(c));
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads returns only and all waiting threads
+     */
+    public void testGetWaitingThreads() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        final Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertTrue(sync.getWaitingThreads(c).isEmpty());
+                assertTrue(acquired1.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        final Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, t1);
+                assertTrue(sync.getWaitingThreads(c).contains(t1));
+                assertFalse(sync.getWaitingThreads(c).isEmpty());
+                assertEquals(1, sync.getWaitingThreads(c).size());
+                assertTrue(acquired2.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertFalse(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(0, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        t1.start();
+        acquired1.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1);
+        assertTrue(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertFalse(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(1, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        t2.start();
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertTrue(sync.getWaitingThreads(c).contains(t1));
+        assertTrue(sync.getWaitingThreads(c).contains(t2));
+        assertFalse(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(2, sync.getWaitingThreads(c).size());
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertFalse(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(0, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * awaitUninterruptibly is uninterruptible
+     */
+    public void testAwaitUninterruptibly() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch pleaseInterrupt = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                sync.acquire();
+                assertTrue(pleaseInterrupt.releaseShared(0));
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                sync.release();
+            }});
+
+        pleaseInterrupt.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        sync.release();
+        t.interrupt();
+        assertHasWaitersUnlocked(sync, c, t);
+        assertThreadStaysAlive(t);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        sync.release();
+        awaitTermination(t);
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil is interruptible
+     */
+    public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
+    public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
+    public void testInterruptible(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch pleaseInterrupt = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(pleaseInterrupt.releaseShared(0));
+                await(c, awaitMethod);
+            }});
+
+        pleaseInterrupt.acquireShared(0);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * signalAll wakes up all threads
+     */
+    public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
+    public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
+    public void testSignalAll(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                acquired1.releaseShared(0);
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                acquired2.releaseShared(0);
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        acquired1.acquireShared(0);
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        sync.release();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * toString indicates current state
+     */
+    public void testToString() {
+        Mutex sync = new Mutex();
+        assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
+        sync.acquire();
+        assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
+    }
+
+    /**
+     * A serialized AQS deserializes with current state, but no queued threads
+     */
+    public void testSerialization() {
+        Mutex sync = new Mutex();
+        assertFalse(serialClone(sync).isHeldExclusively());
+        sync.acquire();
+        Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t);
+        assertTrue(sync.isHeldExclusively());
+
+        Mutex clone = serialClone(sync);
+        assertTrue(clone.isHeldExclusively());
+        assertHasExclusiveQueuedThreads(sync, t);
+        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+        t.interrupt();
+        awaitTermination(t);
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+        assertTrue(clone.isHeldExclusively());
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+    }
+
+    /**
+     * tryReleaseShared setting state changes getState
+     */
+    public void testGetStateWithReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * releaseShared has no effect when already signalled
+     */
+    public void testReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * acquireSharedInterruptibly returns after release, but not before
+     */
+    public void testAcquireSharedInterruptibly() {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                assertTrue(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                assertTrue(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        assertThreadStaysAlive(t);
+        assertHasSharedQueuedThreads(l, t);
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        awaitTermination(t);
+    }
+
+    /**
+     * tryAcquireSharedNanos returns after release, but not before
+     */
+    public void testTryAcquireSharedNanos() {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        assertThreadStaysAlive(t);
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        awaitTermination(t);
+    }
+
+    /**
+     * acquireSharedInterruptibly is interruptible
+     */
+    public void testAcquireSharedInterruptibly_Interruptible() {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * tryAcquireSharedNanos is interruptible
+     */
+    public void testTryAcquireSharedNanos_Interruptible() {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+                l.tryAcquireSharedNanos(0, nanos);
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * tryAcquireSharedNanos times out if not released before timeout
+     */
+    public void testTryAcquireSharedNanos_Timeout() {
+        final BooleanLatch l = new BooleanLatch();
+        final BooleanLatch observedQueued = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                for (long millis = timeoutMillis();
+                     !observedQueued.isSignalled();
+                     millis *= 2) {
+                    long nanos = MILLISECONDS.toNanos(millis);
+                    long startTime = System.nanoTime();
+                    assertFalse(l.tryAcquireSharedNanos(0, nanos));
+                    assertTrue(millisElapsedSince(startTime) >= millis);
+                }
+                assertFalse(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        observedQueued.releaseShared(0);
+        assertFalse(l.isSignalled());
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * awaitNanos/timed await with 0 wait times out immediately
+     */
+    public void testAwait_Zero() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertTrue(c.awaitNanos(0L) <= 0);
+        assertFalse(c.await(0L, NANOSECONDS));
+        sync.release();
+    }
+
+    /**
+     * awaitNanos/timed await with maximum negative wait times does not underflow
+     */
+    public void testAwait_NegativeInfinity() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
+        assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
+        sync.release();
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java
new file mode 100644
index 0000000..a1f36ba
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AbstractQueuedSynchronizerTest.java
@@ -0,0 +1,1289 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer;
+import java.util.concurrent.locks.AbstractQueuedSynchronizer.ConditionObject;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AbstractQueuedSynchronizerTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AbstractQueuedSynchronizerTest.class);
+    }
+
+    /**
+     * A simple mutex class, adapted from the class javadoc.  Exclusive
+     * acquire tests exercise this as a sample user extension.  Other
+     * methods/features of AbstractQueuedSynchronizer are tested via
+     * other test classes, including those for ReentrantLock,
+     * ReentrantReadWriteLock, and Semaphore.
+     */
+    static class Mutex extends AbstractQueuedSynchronizer {
+        /** An eccentric value for locked synchronizer state. */
+        static final int LOCKED = (1 << 31) | (1 << 15);
+
+        static final int UNLOCKED = 0;
+
+        @Override public boolean isHeldExclusively() {
+            int state = getState();
+            assertTrue(state == UNLOCKED || state == LOCKED);
+            return state == LOCKED;
+        }
+
+        @Override public boolean tryAcquire(int acquires) {
+            assertEquals(LOCKED, acquires);
+            return compareAndSetState(UNLOCKED, LOCKED);
+        }
+
+        @Override public boolean tryRelease(int releases) {
+            if (getState() != LOCKED) throw new IllegalMonitorStateException();
+            assertEquals(LOCKED, releases);
+            setState(UNLOCKED);
+            return true;
+        }
+
+        public boolean tryAcquireNanos(long nanos) throws InterruptedException {
+            return tryAcquireNanos(LOCKED, nanos);
+        }
+
+        public boolean tryAcquire() {
+            return tryAcquire(LOCKED);
+        }
+
+        public boolean tryRelease() {
+            return tryRelease(LOCKED);
+        }
+
+        public void acquire() {
+            acquire(LOCKED);
+        }
+
+        public void acquireInterruptibly() throws InterruptedException {
+            acquireInterruptibly(LOCKED);
+        }
+
+        public void release() {
+            release(LOCKED);
+        }
+
+        public ConditionObject newCondition() {
+            return new ConditionObject();
+        }
+    }
+
+    /**
+     * A simple latch class, to test shared mode.
+     */
+    static class BooleanLatch extends AbstractQueuedSynchronizer {
+        public boolean isSignalled() { return getState() != 0; }
+
+        public int tryAcquireShared(int ignore) {
+            return isSignalled() ? 1 : -1;
+        }
+
+        public boolean tryReleaseShared(int ignore) {
+            setState(1);
+            return true;
+        }
+    }
+
+    /**
+     * A runnable calling acquireInterruptibly that does not expect to
+     * be interrupted.
+     */
+    class InterruptibleSyncRunnable extends CheckedRunnable {
+        final Mutex sync;
+        InterruptibleSyncRunnable(Mutex sync) { this.sync = sync; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly();
+        }
+    }
+
+    /**
+     * A runnable calling acquireInterruptibly that expects to be
+     * interrupted.
+     */
+    class InterruptedSyncRunnable extends CheckedInterruptedRunnable {
+        final Mutex sync;
+        InterruptedSyncRunnable(Mutex sync) { this.sync = sync; }
+        public void realRun() throws InterruptedException {
+            sync.acquireInterruptibly();
+        }
+    }
+
+    /** A constant to clarify calls to checking methods below. */
+    static final Thread[] NO_THREADS = new Thread[0];
+
+    /**
+     * Spin-waits until sync.isQueued(t) becomes true.
+     */
+    void waitForQueuedThread(AbstractQueuedSynchronizer sync, Thread t) {
+        long startTime = System.nanoTime();
+        while (!sync.isQueued(t)) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+        assertTrue(t.isAlive());
+    }
+
+    /**
+     * Checks that sync has exactly the given queued threads.
+     */
+    void assertHasQueuedThreads(AbstractQueuedSynchronizer sync,
+                                Thread... expected) {
+        Collection<Thread> actual = sync.getQueuedThreads();
+        assertEquals(expected.length > 0, sync.hasQueuedThreads());
+        assertEquals(expected.length, sync.getQueueLength());
+        assertEquals(expected.length, actual.size());
+        assertEquals(expected.length == 0, actual.isEmpty());
+        assertEquals(new HashSet<Thread>(actual),
+                     new HashSet<Thread>(Arrays.asList(expected)));
+        // Android-added: Since we check queued threads, also check queued predecessors
+        final boolean expectedQueuedPredecessors =
+            sync.getFirstQueuedThread() != Thread.currentThread() &&
+            sync.hasQueuedThreads();
+        assertEquals(expectedQueuedPredecessors, sync.hasQueuedPredecessors());
+    }
+
+    /**
+     * Checks that sync has exactly the given (exclusive) queued threads.
+     */
+    void assertHasExclusiveQueuedThreads(AbstractQueuedSynchronizer sync,
+                                         Thread... expected) {
+        assertHasQueuedThreads(sync, expected);
+        assertEquals(new HashSet<Thread>(sync.getExclusiveQueuedThreads()),
+                     new HashSet<Thread>(sync.getQueuedThreads()));
+        assertEquals(0, sync.getSharedQueuedThreads().size());
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+    }
+
+    /**
+     * Checks that sync has exactly the given (shared) queued threads.
+     */
+    void assertHasSharedQueuedThreads(AbstractQueuedSynchronizer sync,
+                                      Thread... expected) {
+        assertHasQueuedThreads(sync, expected);
+        assertEquals(new HashSet<Thread>(sync.getSharedQueuedThreads()),
+                     new HashSet<Thread>(sync.getQueuedThreads()));
+        assertEquals(0, sync.getExclusiveQueuedThreads().size());
+        assertTrue(sync.getExclusiveQueuedThreads().isEmpty());
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads,
+     * after acquiring mutex.
+     */
+    void assertHasWaitersUnlocked(Mutex sync, ConditionObject c,
+                                 Thread... threads) {
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, threads);
+        sync.release();
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads.
+     */
+    void assertHasWaitersLocked(Mutex sync, ConditionObject c,
+                                Thread... threads) {
+        assertEquals(threads.length > 0, sync.hasWaiters(c));
+        assertEquals(threads.length, sync.getWaitQueueLength(c));
+        assertEquals(threads.length == 0, sync.getWaitingThreads(c).isEmpty());
+        assertEquals(threads.length, sync.getWaitingThreads(c).size());
+        assertEquals(new HashSet<Thread>(sync.getWaitingThreads(c)),
+                     new HashSet<Thread>(Arrays.asList(threads)));
+    }
+
+    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
+
+    /**
+     * Awaits condition using the specified AwaitMethod.
+     */
+    void await(ConditionObject c, AwaitMethod awaitMethod)
+            throws InterruptedException {
+        long timeoutMillis = 2 * LONG_DELAY_MS;
+        switch (awaitMethod) {
+        case await:
+            c.await();
+            break;
+        case awaitTimed:
+            assertTrue(c.await(timeoutMillis, MILLISECONDS));
+            break;
+        case awaitNanos:
+            long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(nanosTimeout);
+            assertTrue(nanosRemaining > 0);
+            break;
+        case awaitUntil:
+            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+            break;
+        default:
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Checks that awaiting the given condition times out (using the
+     * default timeout duration).
+     */
+    void assertAwaitTimesOut(ConditionObject c, AwaitMethod awaitMethod) {
+        final long timeoutMillis = timeoutMillis();
+        final long startTime;
+        try {
+            switch (awaitMethod) {
+            case awaitTimed:
+                startTime = System.nanoTime();
+                assertFalse(c.await(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+                break;
+            case awaitNanos:
+                startTime = System.nanoTime();
+                long nanosTimeout = MILLISECONDS.toNanos(timeoutMillis);
+                long nanosRemaining = c.awaitNanos(nanosTimeout);
+                assertTrue(nanosRemaining <= 0);
+                assertTrue(nanosRemaining > -MILLISECONDS.toNanos(LONG_DELAY_MS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+                break;
+            case awaitUntil:
+                // We shouldn't assume that nanoTime and currentTimeMillis
+                // use the same time source, so don't use nanoTime here.
+                java.util.Date delayedDate = delayedDate(timeoutMillis);
+                assertFalse(c.awaitUntil(delayedDate(timeoutMillis)));
+                assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
+                break;
+            default:
+                throw new UnsupportedOperationException();
+            }
+        } catch (InterruptedException ie) { threadUnexpectedException(ie); }
+    }
+
+    /**
+     * isHeldExclusively is false upon construction
+     */
+    public void testIsHeldExclusively() {
+        Mutex sync = new Mutex();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * acquiring released sync succeeds
+     */
+    public void testAcquire() {
+        Mutex sync = new Mutex();
+        sync.acquire();
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * tryAcquire on a released sync succeeds
+     */
+    public void testTryAcquire() {
+        Mutex sync = new Mutex();
+        assertTrue(sync.tryAcquire());
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testHasQueuedThreads() {
+        final Mutex sync = new Mutex();
+        assertFalse(sync.hasQueuedThreads());
+        sync.acquire();
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.hasQueuedThreads());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.hasQueuedThreads());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.hasQueuedThreads());
+        sync.release();
+        awaitTermination(t2);
+        assertFalse(sync.hasQueuedThreads());
+    }
+
+    /**
+     * isQueued(null) throws NullPointerException
+     */
+    public void testIsQueuedNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.isQueued(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * isQueued reports whether a thread is queued
+     */
+    public void testIsQueued() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        sync.acquire();
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(sync.isQueued(t1));
+        assertTrue(sync.isQueued(t2));
+        sync.release();
+        awaitTermination(t2);
+        assertFalse(sync.isQueued(t1));
+        assertFalse(sync.isQueued(t2));
+    }
+
+    /**
+     * getFirstQueuedThread returns first waiting thread or null if none
+     */
+    public void testGetFirstQueuedThread() {
+        final Mutex sync = new Mutex();
+        assertNull(sync.getFirstQueuedThread());
+        sync.acquire();
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertEquals(t1, sync.getFirstQueuedThread());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertEquals(t2, sync.getFirstQueuedThread());
+        sync.release();
+        awaitTermination(t2);
+        assertNull(sync.getFirstQueuedThread());
+    }
+
+    /**
+     * hasContended reports false if no thread has ever blocked, else true
+     */
+    public void testHasContended() {
+        final Mutex sync = new Mutex();
+        assertFalse(sync.hasContended());
+        sync.acquire();
+        assertFalse(sync.hasContended());
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.hasContended());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.hasContended());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.hasContended());
+        sync.release();
+        awaitTermination(t2);
+        assertTrue(sync.hasContended());
+    }
+
+    /**
+     * getQueuedThreads returns all waiting threads
+     */
+    public void testGetQueuedThreads() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        sync.acquire();
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertHasExclusiveQueuedThreads(sync, t1);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertFalse(sync.getQueuedThreads().contains(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertTrue(sync.getQueuedThreads().contains(t1));
+        assertTrue(sync.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasExclusiveQueuedThreads(sync, t2);
+        sync.release();
+        awaitTermination(t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+    }
+
+    /**
+     * getExclusiveQueuedThreads returns all exclusive waiting threads
+     */
+    public void testGetExclusiveQueuedThreads() {
+        final Mutex sync = new Mutex();
+        Thread t1 = new Thread(new InterruptedSyncRunnable(sync));
+        Thread t2 = new Thread(new InterruptibleSyncRunnable(sync));
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        sync.acquire();
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        t1.start();
+        waitForQueuedThread(sync, t1);
+        assertHasExclusiveQueuedThreads(sync, t1);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertFalse(sync.getExclusiveQueuedThreads().contains(t2));
+        t2.start();
+        waitForQueuedThread(sync, t2);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t1));
+        assertTrue(sync.getExclusiveQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasExclusiveQueuedThreads(sync, t2);
+        sync.release();
+        awaitTermination(t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+    }
+
+    /**
+     * getSharedQueuedThreads does not include exclusively waiting threads
+     */
+    public void testGetSharedQueuedThreads_Exclusive() {
+        final Mutex sync = new Mutex();
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.acquire();
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        Thread t1 = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        Thread t2 = newStartedThread(new InterruptibleSyncRunnable(sync));
+        waitForQueuedThread(sync, t2);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+        sync.release();
+        awaitTermination(t2);
+        assertTrue(sync.getSharedQueuedThreads().isEmpty());
+    }
+
+    /**
+     * getSharedQueuedThreads returns all shared waiting threads
+     */
+    public void testGetSharedQueuedThreads_Shared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertHasSharedQueuedThreads(l, NO_THREADS);
+        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                l.acquireSharedInterruptibly(0);
+            }});
+        waitForQueuedThread(l, t1);
+        assertHasSharedQueuedThreads(l, t1);
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                l.acquireSharedInterruptibly(0);
+            }});
+        waitForQueuedThread(l, t2);
+        assertHasSharedQueuedThreads(l, t1, t2);
+        t1.interrupt();
+        awaitTermination(t1);
+        assertHasSharedQueuedThreads(l, t2);
+        assertTrue(l.releaseShared(0));
+        awaitTermination(t2);
+        assertHasSharedQueuedThreads(l, NO_THREADS);
+    }
+
+    /**
+     * tryAcquireNanos is interruptible
+     */
+    public void testTryAcquireNanos_Interruptible() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.tryAcquireNanos(MILLISECONDS.toNanos(2 * LONG_DELAY_MS));
+            }});
+
+        waitForQueuedThread(sync, t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * tryAcquire on exclusively held sync fails
+     */
+    public void testTryAcquireWhenSynced() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(sync.tryAcquire());
+            }});
+
+        awaitTermination(t);
+        sync.release();
+    }
+
+    /**
+     * tryAcquireNanos on an exclusively held sync times out
+     */
+    public void testAcquireNanos_Timeout() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                long nanos = MILLISECONDS.toNanos(timeoutMillis());
+                assertFalse(sync.tryAcquireNanos(nanos));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t);
+        sync.release();
+    }
+
+    /**
+     * getState is true when acquired and false when not
+     */
+    public void testGetState() {
+        final Mutex sync = new Mutex();
+        sync.acquire();
+        assertTrue(sync.isHeldExclusively());
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+
+        final BooleanLatch acquired = new BooleanLatch();
+        final BooleanLatch done = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(acquired.releaseShared(0));
+                done.acquireShared(0);
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        assertTrue(sync.isHeldExclusively());
+        assertTrue(done.releaseShared(0));
+        awaitTermination(t);
+        assertFalse(sync.isHeldExclusively());
+    }
+
+    /**
+     * acquireInterruptibly succeeds when released, else is interruptible
+     */
+    public void testAcquireInterruptibly() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final BooleanLatch threadStarted = new BooleanLatch();
+        sync.acquireInterruptibly();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertTrue(threadStarted.releaseShared(0));
+                sync.acquireInterruptibly();
+            }});
+
+        threadStarted.acquireShared(0);
+        waitForQueuedThread(sync, t);
+        t.interrupt();
+        awaitTermination(t);
+        assertTrue(sync.isHeldExclusively());
+    }
+
+    /**
+     * owns is true for a condition created by sync else false
+     */
+    public void testOwns() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        assertTrue(sync.owns(c));
+        assertFalse(sync2.owns(c));
+    }
+
+    /**
+     * Calling await without holding sync throws IllegalMonitorStateException
+     */
+    public void testAwait_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+            long startTime = System.nanoTime();
+            try {
+                await(c, awaitMethod);
+                shouldThrow();
+            } catch (IllegalMonitorStateException success) {
+            } catch (InterruptedException e) { threadUnexpectedException(e); }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * Calling signal without holding sync throws IllegalMonitorStateException
+     */
+    public void testSignal_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            c.signal();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * Calling signalAll without holding sync throws IllegalMonitorStateException
+     */
+    public void testSignalAll_IMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            c.signalAll();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil without a signal times out
+     */
+    public void testAwaitTimed_Timeout() { testAwait_Timeout(AwaitMethod.awaitTimed); }
+    public void testAwaitNanos_Timeout() { testAwait_Timeout(AwaitMethod.awaitNanos); }
+    public void testAwaitUntil_Timeout() { testAwait_Timeout(AwaitMethod.awaitUntil); }
+    public void testAwait_Timeout(AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertAwaitTimesOut(c, awaitMethod);
+        sync.release();
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil returns when signalled
+     */
+    public void testSignal_await()      { testSignal(AwaitMethod.await); }
+    public void testSignal_awaitTimed() { testSignal(AwaitMethod.awaitTimed); }
+    public void testSignal_awaitNanos() { testSignal(AwaitMethod.awaitNanos); }
+    public void testSignal_awaitUntil() { testSignal(AwaitMethod.awaitUntil); }
+    public void testSignal(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(acquired.releaseShared(0));
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        sync.release();
+        awaitTermination(t);
+    }
+
+    /**
+     * hasWaiters(null) throws NullPointerException
+     */
+    public void testHasWaitersNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.hasWaiters(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitQueueLength(null) throws NullPointerException
+     */
+    public void testGetWaitQueueLengthNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitQueueLength(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitingThreads(null) throws NullPointerException
+     */
+    public void testGetWaitingThreadsNPE() {
+        final Mutex sync = new Mutex();
+        try {
+            sync.getWaitingThreads(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalArgumentException if not owned
+     */
+    public void testHasWaitersIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * hasWaiters throws IllegalMonitorStateException if not synced
+     */
+    public void testHasWaitersIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitQueueLengthIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalMonitorStateException if not synced
+     */
+    public void testGetWaitQueueLengthIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitingThreadsIAE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final Mutex sync2 = new Mutex();
+        try {
+            sync2.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads throws IllegalMonitorStateException if not synced
+     */
+    public void testGetWaitingThreadsIMSE() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        try {
+            sync.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * hasWaiters returns true when a thread is waiting, else false
+     */
+    public void testHasWaiters() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertFalse(sync.hasWaiters(c));
+                assertTrue(acquired.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        acquired.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertTrue(sync.hasWaiters(c));
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        assertFalse(sync.hasWaiters(c));
+        sync.release();
+
+        awaitTermination(t);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitQueueLength returns number of waiting threads
+     */
+    public void testGetWaitQueueLength() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        final Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertEquals(0, sync.getWaitQueueLength(c));
+                assertTrue(acquired1.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+        acquired1.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1);
+        assertEquals(1, sync.getWaitQueueLength(c));
+        sync.release();
+
+        final Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, t1);
+                assertEquals(1, sync.getWaitQueueLength(c));
+                assertTrue(acquired2.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertEquals(2, sync.getWaitQueueLength(c));
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertEquals(0, sync.getWaitQueueLength(c));
+        sync.release();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * getWaitingThreads returns only and all waiting threads
+     */
+    public void testGetWaitingThreads() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        final Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                assertTrue(sync.getWaitingThreads(c).isEmpty());
+                assertTrue(acquired1.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        final Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertHasWaitersLocked(sync, c, t1);
+                assertTrue(sync.getWaitingThreads(c).contains(t1));
+                assertFalse(sync.getWaitingThreads(c).isEmpty());
+                assertEquals(1, sync.getWaitingThreads(c).size());
+                assertTrue(acquired2.releaseShared(0));
+                c.await();
+                sync.release();
+            }});
+
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertFalse(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(0, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        t1.start();
+        acquired1.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1);
+        assertTrue(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertFalse(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(1, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        t2.start();
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertTrue(sync.getWaitingThreads(c).contains(t1));
+        assertTrue(sync.getWaitingThreads(c).contains(t2));
+        assertFalse(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(2, sync.getWaitingThreads(c).size());
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        assertFalse(sync.getWaitingThreads(c).contains(t1));
+        assertFalse(sync.getWaitingThreads(c).contains(t2));
+        assertTrue(sync.getWaitingThreads(c).isEmpty());
+        assertEquals(0, sync.getWaitingThreads(c).size());
+        sync.release();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertHasWaitersUnlocked(sync, c, NO_THREADS);
+    }
+
+    /**
+     * awaitUninterruptibly is uninterruptible
+     */
+    public void testAwaitUninterruptibly() {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch pleaseInterrupt = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                sync.acquire();
+                assertTrue(pleaseInterrupt.releaseShared(0));
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                assertHasWaitersLocked(sync, c, NO_THREADS);
+                sync.release();
+            }});
+
+        pleaseInterrupt.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        sync.release();
+        t.interrupt();
+        assertHasWaitersUnlocked(sync, c, t);
+        assertThreadStaysAlive(t);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signal();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t);
+        sync.release();
+        awaitTermination(t);
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil is interruptible
+     */
+    public void testInterruptible_await()      { testInterruptible(AwaitMethod.await); }
+    public void testInterruptible_awaitTimed() { testInterruptible(AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitNanos() { testInterruptible(AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitUntil() { testInterruptible(AwaitMethod.awaitUntil); }
+    public void testInterruptible(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch pleaseInterrupt = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                assertTrue(pleaseInterrupt.releaseShared(0));
+                await(c, awaitMethod);
+            }});
+
+        pleaseInterrupt.acquireShared(0);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * signalAll wakes up all threads
+     */
+    public void testSignalAll_await()      { testSignalAll(AwaitMethod.await); }
+    public void testSignalAll_awaitTimed() { testSignalAll(AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitNanos() { testSignalAll(AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitUntil() { testSignalAll(AwaitMethod.awaitUntil); }
+    public void testSignalAll(final AwaitMethod awaitMethod) {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        final BooleanLatch acquired1 = new BooleanLatch();
+        final BooleanLatch acquired2 = new BooleanLatch();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                acquired1.releaseShared(0);
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                sync.acquire();
+                acquired2.releaseShared(0);
+                await(c, awaitMethod);
+                sync.release();
+            }});
+
+        acquired1.acquireShared(0);
+        acquired2.acquireShared(0);
+        sync.acquire();
+        assertHasWaitersLocked(sync, c, t1, t2);
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        c.signalAll();
+        assertHasWaitersLocked(sync, c, NO_THREADS);
+        assertHasExclusiveQueuedThreads(sync, t1, t2);
+        sync.release();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * toString indicates current state
+     */
+    public void testToString() {
+        Mutex sync = new Mutex();
+        assertTrue(sync.toString().contains("State = " + Mutex.UNLOCKED));
+        sync.acquire();
+        assertTrue(sync.toString().contains("State = " + Mutex.LOCKED));
+    }
+
+    /**
+     * A serialized AQS deserializes with current state, but no queued threads
+     */
+    public void testSerialization() {
+        Mutex sync = new Mutex();
+        assertFalse(serialClone(sync).isHeldExclusively());
+        sync.acquire();
+        Thread t = newStartedThread(new InterruptedSyncRunnable(sync));
+        waitForQueuedThread(sync, t);
+        assertTrue(sync.isHeldExclusively());
+
+        Mutex clone = serialClone(sync);
+        assertTrue(clone.isHeldExclusively());
+        assertHasExclusiveQueuedThreads(sync, t);
+        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+        t.interrupt();
+        awaitTermination(t);
+        sync.release();
+        assertFalse(sync.isHeldExclusively());
+        assertTrue(clone.isHeldExclusively());
+        assertHasExclusiveQueuedThreads(sync, NO_THREADS);
+        assertHasExclusiveQueuedThreads(clone, NO_THREADS);
+    }
+
+    /**
+     * tryReleaseShared setting state changes getState
+     */
+    public void testGetStateWithReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * releaseShared has no effect when already signalled
+     */
+    public void testReleaseShared() {
+        final BooleanLatch l = new BooleanLatch();
+        assertFalse(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+    }
+
+    /**
+     * acquireSharedInterruptibly returns after release, but not before
+     */
+    public void testAcquireSharedInterruptibly() {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                assertTrue(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+                assertTrue(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        assertThreadStaysAlive(t);
+        assertHasSharedQueuedThreads(l, t);
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        awaitTermination(t);
+    }
+
+    /**
+     * tryAcquireSharedNanos returns after release, but not before
+     */
+    public void testTryAcquireSharedNanos() {
+        final BooleanLatch l = new BooleanLatch();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+                assertTrue(l.tryAcquireSharedNanos(0, nanos));
+                assertTrue(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        assertThreadStaysAlive(t);
+        assertTrue(l.releaseShared(0));
+        assertTrue(l.isSignalled());
+        awaitTermination(t);
+    }
+
+    /**
+     * acquireSharedInterruptibly is interruptible
+     */
+    public void testAcquireSharedInterruptibly_Interruptible() {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                l.acquireSharedInterruptibly(0);
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * tryAcquireSharedNanos is interruptible
+     */
+    public void testTryAcquireSharedNanos_Interruptible() {
+        final BooleanLatch l = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                long nanos = MILLISECONDS.toNanos(2 * LONG_DELAY_MS);
+                l.tryAcquireSharedNanos(0, nanos);
+            }});
+
+        waitForQueuedThread(l, t);
+        assertFalse(l.isSignalled());
+        t.interrupt();
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * tryAcquireSharedNanos times out if not released before timeout
+     */
+    public void testTryAcquireSharedNanos_Timeout() {
+        final BooleanLatch l = new BooleanLatch();
+        final BooleanLatch observedQueued = new BooleanLatch();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertFalse(l.isSignalled());
+                for (long millis = timeoutMillis();
+                     !observedQueued.isSignalled();
+                     millis *= 2) {
+                    long nanos = MILLISECONDS.toNanos(millis);
+                    long startTime = System.nanoTime();
+                    assertFalse(l.tryAcquireSharedNanos(0, nanos));
+                    assertTrue(millisElapsedSince(startTime) >= millis);
+                }
+                assertFalse(l.isSignalled());
+            }});
+
+        waitForQueuedThread(l, t);
+        observedQueued.releaseShared(0);
+        assertFalse(l.isSignalled());
+        awaitTermination(t);
+        assertFalse(l.isSignalled());
+    }
+
+    /**
+     * awaitNanos/timed await with 0 wait times out immediately
+     */
+    public void testAwait_Zero() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertTrue(c.awaitNanos(0L) <= 0);
+        assertFalse(c.await(0L, NANOSECONDS));
+        sync.release();
+    }
+
+    /**
+     * awaitNanos/timed await with maximum negative wait times does not underflow
+     */
+    public void testAwait_NegativeInfinity() throws InterruptedException {
+        final Mutex sync = new Mutex();
+        final ConditionObject c = sync.newCondition();
+        sync.acquire();
+        assertTrue(c.awaitNanos(Long.MIN_VALUE) <= 0);
+        assertFalse(c.await(Long.MIN_VALUE, NANOSECONDS));
+        sync.release();
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java
new file mode 100644
index 0000000..23b11d7
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ArrayBlockingQueueTest.java
@@ -0,0 +1,979 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadLocalRandom;
+
+import junit.framework.Test;
+
+public class ArrayBlockingQueueTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return ArrayBlockingQueue.class; }
+            public Collection emptyCollection() {
+                boolean fair = ThreadLocalRandom.current().nextBoolean();
+                return populatedQueue(0, SIZE, 2 * SIZE, fair);
+            }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+
+        return newTestSuite(
+            ArrayBlockingQueueTest.class,
+            new Fair().testSuite(),
+            new NonFair().testSuite(),
+            CollectionTest.testSuite(new Implementation()));
+    }
+
+    public static class Fair extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return populatedQueue(0, SIZE, 2 * SIZE, true);
+        }
+    }
+
+    public static class NonFair extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return populatedQueue(0, SIZE, 2 * SIZE, false);
+        }
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    static ArrayBlockingQueue<Integer> populatedQueue(int n) {
+        return populatedQueue(n, n, n, false);
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1, with given capacity range and fairness.
+     */
+    static ArrayBlockingQueue<Integer> populatedQueue(
+        int size, int minCapacity, int maxCapacity, boolean fair) {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int capacity = rnd.nextInt(minCapacity, maxCapacity + 1);
+        ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<>(capacity);
+        assertTrue(q.isEmpty());
+        // shuffle circular array elements so they wrap
+        {
+            int n = rnd.nextInt(capacity);
+            for (int i = 0; i < n; i++) q.add(42);
+            for (int i = 0; i < n; i++) q.remove();
+        }
+        for (int i = 0; i < size; i++)
+            assertTrue(q.offer((Integer) i));
+        assertEquals(size == 0, q.isEmpty());
+        assertEquals(capacity - size, q.remainingCapacity());
+        assertEquals(size, q.size());
+        if (size > 0)
+            assertEquals((Integer) 0, q.peek());
+        return q;
+    }
+
+    /**
+     * A new queue has the indicated capacity
+     */
+    public void testConstructor1() {
+        assertEquals(SIZE, new ArrayBlockingQueue(SIZE).remainingCapacity());
+    }
+
+    /**
+     * Constructor throws IAE if capacity argument nonpositive
+     */
+    public void testConstructor_nonPositiveCapacity() {
+        for (int i : new int[] { 0, -1, Integer.MIN_VALUE }) {
+            try {
+                new ArrayBlockingQueue(i);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+            for (boolean fair : new boolean[] { true, false }) {
+                try {
+                    new ArrayBlockingQueue(i, fair);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor_nullCollection() {
+        try {
+            new ArrayBlockingQueue(1, true, null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            new ArrayBlockingQueue(SIZE, false, elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            new ArrayBlockingQueue(SIZE, false, elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from too large collection throws IAE
+     */
+    public void testConstructor_collectionTooLarge() {
+        // just barely fits - succeeds
+        new ArrayBlockingQueue(SIZE, false,
+                               Collections.nCopies(SIZE, ""));
+        try {
+            new ArrayBlockingQueue(SIZE - 1, false,
+                                   Collections.nCopies(SIZE, ""));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor7() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = i;
+        Collection<Integer> elements = Arrays.asList(ints);
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE, true, elements);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * Queue transitions from empty to full when elements added
+     */
+    public void testEmptyFull() {
+        BlockingQueue q = populatedQueue(0, 2, 2, false);
+        assertTrue(q.isEmpty());
+        assertEquals(2, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.offer(two));
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertFalse(q.offer(three));
+    }
+
+    /**
+     * remainingCapacity decreases on add, increases on remove
+     */
+    public void testRemainingCapacity() {
+        int size = ThreadLocalRandom.current().nextInt(1, SIZE);
+        BlockingQueue q = populatedQueue(size, size, 2 * size, false);
+        int spare = q.remainingCapacity();
+        int capacity = spare + size;
+        for (int i = 0; i < size; i++) {
+            assertEquals(spare + i, q.remainingCapacity());
+            assertEquals(capacity, q.size() + q.remainingCapacity());
+            assertEquals(i, q.remove());
+        }
+        for (int i = 0; i < size; i++) {
+            assertEquals(capacity - i, q.remainingCapacity());
+            assertEquals(capacity, q.size() + q.remainingCapacity());
+            assertTrue(q.add(i));
+        }
+    }
+
+    /**
+     * Offer succeeds if not full; fails if full
+     */
+    public void testOffer() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(1);
+        assertTrue(q.offer(zero));
+        assertFalse(q.offer(one));
+    }
+
+    /**
+     * add succeeds if not full; throws ISE if full
+     */
+    public void testAdd() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; i++) assertTrue(q.add((Integer) i));
+        assertEquals(0, q.remainingCapacity());
+        try {
+            q.add((Integer) SIZE);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll throws ISE if not enough room
+     */
+    public void testAddAll_insufficientSpace() {
+        int size = ThreadLocalRandom.current().nextInt(1, SIZE);
+        ArrayBlockingQueue q = populatedQueue(0, size, size, false);
+        // Just fits:
+        q.addAll(populatedQueue(size, size, 2 * size, false));
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(size, q.size());
+        assertEquals(0, q.peek());
+        try {
+            q = populatedQueue(0, size, size, false);
+            q.addAll(Collections.nCopies(size + 1, 42));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() throws InterruptedException {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.put(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly if full
+     */
+    public void testBlockingPut() throws InterruptedException {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly waiting for take when full
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(capacity);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity; i++)
+                    q.put(i);
+                pleaseTake.countDown();
+                q.put(86);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(0, q.take());
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offer times out if full and elements not taken
+     */
+    public void testTimedOffer() throws InterruptedException {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                long startTime = System.nanoTime();
+                assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTake() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
+    }
+
+    /**
+     * Take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final ArrayBlockingQueue q = populatedQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+        checkEmpty(q);
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedQueue(SIZE);
+        final CountDownLatch aboutToWait = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                }
+                aboutToWait.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }
+            }});
+
+        await(aboutToWait);
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        int size = ThreadLocalRandom.current().nextInt(1, SIZE);
+        ArrayBlockingQueue q = populatedQueue(size, size, 2 * size, false);
+        assertFalse(q.contains(null));
+        for (int i = 0; i < size; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            assertEquals(i, q.poll());
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        int size = ThreadLocalRandom.current().nextInt(1, 5);
+        ArrayBlockingQueue q = populatedQueue(size, size, 2 * size, false);
+        int capacity = size + q.remainingCapacity();
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(capacity, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        ArrayBlockingQueue p = new ArrayBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        ArrayBlockingQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ArrayBlockingQueue q = populatedQueue(SIZE);
+            ArrayBlockingQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    void checkToArray(ArrayBlockingQueue<Integer> q) {
+        int size = q.size();
+        Object[] a1 = q.toArray();
+        assertEquals(size, a1.length);
+        Integer[] a2 = q.toArray(new Integer[0]);
+        assertEquals(size, a2.length);
+        Integer[] a3 = q.toArray(new Integer[Math.max(0, size - 1)]);
+        assertEquals(size, a3.length);
+        Integer[] a4 = new Integer[size];
+        assertSame(a4, q.toArray(a4));
+        Integer[] a5 = new Integer[size + 1];
+        Arrays.fill(a5, 42);
+        assertSame(a5, q.toArray(a5));
+        Integer[] a6 = new Integer[size + 2];
+        Arrays.fill(a6, 42);
+        assertSame(a6, q.toArray(a6));
+        Object[][] as = { a1, a2, a3, a4, a5, a6 };
+        for (Object[] a : as) {
+            if (a.length > size) assertNull(a[size]);
+            if (a.length > size + 1) assertEquals(42, a[size + 1]);
+        }
+        Iterator it = q.iterator();
+        Integer s = q.peek();
+        for (int i = 0; i < size; i++) {
+            Integer x = (Integer) it.next();
+            assertEquals(s + i, (int) x);
+            for (Object[] a : as)
+                assertSame(a1[i], x);
+        }
+    }
+
+    /**
+     * toArray() and toArray(a) contain all elements in FIFO order
+     */
+    public void testToArray() {
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final int size = rnd.nextInt(6);
+        final int capacity = Math.max(1, size + rnd.nextInt(size + 1));
+        ArrayBlockingQueue<Integer> q = new ArrayBlockingQueue<>(capacity);
+        for (int i = 0; i < size; i++) {
+            checkToArray(q);
+            q.add(i);
+        }
+        // Provoke wraparound
+        int added = size * 2;
+        for (int i = 0; i < added; i++) {
+            checkToArray(q);
+            assertEquals((Integer) i, q.poll());
+            q.add(size + i);
+        }
+        for (int i = 0; i < size; i++) {
+            checkToArray(q);
+            assertEquals((Integer) (added + i), q.poll());
+        }
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray_incompatibleArrayType() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+        try {
+            q.toArray(new String[0]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() throws InterruptedException {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+
+        it = q.iterator();
+        for (i = 0; it.hasNext(); i++)
+            assertEquals(it.next(), q.take());
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new ArrayBlockingQueue(SIZE).iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+        q.add(two);
+        q.add(one);
+        q.add(three);
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+
+        assertEquals("queue should be full", 0, q.remainingCapacity());
+
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+        assertEquals(0, q.size());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor() {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+        q.add(one);
+        q.add(two);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertEquals(0, q.remainingCapacity());
+                    assertSame(one, q.take());
+                }});
+        }
+    }
+
+    /**
+     * timed poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor() {
+        final ArrayBlockingQueue q = new ArrayBlockingQueue(2);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * drainTo(c) empties queue into another collection c
+     */
+    public void testDrainTo() {
+        ArrayBlockingQueue q = populatedQueue(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(SIZE, l.size());
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), new Integer(i));
+    }
+
+    /**
+     * drainTo empties full queue, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final ArrayBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE + 1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        ArrayBlockingQueue q = new ArrayBlockingQueue(SIZE * 2);
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(k, l.size());
+            assertEquals(SIZE - k, q.size());
+            for (int j = 0; j < k; ++j)
+                assertEquals(l.get(j), new Integer(j));
+            do {} while (q.poll() != null);
+        }
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?>[] qs = {
+            populatedQueue(0, 1, 10, false),
+            populatedQueue(2, 2, 10, true),
+        };
+
+        for (Collection<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ArrayDeque8Test.java b/ojluni/src/test/java/util/concurrent/tck/ArrayDeque8Test.java
new file mode 100644
index 0000000..a25d036
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ArrayDeque8Test.java
@@ -0,0 +1,126 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.ArrayDeque;
+import java.util.Collections;
+import java.util.Spliterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ArrayDeque8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(ArrayDeque8Test.class);
+    }
+
+    /**
+     * Spliterator.getComparator always throws IllegalStateException
+     */
+    public void testSpliterator_getComparator() {
+        assertThrows(IllegalStateException.class,
+                     () -> new ArrayDeque().spliterator().getComparator());
+    }
+
+    /**
+     * Spliterator characteristics are as advertised
+     */
+    public void testSpliterator_characteristics() {
+        ArrayDeque q = new ArrayDeque();
+        Spliterator s = q.spliterator();
+        int characteristics = s.characteristics();
+        int required = Spliterator.NONNULL
+            | Spliterator.ORDERED
+            | Spliterator.SIZED
+            | Spliterator.SUBSIZED;
+        assertEquals(required, characteristics & required);
+        assertTrue(s.hasCharacteristics(required));
+        assertEquals(0, characteristics
+                     & (Spliterator.CONCURRENT
+                        | Spliterator.DISTINCT
+                        | Spliterator.IMMUTABLE
+                        | Spliterator.SORTED));
+    }
+
+    /**
+     * Handle capacities near Integer.MAX_VALUE.
+     * ant -Dvmoptions='-Xms28g -Xmx28g' -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ArrayDeque8Test -Djsr166.methodFilter=testHugeCapacity tck
+     */
+    public void testHugeCapacity() {
+        if (! (testImplementationDetails
+               && expensiveTests
+               && Runtime.getRuntime().maxMemory() > 24L * (1 << 30)))
+            return;
+
+        final Integer e = 42;
+        final int maxArraySize = Integer.MAX_VALUE - 8;
+
+        assertThrows(OutOfMemoryError.class,
+                     () -> new ArrayDeque(Integer.MAX_VALUE));
+
+        {
+            ArrayDeque q = new ArrayDeque(maxArraySize - 1);
+            assertEquals(0, q.size());
+            assertTrue(q.isEmpty());
+            q = null;
+        }
+
+        {
+            ArrayDeque q = new ArrayDeque();
+            assertTrue(q.addAll(Collections.nCopies(maxArraySize - 3, e)));
+            assertEquals(e, q.peekFirst());
+            assertEquals(e, q.peekLast());
+            assertEquals(maxArraySize - 3, q.size());
+            q.addFirst((Integer) 0);
+            q.addLast((Integer) 1);
+            assertEquals((Integer) 0, q.peekFirst());
+            assertEquals((Integer) 1, q.peekLast());
+            assertEquals(maxArraySize - 1, q.size());
+
+            ArrayDeque qq = q;
+            ArrayDeque smallish = new ArrayDeque(
+                Collections.nCopies(Integer.MAX_VALUE - q.size() + 1, e));
+            assertThrows(
+                IllegalStateException.class,
+                () -> qq.addAll(qq),
+                () -> qq.addAll(smallish),
+                () -> smallish.addAll(qq));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ArrayDequeTest.java b/ojluni/src/test/java/util/concurrent/tck/ArrayDequeTest.java
new file mode 100644
index 0000000..1cff7ff
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ArrayDequeTest.java
@@ -0,0 +1,998 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ArrayDequeTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return ArrayDeque.class; }
+            public Collection emptyCollection() { return populatedDeque(0); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(ArrayDequeTest.class,
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Returns a new deque of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private static ArrayDeque<Integer> populatedDeque(int n) {
+        // Randomize various aspects of memory layout, including
+        // capacity slop and wraparound.
+        final ArrayDeque<Integer> q;
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        switch (rnd.nextInt(6)) {
+        case 0: q = new ArrayDeque<Integer>();      break;
+        case 1: q = new ArrayDeque<Integer>(0);     break;
+        case 2: q = new ArrayDeque<Integer>(1);     break;
+        case 3: q = new ArrayDeque<Integer>(Math.max(0, n - 1)); break;
+        case 4: q = new ArrayDeque<Integer>(n);     break;
+        case 5: q = new ArrayDeque<Integer>(n + 1); break;
+        default: throw new AssertionError();
+        }
+        switch (rnd.nextInt(3)) {
+        case 0:
+            q.addFirst(42);
+            assertEquals((Integer) 42, q.removeLast());
+            break;
+        case 1:
+            q.addLast(42);
+            assertEquals((Integer) 42, q.removeFirst());
+            break;
+        case 2: /* do nothing */ break;
+        default: throw new AssertionError();
+        }
+        assertTrue(q.isEmpty());
+        if (rnd.nextBoolean())
+            for (int i = 0; i < n; i++)
+                assertTrue(q.offerLast((Integer) i));
+        else
+            for (int i = n; --i >= 0; )
+                q.addFirst((Integer) i);
+        assertEquals(n, q.size());
+        if (n > 0) {
+            assertFalse(q.isEmpty());
+            assertEquals((Integer) 0, q.peekFirst());
+            assertEquals((Integer) (n - 1), q.peekLast());
+        }
+        return q;
+    }
+
+    /**
+     * new deque is empty
+     */
+    public void testConstructor1() {
+        assertEquals(0, new ArrayDeque().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new ArrayDeque((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new ArrayDeque(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new ArrayDeque(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayDeque q = new ArrayDeque(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.removeFirst();
+        q.removeFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.removeFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * push(null) throws NPE
+     */
+    public void testPushNull() {
+        ArrayDeque q = new ArrayDeque(1);
+        try {
+            q.push(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * peekFirst() returns element inserted with push
+     */
+    public void testPush() {
+        ArrayDeque q = populatedDeque(3);
+        q.pollLast();
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * pop() removes next element, or throws NSEE if empty
+     */
+    public void testPop() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offerFirst(null) throws NPE
+     */
+    public void testOfferFirstNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.offerFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offerLast(null) throws NPE
+     */
+    public void testOfferLastNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.offerLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offer(x) succeeds
+     */
+    public void testOffer() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.offer(zero));
+        assertTrue(q.offer(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * offerFirst(x) succeeds
+     */
+    public void testOfferFirst() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.offerFirst(zero));
+        assertTrue(q.offerFirst(one));
+        assertSame(one, q.peekFirst());
+        assertSame(zero, q.peekLast());
+    }
+
+    /**
+     * offerLast(x) succeeds
+     */
+    public void testOfferLast() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.offerLast(zero));
+        assertTrue(q.offerLast(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addFirst(null) throws NPE
+     */
+    public void testAddFirstNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.addFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addLast(null) throws NPE
+     */
+    public void testAddLastNull() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.addLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(x) succeeds
+     */
+    public void testAdd() {
+        ArrayDeque q = new ArrayDeque();
+        assertTrue(q.add(zero));
+        assertTrue(q.add(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * addFirst(x) succeeds
+     */
+    public void testAddFirst() {
+        ArrayDeque q = new ArrayDeque();
+        q.addFirst(zero);
+        q.addFirst(one);
+        assertSame(one, q.peekFirst());
+        assertSame(zero, q.peekLast());
+    }
+
+    /**
+     * addLast(x) succeeds
+     */
+    public void testAddLast() {
+        ArrayDeque q = new ArrayDeque();
+        q.addLast(zero);
+        q.addLast(one);
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        ArrayDeque q = new ArrayDeque();
+        try {
+            q.addAll(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        ArrayDeque q = new ArrayDeque();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ArrayDeque q = new ArrayDeque();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * pollFirst() succeeds unless empty
+     */
+    public void testPollFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast() succeeds unless empty
+     */
+    public void testPollLast() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     * poll() succeeds unless empty
+     */
+    public void testPoll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * remove() removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * peekFirst() returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * peek() returns next element, or null if empty
+     */
+    public void testPeek() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * peekLast() returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * element() returns first element, or throws NSEE if empty
+     */
+    public void testElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * getFirst() returns first element, or throws NSEE if empty
+     */
+    public void testFirstElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * getLast() returns last element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirst() removes first element, or throws NSEE if empty
+     */
+    public void testRemoveFirst() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.removeFirst());
+        }
+        try {
+            q.removeFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * removeLast() removes last element, or throws NSEE if empty
+     */
+    public void testRemoveLast() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.removeLast());
+        }
+        try {
+            q.removeLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        Deque<Integer> q = populatedDeque(SIZE);
+        assertFalse(q.removeFirstOccurrence(null));
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(i));
+            assertFalse(q.contains(i));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(i));
+            assertFalse(q.removeFirstOccurrence(i + 1));
+            assertFalse(q.contains(i));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+        assertFalse(q.removeFirstOccurrence(null));
+        assertFalse(q.removeFirstOccurrence(42));
+        q = new ArrayDeque();
+        assertFalse(q.removeFirstOccurrence(null));
+        assertFalse(q.removeFirstOccurrence(42));
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        Deque<Integer> q = populatedDeque(SIZE);
+        assertFalse(q.removeLastOccurrence(null));
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(i));
+            assertFalse(q.contains(i));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(i));
+            assertFalse(q.removeLastOccurrence(i + 1));
+            assertFalse(q.contains(i));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+        assertFalse(q.removeLastOccurrence(null));
+        assertFalse(q.removeLastOccurrence(42));
+        q = new ArrayDeque();
+        assertFalse(q.removeLastOccurrence(null));
+        assertFalse(q.removeLastOccurrence(42));
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ArrayDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            assertEquals(i, q.pollFirst());
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        ArrayDeque q = populatedDeque(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        ArrayDeque p = new ArrayDeque();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            assertTrue(p.add(new Integer(i)));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        ArrayDeque q = populatedDeque(SIZE);
+        ArrayDeque p = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            assertEquals(changed, (i > 0));
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.removeFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ArrayDeque q = populatedDeque(SIZE);
+            ArrayDeque p = populatedDeque(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                assertFalse(q.contains(p.removeFirst()));
+            }
+        }
+    }
+
+    void checkToArray(ArrayDeque<Integer> q) {
+        int size = q.size();
+        Object[] a1 = q.toArray();
+        assertEquals(size, a1.length);
+        Integer[] a2 = q.toArray(new Integer[0]);
+        assertEquals(size, a2.length);
+        Integer[] a3 = q.toArray(new Integer[Math.max(0, size - 1)]);
+        assertEquals(size, a3.length);
+        Integer[] a4 = new Integer[size];
+        assertSame(a4, q.toArray(a4));
+        Integer[] a5 = new Integer[size + 1];
+        Arrays.fill(a5, 42);
+        assertSame(a5, q.toArray(a5));
+        Integer[] a6 = new Integer[size + 2];
+        Arrays.fill(a6, 42);
+        assertSame(a6, q.toArray(a6));
+        Object[][] as = { a1, a2, a3, a4, a5, a6 };
+        for (Object[] a : as) {
+            if (a.length > size) assertNull(a[size]);
+            if (a.length > size + 1) assertEquals(42, a[size + 1]);
+        }
+        Iterator it = q.iterator();
+        Integer s = q.peekFirst();
+        for (int i = 0; i < size; i++) {
+            Integer x = (Integer) it.next();
+            assertEquals(s + i, (int) x);
+            for (Object[] a : as)
+                assertSame(a1[i], x);
+        }
+    }
+
+    /**
+     * toArray() and toArray(a) contain all elements in FIFO order
+     */
+    public void testToArray() {
+        final int size = ThreadLocalRandom.current().nextInt(10);
+        ArrayDeque<Integer> q = new ArrayDeque<>(size);
+        for (int i = 0; i < size; i++) {
+            checkToArray(q);
+            q.addLast(i);
+        }
+        // Provoke wraparound
+        int added = size * 2;
+        for (int i = 0; i < added; i++) {
+            checkToArray(q);
+            assertEquals((Integer) i, q.poll());
+            q.addLast(size + i);
+        }
+        for (int i = 0; i < size; i++) {
+            checkToArray(q);
+            assertEquals((Integer) (added + i), q.poll());
+        }
+    }
+
+    /**
+     * toArray(null) throws NullPointerException
+     */
+    public void testToArray_NullArg() {
+        ArrayDeque l = new ArrayDeque();
+        l.add(new Object());
+        try {
+            l.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray_incompatibleArrayType() {
+        ArrayDeque l = new ArrayDeque();
+        l.add(new Integer(5));
+        try {
+            l.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+        try {
+            l.toArray(new String[0]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * Iterator iterates through all elements
+     */
+    public void testIterator() {
+        ArrayDeque q = populatedDeque(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        Deque c = new ArrayDeque();
+        assertIteratorExhausted(c.iterator());
+        assertIteratorExhausted(c.descendingIterator());
+    }
+
+    /**
+     * Iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final ArrayDeque q = new ArrayDeque();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * iterator.remove() removes current element
+     */
+    public void testIteratorRemove() {
+        final ArrayDeque q = new ArrayDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max - 1) + 1;
+            for (int j = 1; j <= max; ++j)
+                q.add(new Integer(j));
+            Iterator it = q.iterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split + 1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.iterator();
+            for (int j = split + 1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+    /**
+     * Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        ArrayDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final ArrayDeque q = new ArrayDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            int k = 0;
+            for (Iterator it = q.descendingIterator(); it.hasNext();) {
+                assertEquals(++k, it.next());
+            }
+
+            assertEquals(3, k);
+            q.remove();
+            q.remove();
+            q.remove();
+        }
+    }
+
+    /**
+     * descendingIterator.remove() removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final ArrayDeque q = new ArrayDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max - 1) + 1;
+            for (int j = max; j >= 1; --j)
+                q.add(new Integer(j));
+            Iterator it = q.descendingIterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split + 1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.descendingIterator();
+            for (int j = split + 1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+    /**
+     * toString() contains toStrings of elements
+     */
+    public void testToString() {
+        ArrayDeque q = populatedDeque(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized deque has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedDeque(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(Arrays.toString(x.toArray()), Arrays.toString(y.toArray()));
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * A cloned deque has same elements in same order
+     */
+    public void testClone() throws Exception {
+        ArrayDeque<Integer> x = populatedDeque(SIZE);
+        ArrayDeque<Integer> y = x.clone();
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Deque<?>[] qs = {
+            new ArrayDeque<Object>(),
+            populatedDeque(2),
+        };
+
+        for (Deque<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+            assertFalse(q.removeFirstOccurrence(null));
+            assertFalse(q.removeLastOccurrence(null));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ArrayListTest.java b/ojluni/src/test/java/util/concurrent/tck/ArrayListTest.java
new file mode 100644
index 0000000..b168d50
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ArrayListTest.java
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ArrayListTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return ArrayList.class; }
+            public List emptyCollection() { return new ArrayList(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return true; }
+        }
+        class SubListImplementation extends Implementation {
+            public List emptyCollection() {
+                return super.emptyCollection().subList(0, 0);
+            }
+        }
+        return newTestSuite(
+                // ArrayListTest.class,
+                CollectionTest.testSuite(new Implementation()),
+                CollectionTest.testSuite(new SubListImplementation()));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/Atomic8Test.java b/ojluni/src/test/java/util/concurrent/tck/Atomic8Test.java
new file mode 100644
index 0000000..dc3af4c
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/Atomic8Test.java
@@ -0,0 +1,628 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicLongArray;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Tests of atomic class methods accepting lambdas introduced in JDK8.
+ */
+public class Atomic8Test extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(Atomic8Test.class);
+    }
+
+    static long addLong17(long x) { return x + 17; }
+    static int addInt17(int x) { return x + 17; }
+    static Integer addInteger17(Integer x) {
+        return x.intValue() + 17;
+    }
+    static Integer sumInteger(Integer x, Integer y) {
+        return x.intValue() + y.intValue();
+    }
+
+    volatile long aLongField;
+    volatile int anIntField;
+    volatile Integer anIntegerField;
+
+    AtomicLongFieldUpdater<Atomic8Test> aLongFieldUpdater() {
+        return AtomicLongFieldUpdater.newUpdater
+            (Atomic8Test.class, "aLongField");
+    }
+
+    AtomicIntegerFieldUpdater<Atomic8Test> anIntFieldUpdater() {
+        return AtomicIntegerFieldUpdater.newUpdater
+            (Atomic8Test.class, "anIntField");
+    }
+
+    AtomicReferenceFieldUpdater<Atomic8Test,Integer> anIntegerFieldUpdater() {
+        return AtomicReferenceFieldUpdater.newUpdater
+            (Atomic8Test.class, Integer.class, "anIntegerField");
+    }
+
+    /**
+     * AtomicLong getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongGetAndUpdate() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(1L, a.getAndUpdate(Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(Atomic8Test::addLong17));
+        assertEquals(35L, a.get());
+    }
+
+    /**
+     * AtomicLong updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongUpdateAndGet() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(18L, a.updateAndGet(Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(Atomic8Test::addLong17));
+    }
+
+    /**
+     * AtomicLong getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testLongGetAndAccumulate() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(1L, a.getAndAccumulate(2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(3L, Long::sum));
+        assertEquals(6L, a.get());
+    }
+
+    /**
+     * AtomicLong accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongAccumulateAndGet() {
+        AtomicLong a = new AtomicLong(1L);
+        assertEquals(7L, a.accumulateAndGet(6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(3L, Long::sum));
+        assertEquals(10L, a.get());
+    }
+
+    /**
+     * AtomicInteger getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntGetAndUpdate() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(1, a.getAndUpdate(Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(Atomic8Test::addInt17));
+        assertEquals(35, a.get());
+    }
+
+    /**
+     * AtomicInteger updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntUpdateAndGet() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(18, a.updateAndGet(Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(Atomic8Test::addInt17));
+        assertEquals(35, a.get());
+    }
+
+    /**
+     * AtomicInteger getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testIntGetAndAccumulate() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(1, a.getAndAccumulate(2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(3, Integer::sum));
+        assertEquals(6, a.get());
+    }
+
+    /**
+     * AtomicInteger accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntAccumulateAndGet() {
+        AtomicInteger a = new AtomicInteger(1);
+        assertEquals(7, a.accumulateAndGet(6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(3, Integer::sum));
+        assertEquals(10, a.get());
+    }
+
+    /**
+     * AtomicReference getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testReferenceGetAndUpdate() {
+        AtomicReference<Integer> a = new AtomicReference<>(one);
+        assertEquals((Integer) 1, a.getAndUpdate(Atomic8Test::addInteger17));
+        assertEquals((Integer) 18, a.getAndUpdate(Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.get());
+    }
+
+    /**
+     * AtomicReference updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceUpdateAndGet() {
+        AtomicReference<Integer> a = new AtomicReference<>(one);
+        assertEquals((Integer) 18, a.updateAndGet(Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.updateAndGet(Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.get());
+    }
+
+    /**
+     * AtomicReference getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceGetAndAccumulate() {
+        AtomicReference<Integer> a = new AtomicReference<>(one);
+        assertEquals((Integer) 1, a.getAndAccumulate(2, Atomic8Test::sumInteger));
+        assertEquals((Integer) 3, a.getAndAccumulate(3, Atomic8Test::sumInteger));
+        assertEquals((Integer) 6, a.get());
+    }
+
+    /**
+     * AtomicReference accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceAccumulateAndGet() {
+        AtomicReference<Integer> a = new AtomicReference<>(one);
+        assertEquals((Integer) 7, a.accumulateAndGet(6, Atomic8Test::sumInteger));
+        assertEquals((Integer) 10, a.accumulateAndGet(3, Atomic8Test::sumInteger));
+        assertEquals((Integer) 10, a.get());
+    }
+
+    /**
+     * AtomicLongArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongArrayGetAndUpdate() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(1L, a.getAndUpdate(0, Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongArrayUpdateAndGet() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(18L, a.updateAndGet(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(0, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testLongArrayGetAndAccumulate() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(1L, a.getAndAccumulate(0, 2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(0, 3L, Long::sum));
+        assertEquals(6L, a.get(0));
+    }
+
+    /**
+     * AtomicLongArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongArrayAccumulateAndGet() {
+        AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        assertEquals(7L, a.accumulateAndGet(0, 6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(0, 3L, Long::sum));
+        assertEquals(10L, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntArrayGetAndUpdate() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(1, a.getAndUpdate(0, Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(0, Atomic8Test::addInt17));
+        assertEquals(35, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntArrayUpdateAndGet() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(18, a.updateAndGet(0, Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(0, Atomic8Test::addInt17));
+        assertEquals(35, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testIntArrayGetAndAccumulate() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(1, a.getAndAccumulate(0, 2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(0, 3, Integer::sum));
+        assertEquals(6, a.get(0));
+    }
+
+    /**
+     * AtomicIntegerArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntArrayAccumulateAndGet() {
+        AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        assertEquals(7, a.accumulateAndGet(0, 6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(0, 3, Integer::sum));
+    }
+
+    /**
+     * AtomicReferenceArray getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testReferenceArrayGetAndUpdate() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<>(1);
+        a.set(0, one);
+        assertEquals((Integer) 1, a.getAndUpdate(0, Atomic8Test::addInteger17));
+        assertEquals((Integer) 18, a.getAndUpdate(0, Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.get(0));
+    }
+
+    /**
+     * AtomicReferenceArray updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceArrayUpdateAndGet() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<>(1);
+        a.set(0, one);
+        assertEquals((Integer) 18, a.updateAndGet(0, Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.updateAndGet(0, Atomic8Test::addInteger17));
+    }
+
+    /**
+     * AtomicReferenceArray getAndAccumulate returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceArrayGetAndAccumulate() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<>(1);
+        a.set(0, one);
+        assertEquals((Integer) 1, a.getAndAccumulate(0, 2, Atomic8Test::sumInteger));
+        assertEquals((Integer) 3, a.getAndAccumulate(0, 3, Atomic8Test::sumInteger));
+        assertEquals((Integer) 6, a.get(0));
+    }
+
+    /**
+     * AtomicReferenceArray accumulateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testReferenceArrayAccumulateAndGet() {
+        AtomicReferenceArray<Integer> a = new AtomicReferenceArray<>(1);
+        a.set(0, one);
+        assertEquals((Integer) 7, a.accumulateAndGet(0, 6, Atomic8Test::sumInteger));
+        assertEquals((Integer) 10, a.accumulateAndGet(0, 3, Atomic8Test::sumInteger));
+    }
+
+    /**
+     * AtomicLongFieldUpdater getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testLongFieldUpdaterGetAndUpdate() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1L, a.getAndUpdate(this, Atomic8Test::addLong17));
+        assertEquals(18L, a.getAndUpdate(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(this));
+        assertEquals(35L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testLongFieldUpdaterUpdateAndGet() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(18L, a.updateAndGet(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.updateAndGet(this, Atomic8Test::addLong17));
+        assertEquals(35L, a.get(this));
+        assertEquals(35L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater getAndAccumulate returns previous value
+     * and updates with supplied function.
+     */
+    public void testLongFieldUpdaterGetAndAccumulate() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1L, a.getAndAccumulate(this, 2L, Long::sum));
+        assertEquals(3L, a.getAndAccumulate(this, 3L, Long::sum));
+        assertEquals(6L, a.get(this));
+        assertEquals(6L, aLongField);
+    }
+
+    /**
+     * AtomicLongFieldUpdater accumulateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testLongFieldUpdaterAccumulateAndGet() {
+        AtomicLongFieldUpdater a = aLongFieldUpdater();
+        a.set(this, 1);
+        assertEquals(7L, a.accumulateAndGet(this, 6L, Long::sum));
+        assertEquals(10L, a.accumulateAndGet(this, 3L, Long::sum));
+        assertEquals(10L, a.get(this));
+        assertEquals(10L, aLongField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater getAndUpdate returns previous value and updates
+     * result of supplied function
+     */
+    public void testIntegerFieldUpdaterGetAndUpdate() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1, a.getAndUpdate(this, Atomic8Test::addInt17));
+        assertEquals(18, a.getAndUpdate(this, Atomic8Test::addInt17));
+        assertEquals(35, a.get(this));
+        assertEquals(35, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater updateAndGet updates with supplied function and
+     * returns result.
+     */
+    public void testIntegerFieldUpdaterUpdateAndGet() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(18, a.updateAndGet(this, Atomic8Test::addInt17));
+        assertEquals(35, a.updateAndGet(this, Atomic8Test::addInt17));
+        assertEquals(35, a.get(this));
+        assertEquals(35, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater getAndAccumulate returns previous value
+     * and updates with supplied function.
+     */
+    public void testIntegerFieldUpdaterGetAndAccumulate() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(1, a.getAndAccumulate(this, 2, Integer::sum));
+        assertEquals(3, a.getAndAccumulate(this, 3, Integer::sum));
+        assertEquals(6, a.get(this));
+        assertEquals(6, anIntField);
+    }
+
+    /**
+     * AtomicIntegerFieldUpdater accumulateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testIntegerFieldUpdaterAccumulateAndGet() {
+        AtomicIntegerFieldUpdater a = anIntFieldUpdater();
+        a.set(this, 1);
+        assertEquals(7, a.accumulateAndGet(this, 6, Integer::sum));
+        assertEquals(10, a.accumulateAndGet(this, 3, Integer::sum));
+        assertEquals(10, a.get(this));
+        assertEquals(10, anIntField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater getAndUpdate returns previous value
+     * and updates result of supplied function
+     */
+    public void testReferenceFieldUpdaterGetAndUpdate() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals((Integer) 1, a.getAndUpdate(this, Atomic8Test::addInteger17));
+        assertEquals((Integer) 18, a.getAndUpdate(this, Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.get(this));
+        assertEquals((Integer) 35, anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater updateAndGet updates with supplied
+     * function and returns result.
+     */
+    public void testReferenceFieldUpdaterUpdateAndGet() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals((Integer) 18, a.updateAndGet(this, Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.updateAndGet(this, Atomic8Test::addInteger17));
+        assertEquals((Integer) 35, a.get(this));
+        assertEquals((Integer) 35, anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater returns previous value and updates
+     * with supplied function.
+     */
+    public void testReferenceFieldUpdaterGetAndAccumulate() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals((Integer) 1, a.getAndAccumulate(this, 2, Atomic8Test::sumInteger));
+        assertEquals((Integer) 3, a.getAndAccumulate(this, 3, Atomic8Test::sumInteger));
+        assertEquals((Integer) 6, a.get(this));
+        assertEquals((Integer) 6, anIntegerField);
+    }
+
+    /**
+     * AtomicReferenceFieldUpdater accumulateAndGet updates with
+     * supplied function and returns result.
+     */
+    public void testReferenceFieldUpdaterAccumulateAndGet() {
+        AtomicReferenceFieldUpdater<Atomic8Test,Integer> a = anIntegerFieldUpdater();
+        a.set(this, one);
+        assertEquals((Integer) 7, a.accumulateAndGet(this, 6, Atomic8Test::sumInteger));
+        assertEquals((Integer) 10, a.accumulateAndGet(this, 3, Atomic8Test::sumInteger));
+        assertEquals((Integer) 10, a.get(this));
+        assertEquals((Integer) 10, anIntegerField);
+    }
+
+    /**
+     * All Atomic getAndUpdate methods throw NullPointerException on
+     * null function argument
+     */
+    public void testGetAndUpdateNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().getAndUpdate(null),
+            () -> new AtomicInteger().getAndUpdate(null),
+            () -> new AtomicReference().getAndUpdate(null),
+            () -> new AtomicLongArray(1).getAndUpdate(0, null),
+            () -> new AtomicIntegerArray(1).getAndUpdate(0, null),
+            () -> new AtomicReferenceArray(1).getAndUpdate(0, null),
+            () -> aLongFieldUpdater().getAndUpdate(this, null),
+            () -> anIntFieldUpdater().getAndUpdate(this, null),
+            () -> anIntegerFieldUpdater().getAndUpdate(this, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic updateAndGet methods throw NullPointerException on null function argument
+     */
+    public void testUpdateAndGetNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().updateAndGet(null),
+            () -> new AtomicInteger().updateAndGet(null),
+            () -> new AtomicReference().updateAndGet(null),
+            () -> new AtomicLongArray(1).updateAndGet(0, null),
+            () -> new AtomicIntegerArray(1).updateAndGet(0, null),
+            () -> new AtomicReferenceArray(1).updateAndGet(0, null),
+            () -> aLongFieldUpdater().updateAndGet(this, null),
+            () -> anIntFieldUpdater().updateAndGet(this, null),
+            () -> anIntegerFieldUpdater().updateAndGet(this, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic getAndAccumulate methods throw NullPointerException
+     * on null function argument
+     */
+    public void testGetAndAccumulateNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().getAndAccumulate(1L, null),
+            () -> new AtomicInteger().getAndAccumulate(1, null),
+            () -> new AtomicReference().getAndAccumulate(one, null),
+            () -> new AtomicLongArray(1).getAndAccumulate(0, 1L, null),
+            () -> new AtomicIntegerArray(1).getAndAccumulate(0, 1, null),
+            () -> new AtomicReferenceArray(1).getAndAccumulate(0, one, null),
+            () -> aLongFieldUpdater().getAndAccumulate(this, 1L, null),
+            () -> anIntFieldUpdater().getAndAccumulate(this, 1, null),
+            () -> anIntegerFieldUpdater().getAndAccumulate(this, one, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * All Atomic accumulateAndGet methods throw NullPointerException
+     * on null function argument
+     */
+    public void testAccumulateAndGetNPE() {
+        Runnable[] throwingActions = {
+            () -> new AtomicLong().accumulateAndGet(1L, null),
+            () -> new AtomicInteger().accumulateAndGet(1, null),
+            () -> new AtomicReference().accumulateAndGet(one, null),
+            () -> new AtomicLongArray(1).accumulateAndGet(0, 1L, null),
+            () -> new AtomicIntegerArray(1).accumulateAndGet(0, 1, null),
+            () -> new AtomicReferenceArray(1).accumulateAndGet(0, one, null),
+            () -> aLongFieldUpdater().accumulateAndGet(this, 1L, null),
+            () -> anIntFieldUpdater().accumulateAndGet(this, 1, null),
+            () -> anIntegerFieldUpdater().accumulateAndGet(this, one, null),
+        };
+        assertThrows(NullPointerException.class, throwingActions);
+    }
+
+    /**
+     * Object arguments for parameters of type T that are not
+     * instances of the class passed to the newUpdater call will
+     * result in a ClassCastException being thrown.
+     */
+    public void testFieldUpdaters_ClassCastException() {
+        // Use raw types to allow passing wrong object type, provoking CCE
+        final AtomicLongFieldUpdater longUpdater = aLongFieldUpdater();
+        final AtomicIntegerFieldUpdater intUpdater = anIntFieldUpdater();
+        final AtomicReferenceFieldUpdater refUpdater = anIntegerFieldUpdater();
+        final Object obj = new Object();
+        for (Object x : new Object[]{ new Object(), null }) {
+            Runnable[] throwingActions = {
+                () -> longUpdater.get(x),
+                () -> intUpdater.get(x),
+                () -> refUpdater.get(x),
+
+                () -> longUpdater.set(x, 17L),
+                () -> intUpdater.set(x, 17),
+                () -> refUpdater.set(x, (Integer) 17),
+
+                () -> longUpdater.addAndGet(x, 17L),
+                () -> intUpdater.addAndGet(x, 17),
+
+                () -> longUpdater.getAndUpdate(x, y -> y),
+                () -> intUpdater.getAndUpdate(x, y -> y),
+                () -> refUpdater.getAndUpdate(x, y -> y),
+
+                () -> longUpdater.compareAndSet(x, 17L, 42L),
+                () -> intUpdater.compareAndSet(x, 17, 42),
+                () -> refUpdater.compareAndSet(x, (Integer) 17, (Integer) 42),
+            };
+            assertThrows(ClassCastException.class, throwingActions);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicBooleanTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicBooleanTest.java
new file mode 100644
index 0000000..4d666da
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicBooleanTest.java
@@ -0,0 +1,173 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicBooleanTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicBooleanTest.class);
+    }
+
+    /**
+     * constructor initializes to given value
+     */
+    public void testConstructor() {
+        assertTrue(new AtomicBoolean(true).get());
+        assertFalse(new AtomicBoolean(false).get());
+    }
+
+    /**
+     * default constructed initializes to false
+     */
+    public void testConstructor2() {
+        AtomicBoolean ai = new AtomicBoolean();
+        assertFalse(ai.get());
+    }
+
+    /**
+     * get returns the last value set
+     */
+    public void testGetSet() {
+        AtomicBoolean ai = new AtomicBoolean(true);
+        assertTrue(ai.get());
+        ai.set(false);
+        assertFalse(ai.get());
+        ai.set(true);
+        assertTrue(ai.get());
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicBoolean ai = new AtomicBoolean(true);
+        assertTrue(ai.get());
+        ai.lazySet(false);
+        assertFalse(ai.get());
+        ai.lazySet(true);
+        assertTrue(ai.get());
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicBoolean ai = new AtomicBoolean(true);
+        assertTrue(ai.compareAndSet(true, false));
+        assertFalse(ai.get());
+        assertTrue(ai.compareAndSet(false, false));
+        assertFalse(ai.get());
+        assertFalse(ai.compareAndSet(true, false));
+        assertFalse(ai.get());
+        assertTrue(ai.compareAndSet(false, true));
+        assertTrue(ai.get());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicBoolean ai = new AtomicBoolean(true);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(false, true)) Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(true, false));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicBoolean ai = new AtomicBoolean(true);
+        do {} while (!ai.weakCompareAndSet(true, false));
+        assertFalse(ai.get());
+        do {} while (!ai.weakCompareAndSet(false, false));
+        assertFalse(ai.get());
+        do {} while (!ai.weakCompareAndSet(false, true));
+        assertTrue(ai.get());
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicBoolean ai = new AtomicBoolean();
+        boolean[] booleans = { false, true };
+        for (boolean before : booleans)
+            for (boolean after : booleans) {
+                ai.set(before);
+                assertEquals(before, ai.getAndSet(after));
+                assertEquals(after, ai.get());
+            }
+    }
+
+    /**
+     * a deserialized serialized atomic holds same value
+     */
+    public void testSerialization() throws Exception {
+        AtomicBoolean x = new AtomicBoolean();
+        AtomicBoolean y = serialClone(x);
+        x.set(true);
+        AtomicBoolean z = serialClone(x);
+        assertTrue(x.get());
+        assertFalse(y.get());
+        assertTrue(z.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        AtomicBoolean ai = new AtomicBoolean();
+        assertEquals(Boolean.toString(false), ai.toString());
+        ai.set(true);
+        assertEquals(Boolean.toString(true), ai.toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java
new file mode 100644
index 0000000..e24d0ea
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerArrayTest.java
@@ -0,0 +1,369 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicIntegerArray;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicIntegerArrayTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicIntegerArrayTest.class);
+    }
+
+    /**
+     * constructor creates array of given size with all elements zero
+     */
+    public void testConstructor() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++)
+            assertEquals(0, aa.get(i));
+    }
+
+    /**
+     * constructor with null array throws NPE
+     */
+    public void testConstructor2NPE() {
+        try {
+            int[] a = null;
+            new AtomicIntegerArray(a);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * constructor with array is of same size and has all elements
+     */
+    public void testConstructor2() {
+        int[] a = { 17, 3, -42, 99, -7 };
+        AtomicIntegerArray aa = new AtomicIntegerArray(a);
+        assertEquals(a.length, aa.length());
+        for (int i = 0; i < a.length; i++)
+            assertEquals(a[i], aa.get(i));
+    }
+
+    /**
+     * get and set for out of bound indices throw IndexOutOfBoundsException
+     */
+    public void testIndexing() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int index : new int[] { -1, SIZE }) {
+            try {
+                aa.get(index);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.set(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.lazySet(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.compareAndSet(index, 1, 2);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.weakCompareAndSet(index, 1, 2);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.getAndAdd(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.addAndGet(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * get returns the last value set at index
+     */
+    public void testGetSet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.get(i));
+            aa.set(i, 2);
+            assertEquals(2, aa.get(i));
+            aa.set(i, -3);
+            assertEquals(-3, aa.get(i));
+        }
+    }
+
+    /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.lazySet(i, 1);
+            assertEquals(1, aa.get(i));
+            aa.lazySet(i, 2);
+            assertEquals(2, aa.get(i));
+            aa.lazySet(i, -3);
+            assertEquals(-3, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertTrue(aa.compareAndSet(i, 1, 2));
+            assertTrue(aa.compareAndSet(i, 2, -4));
+            assertEquals(-4, aa.get(i));
+            assertFalse(aa.compareAndSet(i, -5, 7));
+            assertEquals(-4, aa.get(i));
+            assertTrue(aa.compareAndSet(i, -4, 7));
+            assertEquals(7, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicIntegerArray a = new AtomicIntegerArray(1);
+        a.set(0, 1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, a.get(0));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            do {} while (!aa.weakCompareAndSet(i, 1, 2));
+            do {} while (!aa.weakCompareAndSet(i, 2, -4));
+            assertEquals(-4, aa.get(i));
+            do {} while (!aa.weakCompareAndSet(i, -4, 7));
+            assertEquals(7, aa.get(i));
+        }
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value at given index
+     */
+    public void testGetAndSet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndSet(i, 0));
+            assertEquals(0, aa.getAndSet(i, -10));
+            assertEquals(-10, aa.getAndSet(i, 1));
+        }
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndAdd(i, 2));
+            assertEquals(3, aa.get(i));
+            assertEquals(3, aa.getAndAdd(i, -4));
+            assertEquals(-1, aa.get(i));
+        }
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndDecrement(i));
+            assertEquals(0, aa.getAndDecrement(i));
+            assertEquals(-1, aa.getAndDecrement(i));
+        }
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndIncrement(i));
+            assertEquals(2, aa.get(i));
+            aa.set(i, -2);
+            assertEquals(-2, aa.getAndIncrement(i));
+            assertEquals(-1, aa.getAndIncrement(i));
+            assertEquals(0, aa.getAndIncrement(i));
+            assertEquals(1, aa.get(i));
+        }
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(3, aa.addAndGet(i, 2));
+            assertEquals(3, aa.get(i));
+            assertEquals(-1, aa.addAndGet(i, -4));
+            assertEquals(-1, aa.get(i));
+        }
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(0, aa.decrementAndGet(i));
+            assertEquals(-1, aa.decrementAndGet(i));
+            assertEquals(-2, aa.decrementAndGet(i));
+            assertEquals(-2, aa.get(i));
+        }
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(2, aa.incrementAndGet(i));
+            assertEquals(2, aa.get(i));
+            aa.set(i, -2);
+            assertEquals(-1, aa.incrementAndGet(i));
+            assertEquals(0, aa.incrementAndGet(i));
+            assertEquals(1, aa.incrementAndGet(i));
+            assertEquals(1, aa.get(i));
+        }
+    }
+
+    class Counter extends CheckedRunnable {
+        final AtomicIntegerArray aa;
+        int decs;
+        Counter(AtomicIntegerArray a) { aa = a; }
+        public void realRun() {
+            for (;;) {
+                boolean done = true;
+                for (int i = 0; i < aa.length(); i++) {
+                    int v = aa.get(i);
+                    assertTrue(v >= 0);
+                    if (v != 0) {
+                        done = false;
+                        if (aa.compareAndSet(i, v, v - 1))
+                            decs++;
+                    }
+                }
+                if (done)
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Multiple threads using same array of counters successfully
+     * update a number of times equal to total count
+     */
+    public void testCountingInMultipleThreads() throws InterruptedException {
+        final AtomicIntegerArray aa = new AtomicIntegerArray(SIZE);
+        int countdown = 10000;
+        for (int i = 0; i < SIZE; i++)
+            aa.set(i, countdown);
+        Counter c1 = new Counter(aa);
+        Counter c2 = new Counter(aa);
+        Thread t1 = newStartedThread(c1);
+        Thread t2 = newStartedThread(c2);
+        t1.join();
+        t2.join();
+        assertEquals(c1.decs + c2.decs, SIZE * countdown);
+    }
+
+    /**
+     * a deserialized serialized array holds same values
+     */
+    public void testSerialization() throws Exception {
+        AtomicIntegerArray x = new AtomicIntegerArray(SIZE);
+        for (int i = 0; i < SIZE; i++)
+            x.set(i, -i);
+        AtomicIntegerArray y = serialClone(x);
+        assertNotSame(x, y);
+        assertEquals(x.length(), y.length());
+        for (int i = 0; i < SIZE; i++) {
+            assertEquals(x.get(i), y.get(i));
+        }
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        int[] a = { 17, 3, -42, 99, -7 };
+        AtomicIntegerArray aa = new AtomicIntegerArray(a);
+        assertEquals(Arrays.toString(a), aa.toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerFieldUpdaterTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerFieldUpdaterTest.java
new file mode 100644
index 0000000..0d6f79a
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerFieldUpdaterTest.java
@@ -0,0 +1,364 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase {
+    volatile int x = 0;
+    protected volatile int protectedField;
+    private volatile int privateField;
+    int w;
+    float z;
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicIntegerFieldUpdaterTest.class);
+    }
+
+    // for testing subclass 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());
+            }
+        }
+
+        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));
+        }
+
+        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
+            (AtomicIntegerFieldUpdaterTest.class, fieldName);
+    }
+
+    /**
+     * Construction with non-existent field throws RuntimeException
+     */
+    public void testConstructor() {
+        try {
+            updaterFor("y");
+            shouldThrow();
+        } catch (RuntimeException success) {
+            assertNotNull(success.getCause());
+        }
+    }
+
+    /**
+     * construction with field not of given type throws IllegalArgumentException
+     */
+    public void testConstructor2() {
+        try {
+            updaterFor("z");
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * construction with non-volatile field throws IllegalArgumentException
+     */
+    public void testConstructor3() {
+        try {
+            updaterFor("w");
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    public void testPrivateFieldInSubclass() {
+        AtomicIntegerFieldUpdaterTestSubclass s =
+            new AtomicIntegerFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
+
+    /**
+     * get returns the last value set or assigned
+     */
+    public void testGetSet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.get(this));
+        a.set(this, 2);
+        assertEquals(2, a.get(this));
+        a.set(this, -3);
+        assertEquals(-3, a.get(this));
+    }
+
+    /**
+     * get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.get(this));
+        a.lazySet(this, 2);
+        assertEquals(2, a.get(this));
+        a.lazySet(this, -3);
+        assertEquals(-3, a.get(this));
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 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));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtected() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("protectedField");
+        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));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtectedInSubclass() {
+        AtomicIntegerFieldUpdaterTestSubclass s =
+            new AtomicIntegerFieldUpdaterTestSubclass();
+        s.checkCompareAndSetProtectedSub();
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        x = 1;
+        final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, a.get(this));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        do {} while (!a.weakCompareAndSet(this, 1, 2));
+        do {} while (!a.weakCompareAndSet(this, 2, -4));
+        assertEquals(-4, a.get(this));
+        do {} while (!a.weakCompareAndSet(this, -4, 7));
+        assertEquals(7, a.get(this));
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndSet(this, 0));
+        assertEquals(0, a.getAndSet(this, -10));
+        assertEquals(-10, a.getAndSet(this, 1));
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndAdd(this, 2));
+        assertEquals(3, a.get(this));
+        assertEquals(3, a.getAndAdd(this, -4));
+        assertEquals(-1, a.get(this));
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndDecrement(this));
+        assertEquals(0, a.getAndDecrement(this));
+        assertEquals(-1, a.getAndDecrement(this));
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndIncrement(this));
+        assertEquals(2, a.get(this));
+        a.set(this, -2);
+        assertEquals(-2, a.getAndIncrement(this));
+        assertEquals(-1, a.getAndIncrement(this));
+        assertEquals(0, a.getAndIncrement(this));
+        assertEquals(1, a.get(this));
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(3, a.addAndGet(this, 2));
+        assertEquals(3, a.get(this));
+        assertEquals(-1, a.addAndGet(this, -4));
+        assertEquals(-1, a.get(this));
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(0, a.decrementAndGet(this));
+        assertEquals(-1, a.decrementAndGet(this));
+        assertEquals(-2, a.decrementAndGet(this));
+        assertEquals(-2, a.get(this));
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(2, a.incrementAndGet(this));
+        assertEquals(2, a.get(this));
+        a.set(this, -2);
+        assertEquals(-1, a.incrementAndGet(this));
+        assertEquals(0, a.incrementAndGet(this));
+        assertEquals(1, a.incrementAndGet(this));
+        assertEquals(1, a.get(this));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerTest.java
new file mode 100644
index 0000000..111cd3f
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicIntegerTest.java
@@ -0,0 +1,295 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicIntegerTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicIntegerTest.class);
+    }
+
+    final int[] VALUES = {
+        Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+    };
+
+    /**
+     * constructor initializes to given value
+     */
+    public void testConstructor() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor2() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * get returns the last value set
+     */
+    public void testGetSet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.get());
+        ai.set(2);
+        assertEquals(2, ai.get());
+        ai.set(-3);
+        assertEquals(-3, ai.get());
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.get());
+        ai.lazySet(2);
+        assertEquals(2, ai.get());
+        ai.lazySet(-3);
+        assertEquals(-3, ai.get());
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertTrue(ai.compareAndSet(1, 2));
+        assertTrue(ai.compareAndSet(2, -4));
+        assertEquals(-4, ai.get());
+        assertFalse(ai.compareAndSet(-5, 7));
+        assertEquals(-4, ai.get());
+        assertTrue(ai.compareAndSet(-4, 7));
+        assertEquals(7, ai.get());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicInteger ai = new AtomicInteger(1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, ai.get());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        do {} while (!ai.weakCompareAndSet(1, 2));
+        do {} while (!ai.weakCompareAndSet(2, -4));
+        assertEquals(-4, ai.get());
+        do {} while (!ai.weakCompareAndSet(-4, 7));
+        assertEquals(7, ai.get());
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.getAndSet(0));
+        assertEquals(0, ai.getAndSet(-10));
+        assertEquals(-10, ai.getAndSet(1));
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.getAndAdd(2));
+        assertEquals(3, ai.get());
+        assertEquals(3, ai.getAndAdd(-4));
+        assertEquals(-1, ai.get());
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.getAndDecrement());
+        assertEquals(0, ai.getAndDecrement());
+        assertEquals(-1, ai.getAndDecrement());
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(1, ai.getAndIncrement());
+        assertEquals(2, ai.get());
+        ai.set(-2);
+        assertEquals(-2, ai.getAndIncrement());
+        assertEquals(-1, ai.getAndIncrement());
+        assertEquals(0, ai.getAndIncrement());
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(3, ai.addAndGet(2));
+        assertEquals(3, ai.get());
+        assertEquals(-1, ai.addAndGet(-4));
+        assertEquals(-1, ai.get());
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(0, ai.decrementAndGet());
+        assertEquals(-1, ai.decrementAndGet());
+        assertEquals(-2, ai.decrementAndGet());
+        assertEquals(-2, ai.get());
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicInteger ai = new AtomicInteger(1);
+        assertEquals(2, ai.incrementAndGet());
+        assertEquals(2, ai.get());
+        ai.set(-2);
+        assertEquals(-1, ai.incrementAndGet());
+        assertEquals(0, ai.incrementAndGet());
+        assertEquals(1, ai.incrementAndGet());
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * a deserialized serialized atomic holds same value
+     */
+    public void testSerialization() throws Exception {
+        AtomicInteger x = new AtomicInteger();
+        AtomicInteger y = serialClone(x);
+        assertNotSame(x, y);
+        x.set(22);
+        AtomicInteger z = serialClone(x);
+        assertEquals(22, x.get());
+        assertEquals(0, y.get());
+        assertEquals(22, z.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals("0", ai.toString());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals(Integer.toString(x), ai.toString());
+        }
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals(0, ai.intValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals(x, ai.intValue());
+        }
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals(0L, ai.longValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((long)x, ai.longValue());
+        }
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals(0.0f, ai.floatValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((float)x, ai.floatValue());
+        }
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        AtomicInteger ai = new AtomicInteger();
+        assertEquals(0.0d, ai.doubleValue());
+        for (int x : VALUES) {
+            ai.set(x);
+            assertEquals((double)x, ai.doubleValue());
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicLongArrayTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicLongArrayTest.java
new file mode 100644
index 0000000..c271a06
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicLongArrayTest.java
@@ -0,0 +1,368 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicLongArray;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicLongArrayTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicLongArrayTest.class);
+    }
+
+    /**
+     * constructor creates array of given size with all elements zero
+     */
+    public void testConstructor() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++)
+            assertEquals(0, aa.get(i));
+    }
+
+    /**
+     * constructor with null array throws NPE
+     */
+    public void testConstructor2NPE() {
+        try {
+            long[] a = null;
+            new AtomicLongArray(a);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * constructor with array is of same size and has all elements
+     */
+    public void testConstructor2() {
+        long[] a = { 17L, 3L, -42L, 99L, -7L };
+        AtomicLongArray aa = new AtomicLongArray(a);
+        assertEquals(a.length, aa.length());
+        for (int i = 0; i < a.length; i++)
+            assertEquals(a[i], aa.get(i));
+    }
+
+    /**
+     * get and set for out of bound indices throw IndexOutOfBoundsException
+     */
+    public void testIndexing() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int index : new int[] { -1, SIZE }) {
+            try {
+                aa.get(index);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.set(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.lazySet(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.compareAndSet(index, 1, 2);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.weakCompareAndSet(index, 1, 2);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.getAndAdd(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.addAndGet(index, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * get returns the last value set at index
+     */
+    public void testGetSet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.get(i));
+            aa.set(i, 2);
+            assertEquals(2, aa.get(i));
+            aa.set(i, -3);
+            assertEquals(-3, aa.get(i));
+        }
+    }
+
+    /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.lazySet(i, 1);
+            assertEquals(1, aa.get(i));
+            aa.lazySet(i, 2);
+            assertEquals(2, aa.get(i));
+            aa.lazySet(i, -3);
+            assertEquals(-3, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertTrue(aa.compareAndSet(i, 1, 2));
+            assertTrue(aa.compareAndSet(i, 2, -4));
+            assertEquals(-4, aa.get(i));
+            assertFalse(aa.compareAndSet(i, -5, 7));
+            assertEquals(-4, aa.get(i));
+            assertTrue(aa.compareAndSet(i, -4, 7));
+            assertEquals(7, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws InterruptedException {
+        final AtomicLongArray a = new AtomicLongArray(1);
+        a.set(0, 1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, a.get(0));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            do {} while (!aa.weakCompareAndSet(i, 1, 2));
+            do {} while (!aa.weakCompareAndSet(i, 2, -4));
+            assertEquals(-4, aa.get(i));
+            do {} while (!aa.weakCompareAndSet(i, -4, 7));
+            assertEquals(7, aa.get(i));
+        }
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value at given index
+     */
+    public void testGetAndSet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndSet(i, 0));
+            assertEquals(0, aa.getAndSet(i, -10));
+            assertEquals(-10, aa.getAndSet(i, 1));
+        }
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndAdd(i, 2));
+            assertEquals(3, aa.get(i));
+            assertEquals(3, aa.getAndAdd(i, -4));
+            assertEquals(-1, aa.get(i));
+        }
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndDecrement(i));
+            assertEquals(0, aa.getAndDecrement(i));
+            assertEquals(-1, aa.getAndDecrement(i));
+        }
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(1, aa.getAndIncrement(i));
+            assertEquals(2, aa.get(i));
+            aa.set(i, -2);
+            assertEquals(-2, aa.getAndIncrement(i));
+            assertEquals(-1, aa.getAndIncrement(i));
+            assertEquals(0, aa.getAndIncrement(i));
+            assertEquals(1, aa.get(i));
+        }
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(3, aa.addAndGet(i, 2));
+            assertEquals(3, aa.get(i));
+            assertEquals(-1, aa.addAndGet(i, -4));
+            assertEquals(-1, aa.get(i));
+        }
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(0, aa.decrementAndGet(i));
+            assertEquals(-1, aa.decrementAndGet(i));
+            assertEquals(-2, aa.decrementAndGet(i));
+            assertEquals(-2, aa.get(i));
+        }
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicLongArray aa = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, 1);
+            assertEquals(2, aa.incrementAndGet(i));
+            assertEquals(2, aa.get(i));
+            aa.set(i, -2);
+            assertEquals(-1, aa.incrementAndGet(i));
+            assertEquals(0, aa.incrementAndGet(i));
+            assertEquals(1, aa.incrementAndGet(i));
+            assertEquals(1, aa.get(i));
+        }
+    }
+
+    class Counter extends CheckedRunnable {
+        final AtomicLongArray aa;
+        int decs;
+        Counter(AtomicLongArray a) { aa = a; }
+        public void realRun() {
+            for (;;) {
+                boolean done = true;
+                for (int i = 0; i < aa.length(); i++) {
+                    long v = aa.get(i);
+                    assertTrue(v >= 0);
+                    if (v != 0) {
+                        done = false;
+                        if (aa.compareAndSet(i, v, v - 1))
+                            decs++;
+                    }
+                }
+                if (done)
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Multiple threads using same array of counters successfully
+     * update a number of times equal to total count
+     */
+    public void testCountingInMultipleThreads() throws InterruptedException {
+        final AtomicLongArray aa = new AtomicLongArray(SIZE);
+        long countdown = 10000;
+        for (int i = 0; i < SIZE; i++)
+            aa.set(i, countdown);
+        Counter c1 = new Counter(aa);
+        Counter c2 = new Counter(aa);
+        Thread t1 = newStartedThread(c1);
+        Thread t2 = newStartedThread(c2);
+        t1.join();
+        t2.join();
+        assertEquals(c1.decs + c2.decs, SIZE * countdown);
+    }
+
+    /**
+     * a deserialized serialized array holds same values
+     */
+    public void testSerialization() throws Exception {
+        AtomicLongArray x = new AtomicLongArray(SIZE);
+        for (int i = 0; i < SIZE; i++)
+            x.set(i, -i);
+        AtomicLongArray y = serialClone(x);
+        assertNotSame(x, y);
+        assertEquals(x.length(), y.length());
+        for (int i = 0; i < SIZE; i++) {
+            assertEquals(x.get(i), y.get(i));
+        }
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        long[] a = { 17, 3, -42, 99, -7 };
+        AtomicLongArray aa = new AtomicLongArray(a);
+        assertEquals(Arrays.toString(a), aa.toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicLongFieldUpdaterTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicLongFieldUpdaterTest.java
new file mode 100644
index 0000000..70f0bb9
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicLongFieldUpdaterTest.java
@@ -0,0 +1,364 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicLongFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicLongFieldUpdaterTest extends JSR166TestCase {
+    volatile long x = 0;
+    protected volatile long protectedField;
+    private volatile long privateField;
+    long w;
+    float z;
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicLongFieldUpdaterTest.class);
+    }
+
+    // for testing subclass 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());
+            }
+        }
+
+        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));
+        }
+
+        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
+            (AtomicLongFieldUpdaterTest.class, fieldName);
+    }
+
+    /**
+     * Construction with non-existent field throws RuntimeException
+     */
+    public void testConstructor() {
+        try {
+            updaterFor("y");
+            shouldThrow();
+        } catch (RuntimeException success) {
+            assertNotNull(success.getCause());
+        }
+    }
+
+    /**
+     * construction with field not of given type throws IllegalArgumentException
+     */
+    public void testConstructor2() {
+        try {
+            updaterFor("z");
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * construction with non-volatile field throws IllegalArgumentException
+     */
+    public void testConstructor3() {
+        try {
+            updaterFor("w");
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    public void testPrivateFieldInSubclass() {
+        AtomicLongFieldUpdaterTestSubclass s =
+            new AtomicLongFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
+
+    /**
+     * get returns the last value set or assigned
+     */
+    public void testGetSet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.get(this));
+        a.set(this, 2);
+        assertEquals(2, a.get(this));
+        a.set(this, -3);
+        assertEquals(-3, a.get(this));
+    }
+
+    /**
+     * get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.get(this));
+        a.lazySet(this, 2);
+        assertEquals(2, a.get(this));
+        a.lazySet(this, -3);
+        assertEquals(-3, a.get(this));
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 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));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtected() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("protectedField");
+        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));
+    }
+
+    /**
+     * compareAndSet succeeds in changing protected field value if
+     * equal to expected else fails
+     */
+    public void testCompareAndSetProtectedInSubclass() {
+        AtomicLongFieldUpdaterTestSubclass s =
+            new AtomicLongFieldUpdaterTestSubclass();
+        s.checkCompareAndSetProtectedSub();
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        x = 1;
+        final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, 1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, a.get(this));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        do {} while (!a.weakCompareAndSet(this, 1, 2));
+        do {} while (!a.weakCompareAndSet(this, 2, -4));
+        assertEquals(-4, a.get(this));
+        do {} while (!a.weakCompareAndSet(this, -4, 7));
+        assertEquals(7, a.get(this));
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndSet(this, 0));
+        assertEquals(0, a.getAndSet(this, -10));
+        assertEquals(-10, a.getAndSet(this, 1));
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndAdd(this, 2));
+        assertEquals(3, a.get(this));
+        assertEquals(3, a.getAndAdd(this, -4));
+        assertEquals(-1, a.get(this));
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndDecrement(this));
+        assertEquals(0, a.getAndDecrement(this));
+        assertEquals(-1, a.getAndDecrement(this));
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(1, a.getAndIncrement(this));
+        assertEquals(2, a.get(this));
+        a.set(this, -2);
+        assertEquals(-2, a.getAndIncrement(this));
+        assertEquals(-1, a.getAndIncrement(this));
+        assertEquals(0, a.getAndIncrement(this));
+        assertEquals(1, a.get(this));
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(3, a.addAndGet(this, 2));
+        assertEquals(3, a.get(this));
+        assertEquals(-1, a.addAndGet(this, -4));
+        assertEquals(-1, a.get(this));
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(0, a.decrementAndGet(this));
+        assertEquals(-1, a.decrementAndGet(this));
+        assertEquals(-2, a.decrementAndGet(this));
+        assertEquals(-2, a.get(this));
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
+        a = updaterFor("x");
+        x = 1;
+        assertEquals(2, a.incrementAndGet(this));
+        assertEquals(2, a.get(this));
+        a.set(this, -2);
+        assertEquals(-1, a.incrementAndGet(this));
+        assertEquals(0, a.incrementAndGet(this));
+        assertEquals(1, a.incrementAndGet(this));
+        assertEquals(1, a.get(this));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicLongTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicLongTest.java
new file mode 100644
index 0000000..5b65757
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicLongTest.java
@@ -0,0 +1,298 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicLong;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicLongTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicLongTest.class);
+    }
+
+    final long[] VALUES = {
+        Long.MIN_VALUE,
+        Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
+        Long.MAX_VALUE,
+    };
+
+    /**
+     * constructor initializes to given value
+     */
+    public void testConstructor() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor2() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * get returns the last value set
+     */
+    public void testGetSet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.get());
+        ai.set(2);
+        assertEquals(2, ai.get());
+        ai.set(-3);
+        assertEquals(-3, ai.get());
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.get());
+        ai.lazySet(2);
+        assertEquals(2, ai.get());
+        ai.lazySet(-3);
+        assertEquals(-3, ai.get());
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertTrue(ai.compareAndSet(1, 2));
+        assertTrue(ai.compareAndSet(2, -4));
+        assertEquals(-4, ai.get());
+        assertFalse(ai.compareAndSet(-5, 7));
+        assertEquals(-4, ai.get());
+        assertTrue(ai.compareAndSet(-4, 7));
+        assertEquals(7, ai.get());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicLong ai = new AtomicLong(1);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(2, 3))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(1, 2));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertEquals(3, ai.get());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicLong ai = new AtomicLong(1);
+        do {} while (!ai.weakCompareAndSet(1, 2));
+        do {} while (!ai.weakCompareAndSet(2, -4));
+        assertEquals(-4, ai.get());
+        do {} while (!ai.weakCompareAndSet(-4, 7));
+        assertEquals(7, ai.get());
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.getAndSet(0));
+        assertEquals(0, ai.getAndSet(-10));
+        assertEquals(-10, ai.getAndSet(1));
+    }
+
+    /**
+     * getAndAdd returns previous value and adds given value
+     */
+    public void testGetAndAdd() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.getAndAdd(2));
+        assertEquals(3, ai.get());
+        assertEquals(3, ai.getAndAdd(-4));
+        assertEquals(-1, ai.get());
+    }
+
+    /**
+     * getAndDecrement returns previous value and decrements
+     */
+    public void testGetAndDecrement() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.getAndDecrement());
+        assertEquals(0, ai.getAndDecrement());
+        assertEquals(-1, ai.getAndDecrement());
+    }
+
+    /**
+     * getAndIncrement returns previous value and increments
+     */
+    public void testGetAndIncrement() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(1, ai.getAndIncrement());
+        assertEquals(2, ai.get());
+        ai.set(-2);
+        assertEquals(-2, ai.getAndIncrement());
+        assertEquals(-1, ai.getAndIncrement());
+        assertEquals(0, ai.getAndIncrement());
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * addAndGet adds given value to current, and returns current value
+     */
+    public void testAddAndGet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(3, ai.addAndGet(2));
+        assertEquals(3, ai.get());
+        assertEquals(-1, ai.addAndGet(-4));
+        assertEquals(-1, ai.get());
+    }
+
+    /**
+     * decrementAndGet decrements and returns current value
+     */
+    public void testDecrementAndGet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(0, ai.decrementAndGet());
+        assertEquals(-1, ai.decrementAndGet());
+        assertEquals(-2, ai.decrementAndGet());
+        assertEquals(-2, ai.get());
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndGet() {
+        AtomicLong ai = new AtomicLong(1);
+        assertEquals(2, ai.incrementAndGet());
+        assertEquals(2, ai.get());
+        ai.set(-2);
+        assertEquals(-1, ai.incrementAndGet());
+        assertEquals(0, ai.incrementAndGet());
+        assertEquals(1, ai.incrementAndGet());
+        assertEquals(1, ai.get());
+    }
+
+    /**
+     * a deserialized serialized atomic holds same value
+     */
+    public void testSerialization() throws Exception {
+        AtomicLong x = new AtomicLong();
+        AtomicLong y = serialClone(x);
+        assertNotSame(x, y);
+        x.set(-22);
+        AtomicLong z = serialClone(x);
+        assertNotSame(y, z);
+        assertEquals(-22, x.get());
+        assertEquals(0, y.get());
+        assertEquals(-22, z.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals("0", ai.toString());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals(Long.toString(x), ai.toString());
+        }
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0, ai.intValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((int)x, ai.intValue());
+        }
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0L, ai.longValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals(x, ai.longValue());
+        }
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0.0f, ai.floatValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((float)x, ai.floatValue());
+        }
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        AtomicLong ai = new AtomicLong();
+        assertEquals(0.0d, ai.doubleValue());
+        for (long x : VALUES) {
+            ai.set(x);
+            assertEquals((double)x, ai.doubleValue());
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicMarkableReferenceTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicMarkableReferenceTest.java
new file mode 100644
index 0000000..8fc0369
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicMarkableReferenceTest.java
@@ -0,0 +1,181 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicMarkableReference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicMarkableReferenceTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicMarkableReferenceTest.class);
+    }
+
+    /**
+     * constructor initializes to given reference and mark
+     */
+    public void testConstructor() {
+        AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        assertSame(one, ai.getReference());
+        assertFalse(ai.isMarked());
+        AtomicMarkableReference a2 = new AtomicMarkableReference(null, true);
+        assertNull(a2.getReference());
+        assertTrue(a2.isMarked());
+    }
+
+    /**
+     * get returns the last values of reference and mark set
+     */
+    public void testGetSet() {
+        boolean[] mark = new boolean[1];
+        AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        assertSame(one, ai.getReference());
+        assertFalse(ai.isMarked());
+        assertSame(one, ai.get(mark));
+        assertFalse(mark[0]);
+        ai.set(two, false);
+        assertSame(two, ai.getReference());
+        assertFalse(ai.isMarked());
+        assertSame(two, ai.get(mark));
+        assertFalse(mark[0]);
+        ai.set(one, true);
+        assertSame(one, ai.getReference());
+        assertTrue(ai.isMarked());
+        assertSame(one, ai.get(mark));
+        assertTrue(mark[0]);
+    }
+
+    /**
+     * attemptMark succeeds in single thread
+     */
+    public void testAttemptMark() {
+        boolean[] mark = new boolean[1];
+        AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        assertFalse(ai.isMarked());
+        assertTrue(ai.attemptMark(one, true));
+        assertTrue(ai.isMarked());
+        assertSame(one, ai.get(mark));
+        assertTrue(mark[0]);
+    }
+
+    /**
+     * compareAndSet succeeds in changing values if equal to expected reference
+     * and mark else fails
+     */
+    public void testCompareAndSet() {
+        boolean[] mark = new boolean[1];
+        AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        assertSame(one, ai.get(mark));
+        assertFalse(ai.isMarked());
+        assertFalse(mark[0]);
+
+        assertTrue(ai.compareAndSet(one, two, false, false));
+        assertSame(two, ai.get(mark));
+        assertFalse(mark[0]);
+
+        assertTrue(ai.compareAndSet(two, m3, false, true));
+        assertSame(m3, ai.get(mark));
+        assertTrue(mark[0]);
+
+        assertFalse(ai.compareAndSet(two, m3, true, true));
+        assertSame(m3, ai.get(mark));
+        assertTrue(mark[0]);
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for reference value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three, false, false))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two, false, false));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(three, ai.getReference());
+        assertFalse(ai.isMarked());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for mark value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads2() throws Exception {
+        final AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(one, one, true, false))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, one, false, true));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(one, ai.getReference());
+        assertFalse(ai.isMarked());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing values when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        boolean[] mark = new boolean[1];
+        AtomicMarkableReference ai = new AtomicMarkableReference(one, false);
+        assertSame(one, ai.get(mark));
+        assertFalse(ai.isMarked());
+        assertFalse(mark[0]);
+
+        do {} while (!ai.weakCompareAndSet(one, two, false, false));
+        assertSame(two, ai.get(mark));
+        assertFalse(mark[0]);
+
+        do {} while (!ai.weakCompareAndSet(two, m3, false, true));
+        assertSame(m3, ai.get(mark));
+        assertTrue(mark[0]);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java
new file mode 100644
index 0000000..6e078f8
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceArrayTest.java
@@ -0,0 +1,248 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicReferenceArray;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicReferenceArrayTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicReferenceArrayTest.class);
+    }
+
+    /**
+     * constructor creates array of given size with all elements null
+     */
+    public void testConstructor() {
+        AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<>(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            assertNull(aa.get(i));
+        }
+    }
+
+    /**
+     * constructor with null array throws NPE
+     */
+    public void testConstructor2NPE() {
+        try {
+            Integer[] a = null;
+            new AtomicReferenceArray<Integer>(a);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * constructor with array is of same size and has all elements
+     */
+    public void testConstructor2() {
+        Integer[] a = { two, one, three, four, seven };
+        AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<>(a);
+        assertEquals(a.length, aa.length());
+        for (int i = 0; i < a.length; i++)
+            assertEquals(a[i], aa.get(i));
+    }
+
+    /**
+     * Initialize AtomicReferenceArray<Class> with SubClass[]
+     */
+    public void testConstructorSubClassArray() {
+        Integer[] a = { two, one, three, four, seven };
+        AtomicReferenceArray<Number> aa = new AtomicReferenceArray<Number>(a);
+        assertEquals(a.length, aa.length());
+        for (int i = 0; i < a.length; i++) {
+            assertSame(a[i], aa.get(i));
+            Long x = Long.valueOf(i);
+            aa.set(i, x);
+            assertSame(x, aa.get(i));
+        }
+    }
+
+    /**
+     * get and set for out of bound indices throw IndexOutOfBoundsException
+     */
+    public void testIndexing() {
+        AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<>(SIZE);
+        for (int index : new int[] { -1, SIZE }) {
+            try {
+                aa.get(index);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.set(index, null);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.lazySet(index, null);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.compareAndSet(index, null, null);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+            try {
+                aa.weakCompareAndSet(index, null, null);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * get returns the last value set at index
+     */
+    public void testGetSet() {
+        AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, one);
+            assertSame(one, aa.get(i));
+            aa.set(i, two);
+            assertSame(two, aa.get(i));
+            aa.set(i, m3);
+            assertSame(m3, aa.get(i));
+        }
+    }
+
+    /**
+     * get returns the last value lazySet at index by same thread
+     */
+    public void testGetLazySet() {
+        AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.lazySet(i, one);
+            assertSame(one, aa.get(i));
+            aa.lazySet(i, two);
+            assertSame(two, aa.get(i));
+            aa.lazySet(i, m3);
+            assertSame(m3, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, one);
+            assertTrue(aa.compareAndSet(i, one, two));
+            assertTrue(aa.compareAndSet(i, two, m4));
+            assertSame(m4, aa.get(i));
+            assertFalse(aa.compareAndSet(i, m5, seven));
+            assertSame(m4, aa.get(i));
+            assertTrue(aa.compareAndSet(i, m4, seven));
+            assertSame(seven, aa.get(i));
+        }
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws InterruptedException {
+        final AtomicReferenceArray a = new AtomicReferenceArray(1);
+        a.set(0, one);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(0, two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(0, one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(three, a.get(0));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, one);
+            do {} while (!aa.weakCompareAndSet(i, one, two));
+            do {} while (!aa.weakCompareAndSet(i, two, m4));
+            assertSame(m4, aa.get(i));
+            do {} while (!aa.weakCompareAndSet(i, m4, seven));
+            assertSame(seven, aa.get(i));
+        }
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value at given index
+     */
+    public void testGetAndSet() {
+        AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            aa.set(i, one);
+            assertSame(one, aa.getAndSet(i, zero));
+            assertSame(zero, aa.getAndSet(i, m10));
+            assertSame(m10, aa.getAndSet(i, one));
+        }
+    }
+
+    /**
+     * a deserialized serialized array holds same values
+     */
+    public void testSerialization() throws Exception {
+        AtomicReferenceArray x = new AtomicReferenceArray(SIZE);
+        for (int i = 0; i < SIZE; i++) {
+            x.set(i, new Integer(-i));
+        }
+        AtomicReferenceArray y = serialClone(x);
+        assertNotSame(x, y);
+        assertEquals(x.length(), y.length());
+        for (int i = 0; i < SIZE; i++) {
+            assertEquals(x.get(i), y.get(i));
+        }
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        Integer[] a = { two, one, three, four, seven };
+        AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<>(a);
+        assertEquals(Arrays.toString(a), aa.toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceFieldUpdaterTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceFieldUpdaterTest.java
new file mode 100644
index 0000000..2517842
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceFieldUpdaterTest.java
@@ -0,0 +1,266 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicReferenceFieldUpdaterTest extends JSR166TestCase {
+    volatile Integer x = null;
+    protected volatile Integer protectedField;
+    private volatile Integer privateField;
+    Object z;
+    Integer w;
+    volatile int i;
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicReferenceFieldUpdaterTest.class);
+    }
+
+    // for testing subclass 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());
+            }
+        }
+
+        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));
+        }
+
+        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
+            (AtomicReferenceFieldUpdaterTest.class, Integer.class, fieldName);
+    }
+
+    /**
+     * Construction with non-existent field throws RuntimeException
+     */
+    public void testConstructor() {
+        try {
+            updaterFor("y");
+            shouldThrow();
+        } catch (RuntimeException success) {
+            assertNotNull(success.getCause());
+        }
+    }
+
+    /**
+     * construction with field not of given type throws ClassCastException
+     */
+    public void testConstructor2() {
+        try {
+            updaterFor("z");
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * Constructor with non-volatile field throws IllegalArgumentException
+     */
+    public void testConstructor3() {
+        try {
+            updaterFor("w");
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor with non-reference field throws ClassCastException
+     */
+    public void testConstructor4() {
+        try {
+            updaterFor("i");
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * construction using private field from subclass throws RuntimeException
+     */
+    public void testPrivateFieldInSubclass() {
+        AtomicReferenceFieldUpdaterTestSubclass s =
+            new AtomicReferenceFieldUpdaterTestSubclass();
+        s.checkPrivateAccess();
+    }
+
+    /**
+     * construction from unrelated class; package access is allowed,
+     * private access is not
+     */
+    public void testUnrelatedClassAccess() {
+        new UnrelatedClass().checkPackageAccess(this);
+        new UnrelatedClass().checkPrivateAccess(this);
+    }
+
+    /**
+     * get returns the last value set or assigned
+     */
+    public void testGetSet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+        x = one;
+        assertSame(one, a.get(this));
+        a.set(this, two);
+        assertSame(two, a.get(this));
+        a.set(this, m3);
+        assertSame(m3, a.get(this));
+    }
+
+    /**
+     * get returns the last value lazySet by same thread
+     */
+    public void testGetLazySet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+        x = one;
+        assertSame(one, a.get(this));
+        a.lazySet(this, two);
+        assertSame(two, a.get(this));
+        a.lazySet(this, m3);
+        assertSame(m3, a.get(this));
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+        x = 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));
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        x = one;
+        final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(a.compareAndSet(this, one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(three, a.get(this));
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+        x = one;
+        do {} while (!a.weakCompareAndSet(this, one, two));
+        do {} while (!a.weakCompareAndSet(this, two, m4));
+        assertSame(m4, a.get(this));
+        do {} while (!a.weakCompareAndSet(this, m4, seven));
+        assertSame(seven, a.get(this));
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
+        a = updaterFor("x");
+        x = one;
+        assertSame(one, a.getAndSet(this, zero));
+        assertSame(zero, a.getAndSet(this, m10));
+        assertSame(m10, a.getAndSet(this, 1));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceTest.java
new file mode 100644
index 0000000..1c5e303
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicReferenceTest.java
@@ -0,0 +1,171 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicReference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicReferenceTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicReferenceTest.class);
+    }
+
+    /**
+     * constructor initializes to given value
+     */
+    public void testConstructor() {
+        AtomicReference ai = new AtomicReference(one);
+        assertSame(one, ai.get());
+    }
+
+    /**
+     * default constructed initializes to null
+     */
+    public void testConstructor2() {
+        AtomicReference ai = new AtomicReference();
+        assertNull(ai.get());
+    }
+
+    /**
+     * get returns the last value set
+     */
+    public void testGetSet() {
+        AtomicReference ai = new AtomicReference(one);
+        assertSame(one, ai.get());
+        ai.set(two);
+        assertSame(two, ai.get());
+        ai.set(m3);
+        assertSame(m3, ai.get());
+    }
+
+    /**
+     * get returns the last value lazySet in same thread
+     */
+    public void testGetLazySet() {
+        AtomicReference ai = new AtomicReference(one);
+        assertSame(one, ai.get());
+        ai.lazySet(two);
+        assertSame(two, ai.get());
+        ai.lazySet(m3);
+        assertSame(m3, ai.get());
+    }
+
+    /**
+     * compareAndSet succeeds in changing value if equal to expected else fails
+     */
+    public void testCompareAndSet() {
+        AtomicReference ai = new AtomicReference(one);
+        assertTrue(ai.compareAndSet(one, two));
+        assertTrue(ai.compareAndSet(two, m4));
+        assertSame(m4, ai.get());
+        assertFalse(ai.compareAndSet(m5, seven));
+        assertSame(m4, ai.get());
+        assertTrue(ai.compareAndSet(m4, seven));
+        assertSame(seven, ai.get());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicReference ai = new AtomicReference(one);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(three, ai.get());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing value when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        AtomicReference ai = new AtomicReference(one);
+        do {} while (!ai.weakCompareAndSet(one, two));
+        do {} while (!ai.weakCompareAndSet(two, m4));
+        assertSame(m4, ai.get());
+        do {} while (!ai.weakCompareAndSet(m4, seven));
+        assertSame(seven, ai.get());
+    }
+
+    /**
+     * getAndSet returns previous value and sets to given value
+     */
+    public void testGetAndSet() {
+        AtomicReference ai = new AtomicReference(one);
+        assertSame(one, ai.getAndSet(zero));
+        assertSame(zero, ai.getAndSet(m10));
+        assertSame(m10, ai.getAndSet(one));
+    }
+
+    /**
+     * a deserialized serialized atomic holds same value
+     */
+    public void testSerialization() throws Exception {
+        AtomicReference x = new AtomicReference();
+        AtomicReference y = serialClone(x);
+        assertNotSame(x, y);
+        x.set(one);
+        AtomicReference z = serialClone(x);
+        assertNotSame(y, z);
+        assertEquals(one, x.get());
+        assertEquals(null, y.get());
+        assertEquals(one, z.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        AtomicReference<Integer> ai = new AtomicReference<>(one);
+        assertEquals(one.toString(), ai.toString());
+        ai.set(two);
+        assertEquals(two.toString(), ai.toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/AtomicStampedReferenceTest.java b/ojluni/src/test/java/util/concurrent/tck/AtomicStampedReferenceTest.java
new file mode 100644
index 0000000..244bfed
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/AtomicStampedReferenceTest.java
@@ -0,0 +1,181 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.concurrent.atomic.AtomicStampedReference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class AtomicStampedReferenceTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(AtomicStampedReferenceTest.class);
+    }
+
+    /**
+     * constructor initializes to given reference and stamp
+     */
+    public void testConstructor() {
+        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        assertSame(one, ai.getReference());
+        assertEquals(0, ai.getStamp());
+        AtomicStampedReference a2 = new AtomicStampedReference(null, 1);
+        assertNull(a2.getReference());
+        assertEquals(1, a2.getStamp());
+    }
+
+    /**
+     * get returns the last values of reference and stamp set
+     */
+    public void testGetSet() {
+        int[] mark = new int[1];
+        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        assertSame(one, ai.getReference());
+        assertEquals(0, ai.getStamp());
+        assertSame(one, ai.get(mark));
+        assertEquals(0, mark[0]);
+        ai.set(two, 0);
+        assertSame(two, ai.getReference());
+        assertEquals(0, ai.getStamp());
+        assertSame(two, ai.get(mark));
+        assertEquals(0, mark[0]);
+        ai.set(one, 1);
+        assertSame(one, ai.getReference());
+        assertEquals(1, ai.getStamp());
+        assertSame(one, ai.get(mark));
+        assertEquals(1, mark[0]);
+    }
+
+    /**
+     * attemptStamp succeeds in single thread
+     */
+    public void testAttemptStamp() {
+        int[] mark = new int[1];
+        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        assertEquals(0, ai.getStamp());
+        assertTrue(ai.attemptStamp(one, 1));
+        assertEquals(1, ai.getStamp());
+        assertSame(one, ai.get(mark));
+        assertEquals(1, mark[0]);
+    }
+
+    /**
+     * compareAndSet succeeds in changing values if equal to expected reference
+     * and stamp else fails
+     */
+    public void testCompareAndSet() {
+        int[] mark = new int[1];
+        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        assertSame(one, ai.get(mark));
+        assertEquals(0, ai.getStamp());
+        assertEquals(0, mark[0]);
+
+        assertTrue(ai.compareAndSet(one, two, 0, 0));
+        assertSame(two, ai.get(mark));
+        assertEquals(0, mark[0]);
+
+        assertTrue(ai.compareAndSet(two, m3, 0, 1));
+        assertSame(m3, ai.get(mark));
+        assertEquals(1, mark[0]);
+
+        assertFalse(ai.compareAndSet(two, m3, 1, 1));
+        assertSame(m3, ai.get(mark));
+        assertEquals(1, mark[0]);
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for reference value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads() throws Exception {
+        final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(two, three, 0, 0))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, two, 0, 0));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(three, ai.getReference());
+        assertEquals(0, ai.getStamp());
+    }
+
+    /**
+     * compareAndSet in one thread enables another waiting for stamp value
+     * to succeed
+     */
+    public void testCompareAndSetInMultipleThreads2() throws Exception {
+        final AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                while (!ai.compareAndSet(one, one, 1, 2))
+                    Thread.yield();
+            }});
+
+        t.start();
+        assertTrue(ai.compareAndSet(one, one, 0, 1));
+        t.join(LONG_DELAY_MS);
+        assertFalse(t.isAlive());
+        assertSame(one, ai.getReference());
+        assertEquals(2, ai.getStamp());
+    }
+
+    /**
+     * repeated weakCompareAndSet succeeds in changing values when equal
+     * to expected
+     */
+    public void testWeakCompareAndSet() {
+        int[] mark = new int[1];
+        AtomicStampedReference ai = new AtomicStampedReference(one, 0);
+        assertSame(one, ai.get(mark));
+        assertEquals(0, ai.getStamp());
+        assertEquals(0, mark[0]);
+
+        do {} while (!ai.weakCompareAndSet(one, two, 0, 0));
+        assertSame(two, ai.get(mark));
+        assertEquals(0, mark[0]);
+
+        do {} while (!ai.weakCompareAndSet(two, m3, 0, 1));
+        assertSame(m3, ai.get(mark));
+        assertEquals(1, mark[0]);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/BlockingQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/BlockingQueueTest.java
new file mode 100644
index 0000000..6aab850
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/BlockingQueueTest.java
@@ -0,0 +1,404 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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/
+ *
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Contains "contract" tests applicable to all BlockingQueue implementations.
+ */
+public abstract class BlockingQueueTest extends JSR166TestCase {
+    /*
+     * This is the start of an attempt to refactor the tests for the
+     * various related implementations of related interfaces without
+     * too much duplicated code.  junit does not really support such
+     * testing.  Here subclasses of TestCase not only contain tests,
+     * but also configuration information that describes the
+     * implementation class, most importantly how to instantiate
+     * instances.
+     */
+
+    /** Like suite(), but non-static */
+    public Test testSuite() {
+        // TODO: filter the returned tests using the configuration
+        // information provided by the subclass via protected methods.
+        return new TestSuite(this.getClass());
+    }
+
+    //----------------------------------------------------------------
+    // Configuration methods
+    //----------------------------------------------------------------
+
+    /** Returns an empty instance of the implementation class. */
+    protected abstract BlockingQueue emptyCollection();
+
+    /**
+     * Returns an element suitable for insertion in the collection.
+     * Override for collections with unusual element types.
+     */
+    protected Object makeElement(int i) {
+        return Integer.valueOf(i);
+    }
+
+    //----------------------------------------------------------------
+    // Tests
+    //----------------------------------------------------------------
+
+    /**
+     * offer(null) throws NullPointerException
+     */
+    public void testOfferNull() {
+        final Queue q = emptyCollection();
+        try {
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(null) throws NullPointerException
+     */
+    public void testAddNull() {
+        final Collection q = emptyCollection();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * timed offer(null) throws NullPointerException
+     */
+    public void testTimedOfferNull() throws InterruptedException {
+        final BlockingQueue q = emptyCollection();
+        long startTime = System.nanoTime();
+        try {
+            q.offer(null, LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+    }
+
+    /**
+     * put(null) throws NullPointerException
+     */
+    public void testPutNull() throws InterruptedException {
+        final BlockingQueue q = emptyCollection();
+        try {
+            q.put(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null) throws NullPointerException
+     */
+    public void testAddAllNull() throws InterruptedException {
+        final Collection q = emptyCollection();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NullPointerException
+     */
+    public void testAddAllNullElements() {
+        final Collection q = emptyCollection();
+        final Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            q.addAll(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray(null) throws NullPointerException
+     */
+    public void testToArray_NullArray() {
+        final Collection q = emptyCollection();
+        try {
+            q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * drainTo(null) throws NullPointerException
+     */
+    public void testDrainToNull() {
+        final BlockingQueue q = emptyCollection();
+        try {
+            q.drainTo(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * drainTo(this) throws IllegalArgumentException
+     */
+    public void testDrainToSelf() {
+        final BlockingQueue q = emptyCollection();
+        try {
+            q.drainTo(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * drainTo(null, n) throws NullPointerException
+     */
+    public void testDrainToNullN() {
+        final BlockingQueue q = emptyCollection();
+        try {
+            q.drainTo(null, 0);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * drainTo(this, n) throws IllegalArgumentException
+     */
+    public void testDrainToSelfN() {
+        final BlockingQueue q = emptyCollection();
+        try {
+            q.drainTo(q, 0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * drainTo(c, n) returns 0 and does nothing when n <= 0
+     */
+    public void testDrainToNonPositiveMaxElements() {
+        final BlockingQueue q = emptyCollection();
+        final int[] ns = { 0, -1, -42, Integer.MIN_VALUE };
+        for (int n : ns)
+            assertEquals(0, q.drainTo(new ArrayList(), n));
+        if (q.remainingCapacity() > 0) {
+            // Not SynchronousQueue, that is
+            Object one = makeElement(1);
+            q.add(one);
+            ArrayList c = new ArrayList();
+            for (int n : ns)
+                assertEquals(0, q.drainTo(new ArrayList(), n));
+            assertEquals(1, q.size());
+            assertSame(one, q.poll());
+            assertTrue(c.isEmpty());
+        }
+    }
+
+    /**
+     * timed poll before a delayed offer times out; after offer succeeds;
+     * on interruption throws
+     */
+    public void testTimedPollWithOffer() throws InterruptedException {
+        final BlockingQueue q = emptyCollection();
+        final CheckedBarrier barrier = new CheckedBarrier(2);
+        final Object zero = makeElement(0);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+                barrier.await();
+
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                barrier.await();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        barrier.await();
+        long startTime = System.nanoTime();
+        assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+        barrier.await();
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take() blocks interruptibly when empty
+     */
+    public void testTakeFromEmptyBlocksInterruptibly() {
+        final BlockingQueue q = emptyCollection();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                threadStarted.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(threadStarted);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take() throws InterruptedException immediately if interrupted
+     * before waiting
+     */
+    public void testTakeFromEmptyAfterInterrupt() {
+        final BlockingQueue q = emptyCollection();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * timed poll() blocks interruptibly when empty
+     */
+    public void testTimedPollFromEmptyBlocksInterruptibly() {
+        final BlockingQueue q = emptyCollection();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                threadStarted.countDown();
+                try {
+                    q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(threadStarted);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed poll() throws InterruptedException immediately if
+     * interrupted before waiting
+     */
+    public void testTimedPollFromEmptyAfterInterrupt() {
+        final BlockingQueue q = emptyCollection();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                try {
+                    q.poll(2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     * TODO: move to superclass CollectionTest.java
+     */
+    public void testRemoveElement() {
+        final BlockingQueue q = emptyCollection();
+        final int size = Math.min(q.remainingCapacity(), SIZE);
+        final Object[] elts = new Object[size];
+        assertFalse(q.contains(makeElement(99)));
+        assertFalse(q.remove(makeElement(99)));
+        checkEmpty(q);
+        for (int i = 0; i < size; i++)
+            q.add(elts[i] = makeElement(i));
+        for (int i = 1; i < size; i += 2) {
+            for (int pass = 0; pass < 2; pass++) {
+                assertEquals((pass == 0), q.contains(elts[i]));
+                assertEquals((pass == 0), q.remove(elts[i]));
+                assertFalse(q.contains(elts[i]));
+                assertTrue(q.contains(elts[i - 1]));
+                if (i < size - 1)
+                    assertTrue(q.contains(elts[i + 1]));
+            }
+        }
+        if (size > 0)
+            assertTrue(q.contains(elts[0]));
+        for (int i = size - 2; i >= 0; i -= 2) {
+            assertTrue(q.contains(elts[i]));
+            assertFalse(q.contains(elts[i + 1]));
+            assertTrue(q.remove(elts[i]));
+            assertFalse(q.contains(elts[i]));
+            assertFalse(q.remove(elts[i + 1]));
+            assertFalse(q.contains(elts[i + 1]));
+        }
+        checkEmpty(q);
+    }
+
+    /** For debugging. */
+    public void XXXXtestFails() {
+        fail(emptyCollection().getClass().toString());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/Collection8Test.java b/ojluni/src/test/java/util/concurrent/tck/Collection8Test.java
new file mode 100644
index 0000000..d95bbe3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/Collection8Test.java
@@ -0,0 +1,924 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
+import java.util.Deque;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Spliterator;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import junit.framework.Test;
+
+/**
+ * Contains tests applicable to all jdk8+ Collection implementations.
+ * An extension of CollectionTest.
+ */
+// Android-changed: Mark this abstract to prevent scanned by the JUnit directly. http://b/181312360
+// public class Collection8Test extends JSR166TestCase {
+public abstract class Collection8Test extends JSR166TestCase {
+    final CollectionImplementation impl;
+
+    /** Tests are parameterized by a Collection implementation. */
+    Collection8Test(CollectionImplementation impl, String methodName) {
+        super(methodName);
+        this.impl = impl;
+    }
+
+    // BEGIN Android-added: Mark Collection8Test abstract. http://b/181312360
+    static class AndroidCollection8Test extends Collection8Test {
+
+        AndroidCollection8Test(CollectionImplementation impl, String methodName) {
+            super(impl, methodName);
+        }
+    }
+    // END Android-added: Mark Collection8Test abstract. http://b/181312360
+
+    public static Test testSuite(CollectionImplementation impl) {
+        // Android-changed: Prevent scanned by the JUnit directly. http://b/181312360
+        // return parameterizedTestSuite(Collection8Test.class,
+        return parameterizedTestSuite(AndroidCollection8Test.class,
+                                      CollectionImplementation.class,
+                                      impl);
+    }
+
+    Object bomb() {
+        return new Object() {
+                public boolean equals(Object x) { throw new AssertionError(); }
+                public int hashCode() { throw new AssertionError(); }
+            };
+    }
+
+    /** Checks properties of empty collections. */
+    public void testEmptyMeansEmpty() throws Throwable {
+        Collection c = impl.emptyCollection();
+        emptyMeansEmpty(c);
+
+        if (c instanceof java.io.Serializable) {
+            try {
+                emptyMeansEmpty(serialClonePossiblyFailing(c));
+            } catch (java.io.NotSerializableException ex) {
+                // excusable when we have a serializable wrapper around
+                // a non-serializable collection, as can happen with:
+                // Vector.subList() => wrapped AbstractList$RandomAccessSubList
+                if (testImplementationDetails
+                    && (! c.getClass().getName().matches(
+                                "java.util.Collections.*")))
+                    throw ex;
+            }
+        }
+
+        Collection clone = cloneableClone(c);
+        if (clone != null)
+            emptyMeansEmpty(clone);
+    }
+
+    void emptyMeansEmpty(Collection c) throws InterruptedException {
+        assertTrue(c.isEmpty());
+        assertEquals(0, c.size());
+        assertEquals("[]", c.toString());
+        {
+            Object[] a = c.toArray();
+            assertEquals(0, a.length);
+            assertSame(Object[].class, a.getClass());
+        }
+        {
+            Object[] a = new Object[0];
+            assertSame(a, c.toArray(a));
+        }
+        {
+            Integer[] a = new Integer[0];
+            assertSame(a, c.toArray(a));
+        }
+        {
+            Integer[] a = { 1, 2, 3};
+            assertSame(a, c.toArray(a));
+            assertNull(a[0]);
+            assertSame(2, a[1]);
+            assertSame(3, a[2]);
+        }
+        assertIteratorExhausted(c.iterator());
+        Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        c.forEach(alwaysThrows);
+        c.iterator().forEachRemaining(alwaysThrows);
+        c.spliterator().forEachRemaining(alwaysThrows);
+        assertFalse(c.spliterator().tryAdvance(alwaysThrows));
+        if (c.spliterator().hasCharacteristics(Spliterator.SIZED))
+            assertEquals(0, c.spliterator().estimateSize());
+        assertFalse(c.contains(bomb()));
+        assertFalse(c.remove(bomb()));
+        if (c instanceof Queue) {
+            Queue q = (Queue) c;
+            assertNull(q.peek());
+            assertNull(q.poll());
+        }
+        if (c instanceof Deque) {
+            Deque d = (Deque) c;
+            assertNull(d.peekFirst());
+            assertNull(d.peekLast());
+            assertNull(d.pollFirst());
+            assertNull(d.pollLast());
+            assertIteratorExhausted(d.descendingIterator());
+            d.descendingIterator().forEachRemaining(alwaysThrows);
+            assertFalse(d.removeFirstOccurrence(bomb()));
+            assertFalse(d.removeLastOccurrence(bomb()));
+        }
+        if (c instanceof BlockingQueue) {
+            BlockingQueue q = (BlockingQueue) c;
+            assertNull(q.poll(0L, MILLISECONDS));
+        }
+        if (c instanceof BlockingDeque) {
+            BlockingDeque q = (BlockingDeque) c;
+            assertNull(q.pollFirst(0L, MILLISECONDS));
+            assertNull(q.pollLast(0L, MILLISECONDS));
+        }
+    }
+
+    public void testNullPointerExceptions() throws InterruptedException {
+        Collection c = impl.emptyCollection();
+        assertThrows(
+            NullPointerException.class,
+            () -> c.addAll(null),
+            () -> c.containsAll(null),
+            () -> c.retainAll(null),
+            () -> c.removeAll(null),
+            () -> c.removeIf(null),
+            () -> c.forEach(null),
+            () -> c.iterator().forEachRemaining(null),
+            () -> c.spliterator().forEachRemaining(null),
+            () -> c.spliterator().tryAdvance(null),
+            () -> c.toArray(null));
+
+        if (!impl.permitsNulls()) {
+            assertThrows(
+                NullPointerException.class,
+                () -> c.add(null));
+        }
+        if (!impl.permitsNulls() && c instanceof Queue) {
+            Queue q = (Queue) c;
+            assertThrows(
+                NullPointerException.class,
+                () -> q.offer(null));
+        }
+        if (!impl.permitsNulls() && c instanceof Deque) {
+            Deque d = (Deque) c;
+            assertThrows(
+                NullPointerException.class,
+                () -> d.addFirst(null),
+                () -> d.addLast(null),
+                () -> d.offerFirst(null),
+                () -> d.offerLast(null),
+                () -> d.push(null),
+                () -> d.descendingIterator().forEachRemaining(null));
+        }
+        if (c instanceof BlockingQueue) {
+            BlockingQueue q = (BlockingQueue) c;
+            assertThrows(
+                NullPointerException.class,
+                () -> {
+                    try { q.offer(null, 1L, HOURS); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }},
+                () -> {
+                    try { q.put(null); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }});
+        }
+        if (c instanceof BlockingDeque) {
+            BlockingDeque q = (BlockingDeque) c;
+            assertThrows(
+                NullPointerException.class,
+                () -> {
+                    try { q.offerFirst(null, 1L, HOURS); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }},
+                () -> {
+                    try { q.offerLast(null, 1L, HOURS); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }},
+                () -> {
+                    try { q.putFirst(null); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }},
+                () -> {
+                    try { q.putLast(null); }
+                    catch (InterruptedException ex) {
+                        throw new AssertionError(ex);
+                    }});
+        }
+    }
+
+    public void testNoSuchElementExceptions() {
+        Collection c = impl.emptyCollection();
+        assertThrows(
+            NoSuchElementException.class,
+            () -> c.iterator().next());
+
+        if (c instanceof Queue) {
+            Queue q = (Queue) c;
+            assertThrows(
+                NoSuchElementException.class,
+                () -> q.element(),
+                () -> q.remove());
+        }
+        if (c instanceof Deque) {
+            Deque d = (Deque) c;
+            assertThrows(
+                NoSuchElementException.class,
+                () -> d.getFirst(),
+                () -> d.getLast(),
+                () -> d.removeFirst(),
+                () -> d.removeLast(),
+                () -> d.pop(),
+                () -> d.descendingIterator().next());
+        }
+    }
+
+    public void testRemoveIf() {
+        Collection c = impl.emptyCollection();
+        boolean ordered =
+            c.spliterator().hasCharacteristics(Spliterator.ORDERED);
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+        AtomicReference threwAt = new AtomicReference(null);
+        List orig = rnd.nextBoolean()
+            ? new ArrayList(c)
+            : Arrays.asList(c.toArray());
+
+        // Merely creating an iterator can change ArrayBlockingQueue behavior
+        Iterator it = rnd.nextBoolean() ? c.iterator() : null;
+
+        ArrayList survivors = new ArrayList();
+        ArrayList accepts = new ArrayList();
+        ArrayList rejects = new ArrayList();
+
+        Predicate randomPredicate = e -> {
+            assertNull(threwAt.get());
+            switch (rnd.nextInt(3)) {
+            case 0: accepts.add(e); return true;
+            case 1: rejects.add(e); return false;
+            case 2: threwAt.set(e); throw new ArithmeticException();
+            default: throw new AssertionError();
+            }
+        };
+        try {
+            try {
+                boolean modified = c.removeIf(randomPredicate);
+                assertNull(threwAt.get());
+                assertEquals(modified, accepts.size() > 0);
+                assertEquals(modified, rejects.size() != n);
+                assertEquals(accepts.size() + rejects.size(), n);
+                if (ordered) {
+                    assertEquals(rejects,
+                                 Arrays.asList(c.toArray()));
+                } else {
+                    assertEquals(new HashSet(rejects),
+                                 new HashSet(Arrays.asList(c.toArray())));
+                }
+            } catch (ArithmeticException ok) {
+                assertNotNull(threwAt.get());
+                assertTrue(c.contains(threwAt.get()));
+            }
+            if (it != null && impl.isConcurrent())
+                // check for weakly consistent iterator
+                while (it.hasNext()) assertTrue(orig.contains(it.next()));
+            switch (rnd.nextInt(4)) {
+            case 0: survivors.addAll(c); break;
+            case 1: survivors.addAll(Arrays.asList(c.toArray())); break;
+            case 2: c.forEach(survivors::add); break;
+            case 3: for (Object e : c) survivors.add(e); break;
+            }
+            assertTrue(orig.containsAll(accepts));
+            assertTrue(orig.containsAll(rejects));
+            assertTrue(orig.containsAll(survivors));
+            assertTrue(orig.containsAll(c));
+            assertTrue(c.containsAll(rejects));
+            assertTrue(c.containsAll(survivors));
+            assertTrue(survivors.containsAll(rejects));
+            if (threwAt.get() == null) {
+                assertEquals(n - accepts.size(), c.size());
+                for (Object x : accepts) assertFalse(c.contains(x));
+            } else {
+                // Two acceptable behaviors: entire removeIf call is one
+                // transaction, or each element processed is one transaction.
+                assertTrue(n == c.size() || n == c.size() + accepts.size());
+                int k = 0;
+                for (Object x : accepts) if (c.contains(x)) k++;
+                assertTrue(k == accepts.size() || k == 0);
+            }
+        } catch (Throwable ex) {
+            System.err.println(impl.klazz());
+            // c is at risk of corruption if we got here, so be lenient
+            try { System.err.printf("c=%s%n", c); }
+            catch (Throwable t) { t.printStackTrace(); }
+            System.err.printf("n=%d%n", n);
+            System.err.printf("orig=%s%n", orig);
+            System.err.printf("accepts=%s%n", accepts);
+            System.err.printf("rejects=%s%n", rejects);
+            System.err.printf("survivors=%s%n", survivors);
+            System.err.printf("threwAt=%s%n", threwAt.get());
+            throw ex;
+        }
+    }
+
+    /**
+     * All elements removed in the middle of CONCURRENT traversal.
+     */
+    public void testElementRemovalDuringTraversal() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        ArrayList copy = new ArrayList();
+        for (int i = 0; i < n; i++) {
+            Object x = impl.makeElement(i);
+            copy.add(x);
+            c.add(x);
+        }
+        ArrayList iterated = new ArrayList();
+        ArrayList spliterated = new ArrayList();
+        Spliterator s = c.spliterator();
+        Iterator it = c.iterator();
+        for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
+            assertTrue(s.tryAdvance(spliterated::add));
+            if (rnd.nextBoolean()) assertTrue(it.hasNext());
+            iterated.add(it.next());
+        }
+        Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
+            c.clear();          // TODO: many more removal methods
+            if (testImplementationDetails
+                && !(c instanceof java.util.concurrent.ArrayBlockingQueue)) {
+                if (rnd.nextBoolean())
+                    assertFalse(s.tryAdvance(alwaysThrows));
+                else
+                    s.forEachRemaining(alwaysThrows);
+            }
+            if (it.hasNext()) iterated.add(it.next());
+            if (rnd.nextBoolean()) assertIteratorExhausted(it);
+        }
+        assertTrue(copy.containsAll(iterated));
+        assertTrue(copy.containsAll(spliterated));
+    }
+
+    /**
+     * Some elements randomly disappear in the middle of traversal.
+     */
+    public void testRandomElementRemovalDuringTraversal() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        ArrayList copy = new ArrayList();
+        for (int i = 0; i < n; i++) {
+            Object x = impl.makeElement(i);
+            copy.add(x);
+            c.add(x);
+        }
+        ArrayList iterated = new ArrayList();
+        ArrayList spliterated = new ArrayList();
+        ArrayList removed = new ArrayList();
+        Spliterator s = c.spliterator();
+        Iterator it = c.iterator();
+        if (! (s.hasCharacteristics(Spliterator.CONCURRENT) ||
+               s.hasCharacteristics(Spliterator.IMMUTABLE)))
+            return;
+        for (int i = rnd.nextInt(n + 1); --i >= 0; ) {
+            assertTrue(s.tryAdvance(e -> {}));
+            if (rnd.nextBoolean()) assertTrue(it.hasNext());
+            it.next();
+        }
+        Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        // TODO: many more removal methods
+        if (rnd.nextBoolean()) {
+            for (Iterator z = c.iterator(); z.hasNext(); ) {
+                Object e = z.next();
+                if (rnd.nextBoolean()) {
+                    try {
+                        z.remove();
+                    } catch (UnsupportedOperationException ok) { return; }
+                    removed.add(e);
+                }
+            }
+        } else {
+            Predicate randomlyRemove = e -> {
+                if (rnd.nextBoolean()) { removed.add(e); return true; }
+                else return false;
+            };
+            c.removeIf(randomlyRemove);
+        }
+        s.forEachRemaining(spliterated::add);
+        while (it.hasNext())
+            iterated.add(it.next());
+        assertTrue(copy.containsAll(iterated));
+        assertTrue(copy.containsAll(spliterated));
+        assertTrue(copy.containsAll(removed));
+        if (s.hasCharacteristics(Spliterator.CONCURRENT)) {
+            ArrayList iteratedAndRemoved = new ArrayList(iterated);
+            ArrayList spliteratedAndRemoved = new ArrayList(spliterated);
+            iteratedAndRemoved.retainAll(removed);
+            spliteratedAndRemoved.retainAll(removed);
+            assertTrue(iteratedAndRemoved.size() <= 1);
+            assertTrue(spliteratedAndRemoved.size() <= 1);
+            if (testImplementationDetails
+                && !(c instanceof java.util.concurrent.ArrayBlockingQueue))
+                assertTrue(spliteratedAndRemoved.isEmpty());
+        }
+    }
+
+    /**
+     * Various ways of traversing a collection yield same elements
+     */
+    public void testTraversalEquivalence() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = rnd.nextInt(6);
+        for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+        ArrayList iterated = new ArrayList();
+        ArrayList iteratedForEachRemaining = new ArrayList();
+        ArrayList tryAdvanced = new ArrayList();
+        ArrayList spliterated = new ArrayList();
+        ArrayList splitonced = new ArrayList();
+        ArrayList forEached = new ArrayList();
+        ArrayList streamForEached = new ArrayList();
+        ConcurrentLinkedQueue parallelStreamForEached = new ConcurrentLinkedQueue();
+        ArrayList removeIfed = new ArrayList();
+        for (Object x : c) iterated.add(x);
+        c.iterator().forEachRemaining(iteratedForEachRemaining::add);
+        for (Spliterator s = c.spliterator();
+             s.tryAdvance(tryAdvanced::add); ) {}
+        c.spliterator().forEachRemaining(spliterated::add);
+        {                       // trySplit returns "strict prefix"
+            Spliterator s1 = c.spliterator(), s2 = s1.trySplit();
+            if (s2 != null) s2.forEachRemaining(splitonced::add);
+            s1.forEachRemaining(splitonced::add);
+        }
+        c.forEach(forEached::add);
+        c.stream().forEach(streamForEached::add);
+        c.parallelStream().forEach(parallelStreamForEached::add);
+        c.removeIf(e -> { removeIfed.add(e); return false; });
+        boolean ordered =
+            c.spliterator().hasCharacteristics(Spliterator.ORDERED);
+        if (c instanceof List || c instanceof Deque)
+            assertTrue(ordered);
+        HashSet cset = new HashSet(c);
+        assertEquals(cset, new HashSet(parallelStreamForEached));
+        if (ordered) {
+            assertEquals(iterated, iteratedForEachRemaining);
+            assertEquals(iterated, tryAdvanced);
+            assertEquals(iterated, spliterated);
+            assertEquals(iterated, splitonced);
+            assertEquals(iterated, forEached);
+            assertEquals(iterated, streamForEached);
+            assertEquals(iterated, removeIfed);
+        } else {
+            assertEquals(cset, new HashSet(iterated));
+            assertEquals(cset, new HashSet(iteratedForEachRemaining));
+            assertEquals(cset, new HashSet(tryAdvanced));
+            assertEquals(cset, new HashSet(spliterated));
+            assertEquals(cset, new HashSet(splitonced));
+            assertEquals(cset, new HashSet(forEached));
+            assertEquals(cset, new HashSet(streamForEached));
+            assertEquals(cset, new HashSet(removeIfed));
+        }
+        if (c instanceof Deque) {
+            Deque d = (Deque) c;
+            ArrayList descending = new ArrayList();
+            ArrayList descendingForEachRemaining = new ArrayList();
+            for (Iterator it = d.descendingIterator(); it.hasNext(); )
+                descending.add(it.next());
+            d.descendingIterator().forEachRemaining(
+                e -> descendingForEachRemaining.add(e));
+            Collections.reverse(descending);
+            Collections.reverse(descendingForEachRemaining);
+            assertEquals(iterated, descending);
+            assertEquals(iterated, descendingForEachRemaining);
+        }
+    }
+
+    /**
+     * Iterator.forEachRemaining has same behavior as Iterator's
+     * default implementation.
+     */
+    public void testForEachRemainingConsistentWithDefaultImplementation() {
+        Collection c = impl.emptyCollection();
+        if (!testImplementationDetails
+            || c.getClass() == java.util.LinkedList.class)
+            return;
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        int n = 1 + rnd.nextInt(3);
+        for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+        ArrayList iterated = new ArrayList();
+        ArrayList iteratedForEachRemaining = new ArrayList();
+        Iterator it1 = c.iterator();
+        Iterator it2 = c.iterator();
+        assertTrue(it1.hasNext());
+        assertTrue(it2.hasNext());
+        c.clear();
+        Object r1, r2;
+        try {
+            while (it1.hasNext()) iterated.add(it1.next());
+            r1 = iterated;
+        } catch (ConcurrentModificationException ex) {
+            r1 = ConcurrentModificationException.class;
+            assertFalse(impl.isConcurrent());
+        }
+        try {
+            it2.forEachRemaining(iteratedForEachRemaining::add);
+            r2 = iteratedForEachRemaining;
+        } catch (ConcurrentModificationException ex) {
+            r2 = ConcurrentModificationException.class;
+            assertFalse(impl.isConcurrent());
+        }
+        assertEquals(r1, r2);
+    }
+
+    /**
+     * Calling Iterator#remove() after Iterator#forEachRemaining
+     * should (maybe) remove last element
+     */
+    public void testRemoveAfterForEachRemaining() {
+        Collection c = impl.emptyCollection();
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        testCollection: {
+            int n = 3 + rnd.nextInt(2);
+            for (int i = 0; i < n; i++) c.add(impl.makeElement(i));
+            Iterator it = c.iterator();
+            assertTrue(it.hasNext());
+            assertEquals(impl.makeElement(0), it.next());
+            assertTrue(it.hasNext());
+            assertEquals(impl.makeElement(1), it.next());
+            it.forEachRemaining(e -> assertTrue(c.contains(e)));
+            if (testImplementationDetails) {
+                if (c instanceof java.util.concurrent.ArrayBlockingQueue) {
+                    assertIteratorExhausted(it);
+                } else {
+                    try { it.remove(); }
+                    catch (UnsupportedOperationException ok) {
+                        break testCollection;
+                    }
+                    assertEquals(n - 1, c.size());
+                    for (int i = 0; i < n - 1; i++)
+                        assertTrue(c.contains(impl.makeElement(i)));
+                    assertFalse(c.contains(impl.makeElement(n - 1)));
+                }
+            }
+        }
+        if (c instanceof Deque) {
+            Deque d = (Deque) impl.emptyCollection();
+            int n = 3 + rnd.nextInt(2);
+            for (int i = 0; i < n; i++) d.add(impl.makeElement(i));
+            Iterator it = d.descendingIterator();
+            assertTrue(it.hasNext());
+            assertEquals(impl.makeElement(n - 1), it.next());
+            assertTrue(it.hasNext());
+            assertEquals(impl.makeElement(n - 2), it.next());
+            it.forEachRemaining(e -> assertTrue(c.contains(e)));
+            if (testImplementationDetails) {
+                it.remove();
+                assertEquals(n - 1, d.size());
+                for (int i = 1; i < n; i++)
+                    assertTrue(d.contains(impl.makeElement(i)));
+                assertFalse(d.contains(impl.makeElement(0)));
+            }
+        }
+    }
+
+    /**
+     * stream().forEach returns elements in the collection
+     */
+    public void testStreamForEach() throws Throwable {
+        final Collection c = impl.emptyCollection();
+        final AtomicLong count = new AtomicLong(0L);
+        final Object x = impl.makeElement(1);
+        final Object y = impl.makeElement(2);
+        final ArrayList found = new ArrayList();
+        Consumer<Object> spy = o -> found.add(o);
+        c.stream().forEach(spy);
+        assertTrue(found.isEmpty());
+
+        assertTrue(c.add(x));
+        c.stream().forEach(spy);
+        assertEquals(Collections.singletonList(x), found);
+        found.clear();
+
+        assertTrue(c.add(y));
+        c.stream().forEach(spy);
+        assertEquals(2, found.size());
+        assertTrue(found.contains(x));
+        assertTrue(found.contains(y));
+        found.clear();
+
+        c.clear();
+        c.stream().forEach(spy);
+        assertTrue(found.isEmpty());
+    }
+
+    public void testStreamForEachConcurrentStressTest() throws Throwable {
+        if (!impl.isConcurrent()) return;
+        final Collection c = impl.emptyCollection();
+        final long testDurationMillis = timeoutMillis();
+        final AtomicBoolean done = new AtomicBoolean(false);
+        final Object elt = impl.makeElement(1);
+        final Future<?> f1, f2;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(pool, done)) {
+            final CountDownLatch threadsStarted = new CountDownLatch(2);
+            Runnable checkElt = () -> {
+                threadsStarted.countDown();
+                while (!done.get())
+                    c.stream().forEach(x -> assertSame(x, elt)); };
+            Runnable addRemove = () -> {
+                threadsStarted.countDown();
+                while (!done.get()) {
+                    assertTrue(c.add(elt));
+                    assertTrue(c.remove(elt));
+                }};
+            f1 = pool.submit(checkElt);
+            f2 = pool.submit(addRemove);
+            Thread.sleep(testDurationMillis);
+        }
+        assertNull(f1.get(0L, MILLISECONDS));
+        assertNull(f2.get(0L, MILLISECONDS));
+    }
+
+    /**
+     * collection.forEach returns elements in the collection
+     */
+    public void testForEach() throws Throwable {
+        final Collection c = impl.emptyCollection();
+        final AtomicLong count = new AtomicLong(0L);
+        final Object x = impl.makeElement(1);
+        final Object y = impl.makeElement(2);
+        final ArrayList found = new ArrayList();
+        Consumer<Object> spy = o -> found.add(o);
+        c.forEach(spy);
+        assertTrue(found.isEmpty());
+
+        assertTrue(c.add(x));
+        c.forEach(spy);
+        assertEquals(Collections.singletonList(x), found);
+        found.clear();
+
+        assertTrue(c.add(y));
+        c.forEach(spy);
+        assertEquals(2, found.size());
+        assertTrue(found.contains(x));
+        assertTrue(found.contains(y));
+        found.clear();
+
+        c.clear();
+        c.forEach(spy);
+        assertTrue(found.isEmpty());
+    }
+
+    /** TODO: promote to a common utility */
+    static <T> T chooseOne(T ... ts) {
+        return ts[ThreadLocalRandom.current().nextInt(ts.length)];
+    }
+
+    /** TODO: more random adders and removers */
+    static <E> Runnable adderRemover(Collection<E> c, E e) {
+        return chooseOne(
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                assertTrue(c.remove(e));
+                assertFalse(c.contains(e));
+            },
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                assertTrue(c.removeIf(x -> x == e));
+                assertFalse(c.contains(e));
+            },
+            () -> {
+                assertTrue(c.add(e));
+                assertTrue(c.contains(e));
+                for (Iterator it = c.iterator();; )
+                    if (it.next() == e) {
+                        try { it.remove(); }
+                        catch (UnsupportedOperationException ok) {
+                            c.remove(e);
+                        }
+                        break;
+                    }
+                assertFalse(c.contains(e));
+            });
+    }
+
+    /**
+     * Concurrent Spliterators, once exhausted, stay exhausted.
+     */
+    public void testStickySpliteratorExhaustion() throws Throwable {
+        if (!impl.isConcurrent()) return;
+        if (!testImplementationDetails) return;
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final Consumer alwaysThrows = e -> { throw new AssertionError(); };
+        final Collection c = impl.emptyCollection();
+        final Spliterator s = c.spliterator();
+        if (rnd.nextBoolean()) {
+            assertFalse(s.tryAdvance(alwaysThrows));
+        } else {
+            s.forEachRemaining(alwaysThrows);
+        }
+        final Object one = impl.makeElement(1);
+        // Spliterator should not notice added element
+        c.add(one);
+        if (rnd.nextBoolean()) {
+            assertFalse(s.tryAdvance(alwaysThrows));
+        } else {
+            s.forEachRemaining(alwaysThrows);
+        }
+    }
+
+    /**
+     * Motley crew of threads concurrently randomly hammer the collection.
+     */
+    public void testDetectRaces() throws Throwable {
+        if (!impl.isConcurrent()) return;
+        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final Collection c = impl.emptyCollection();
+        final long testDurationMillis
+            = expensiveTests ? LONG_DELAY_MS : timeoutMillis();
+        final AtomicBoolean done = new AtomicBoolean(false);
+        final Object one = impl.makeElement(1);
+        final Object two = impl.makeElement(2);
+        final Consumer checkSanity = x -> assertTrue(x == one || x == two);
+        final Consumer<Object[]> checkArraySanity = array -> {
+            // assertTrue(array.length <= 2); // duplicates are permitted
+            for (Object x : array) assertTrue(x == one || x == two);
+        };
+        final Object[] emptyArray =
+            (Object[]) java.lang.reflect.Array.newInstance(one.getClass(), 0);
+        final List<Future<?>> futures;
+        final Phaser threadsStarted = new Phaser(1); // register this thread
+        final Runnable[] frobbers = {
+            () -> c.forEach(checkSanity),
+            () -> c.stream().forEach(checkSanity),
+            () -> c.parallelStream().forEach(checkSanity),
+            () -> c.spliterator().trySplit(),
+            () -> {
+                Spliterator s = c.spliterator();
+                s.tryAdvance(checkSanity);
+                s.trySplit();
+            },
+            () -> {
+                Spliterator s = c.spliterator();
+                do {} while (s.tryAdvance(checkSanity));
+            },
+            () -> { for (Object x : c) checkSanity.accept(x); },
+            () -> checkArraySanity.accept(c.toArray()),
+            () -> checkArraySanity.accept(c.toArray(emptyArray)),
+            () -> {
+                Object[] a = new Object[5];
+                Object three = impl.makeElement(3);
+                Arrays.fill(a, 0, a.length, three);
+                Object[] x = c.toArray(a);
+                if (x == a)
+                    for (int i = 0; i < a.length && a[i] != null; i++)
+                        checkSanity.accept(a[i]);
+                    // A careful reading of the spec does not support:
+                    // for (i++; i < a.length; i++) assertSame(three, a[i]);
+                else
+                    checkArraySanity.accept(x);
+                },
+            adderRemover(c, one),
+            adderRemover(c, two),
+        };
+        final List<Runnable> tasks =
+            Arrays.stream(frobbers)
+            .filter(task -> rnd.nextBoolean()) // random subset
+            .map(task -> (Runnable) () -> {
+                     threadsStarted.arriveAndAwaitAdvance();
+                     while (!done.get())
+                         task.run();
+                 })
+            .collect(Collectors.toList());
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(pool, done)) {
+            threadsStarted.bulkRegister(tasks.size());
+            futures = tasks.stream()
+                .map(pool::submit)
+                .collect(Collectors.toList());
+            threadsStarted.arriveAndDeregister();
+            Thread.sleep(testDurationMillis);
+        }
+        for (Future future : futures)
+            assertNull(future.get(0L, MILLISECONDS));
+    }
+
+    /**
+     * Spliterators are either IMMUTABLE or truly late-binding or, if
+     * concurrent, use the same "late-binding style" of returning
+     * elements added between creation and first use.
+     */
+    public void testLateBindingStyle() {
+        if (!testImplementationDetails) return;
+        if (impl.klazz() == ArrayList.class) return; // for jdk8
+        // Immutable (snapshot) spliterators are exempt
+        if (impl.emptyCollection().spliterator()
+            .hasCharacteristics(Spliterator.IMMUTABLE))
+            return;
+        final Object one = impl.makeElement(1);
+        {
+            final Collection c = impl.emptyCollection();
+            final Spliterator split = c.spliterator();
+            c.add(one);
+            assertTrue(split.tryAdvance(e -> { assertSame(e, one); }));
+            assertFalse(split.tryAdvance(e -> { throw new AssertionError(); }));
+            assertTrue(c.contains(one));
+        }
+        {
+            final AtomicLong count = new AtomicLong(0);
+            final Collection c = impl.emptyCollection();
+            final Spliterator split = c.spliterator();
+            c.add(one);
+            split.forEachRemaining(
+                e -> { assertSame(e, one); count.getAndIncrement(); });
+            assertEquals(1L, count.get());
+            assertFalse(split.tryAdvance(e -> { throw new AssertionError(); }));
+            assertTrue(c.contains(one));
+        }
+    }
+
+    /**
+     * Spliterator.getComparator throws IllegalStateException iff the
+     * spliterator does not report SORTED.
+     */
+    public void testGetComparator_IllegalStateException() {
+        Collection c = impl.emptyCollection();
+        Spliterator s = c.spliterator();
+        boolean reportsSorted = s.hasCharacteristics(Spliterator.SORTED);
+        try {
+            s.getComparator();
+            assertTrue(reportsSorted);
+        } catch (IllegalStateException ex) {
+            assertFalse(reportsSorted);
+        }
+    }
+
+//     public void testCollection8DebugFail() {
+//         fail(impl.klazz().getSimpleName());
+//     }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CollectionImplementation.java b/ojluni/src/test/java/util/concurrent/tck/CollectionImplementation.java
new file mode 100644
index 0000000..fc3b3be
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CollectionImplementation.java
@@ -0,0 +1,47 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.Collection;
+
+/** Allows tests to work with different Collection implementations. */
+public interface CollectionImplementation {
+    /** Returns the Collection class. */
+    public Class<?> klazz();
+    /** Returns an empty collection. */
+    public Collection emptyCollection();
+    public Object makeElement(int i);
+    public boolean isConcurrent();
+    public boolean permitsNulls();
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java b/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java
new file mode 100644
index 0000000..2f3943a
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CollectionTest.java
@@ -0,0 +1,63 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import junit.framework.Test;
+
+/**
+ * Contains tests applicable to all Collection implementations.
+ */
+public class CollectionTest extends JSR166TestCase {
+    final CollectionImplementation impl;
+
+    /** Tests are parameterized by a Collection implementation. */
+    CollectionTest(CollectionImplementation impl, String methodName) {
+        super(methodName);
+        this.impl = impl;
+    }
+
+    public static Test testSuite(CollectionImplementation impl) {
+        return newTestSuite
+            (parameterizedTestSuite(CollectionTest.class,
+                                    CollectionImplementation.class,
+                                    impl),
+             jdk8ParameterizedTestSuite(CollectionTest.class,
+                                        CollectionImplementation.class,
+                                        impl));
+    }
+
+//     public void testCollectionDebugFail() {
+//         fail(impl.klazz().getSimpleName());
+//     }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CompletableFutureTest.java b/ojluni/src/test/java/util/concurrent/tck/CompletableFutureTest.java
new file mode 100644
index 0000000..e97a0ab
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CompletableFutureTest.java
@@ -0,0 +1,4513 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.CompletableFuture.completedFuture;
+import static java.util.concurrent.CompletableFuture.failedFuture;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CompletableFutureTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(CompletableFutureTest.class);
+    }
+
+    static class CFException extends RuntimeException {}
+
+    void checkIncomplete(CompletableFuture<?> f) {
+        assertFalse(f.isDone());
+        assertFalse(f.isCancelled());
+        assertTrue(f.toString().contains("Not completed"));
+        try {
+            assertNull(f.getNow(null));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            f.get(0L, SECONDS);
+            shouldThrow();
+        }
+        catch (TimeoutException success) {}
+        catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(CompletableFuture<T> f, T value) {
+        checkTimedGet(f, value);
+
+        try {
+            assertEquals(value, f.join());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertEquals(value, f.getNow(null));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertEquals(value, f.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(f.isDone());
+        assertFalse(f.isCancelled());
+        assertFalse(f.isCompletedExceptionally());
+        assertTrue(f.toString().contains("[Completed normally]"));
+    }
+
+    /**
+     * Returns the "raw" internal exceptional completion of f,
+     * without any additional wrapping with CompletionException.
+     */
+    Throwable exceptionalCompletion(CompletableFuture<?> f) {
+        // handle (and whenComplete and exceptionally) can distinguish
+        // between "direct" and "wrapped" exceptional completion
+        return f.handle((u, t) -> t).join();
+    }
+
+    void checkCompletedExceptionally(CompletableFuture<?> f,
+                                     boolean wrapped,
+                                     Consumer<Throwable> checker) {
+        Throwable cause = exceptionalCompletion(f);
+        if (wrapped) {
+            assertTrue(cause instanceof CompletionException);
+            cause = cause.getCause();
+        }
+        checker.accept(cause);
+
+        long startTime = System.nanoTime();
+        try {
+            f.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.getNow(null);
+            shouldThrow();
+        } catch (CompletionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(cause, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        assertFalse(f.isCancelled());
+        assertTrue(f.isDone());
+        assertTrue(f.isCompletedExceptionally());
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+    }
+
+    void checkCompletedWithWrappedCFException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, true,
+            t -> assertTrue(t instanceof CFException));
+    }
+
+    void checkCompletedWithWrappedCancellationException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, true,
+            t -> assertTrue(t instanceof CancellationException));
+    }
+
+    void checkCompletedWithTimeoutException(CompletableFuture<?> f) {
+        checkCompletedExceptionally(f, false,
+            t -> assertTrue(t instanceof TimeoutException));
+    }
+
+    void checkCompletedWithWrappedException(CompletableFuture<?> f,
+                                            Throwable ex) {
+        checkCompletedExceptionally(f, true, t -> assertSame(t, ex));
+    }
+
+    void checkCompletedExceptionally(CompletableFuture<?> f, Throwable ex) {
+        checkCompletedExceptionally(f, false, t -> assertSame(t, ex));
+    }
+
+    void checkCancelled(CompletableFuture<?> f) {
+        long startTime = System.nanoTime();
+        try {
+            f.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CancellationException success) {}
+        try {
+            f.getNow(null);
+            shouldThrow();
+        } catch (CancellationException success) {}
+        try {
+            f.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        assertTrue(exceptionalCompletion(f) instanceof CancellationException);
+
+        assertTrue(f.isDone());
+        assertTrue(f.isCompletedExceptionally());
+        assertTrue(f.isCancelled());
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+    }
+
+    /**
+     * A newly constructed CompletableFuture is incomplete, as indicated
+     * by methods isDone, isCancelled, and getNow
+     */
+    public void testConstructor() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+    }
+
+    /**
+     * complete completes normally, as indicated by methods isDone,
+     * isCancelled, join, get, and getNow
+     */
+    public void testComplete() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.complete(v1));
+        assertFalse(f.complete(v1));
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * completeExceptionally completes exceptionally, as indicated by
+     * methods isDone, isCancelled, join, get, and getNow
+     */
+    public void testCompleteExceptionally() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        checkIncomplete(f);
+        f.completeExceptionally(ex);
+        checkCompletedExceptionally(f, ex);
+    }
+
+    /**
+     * cancel completes exceptionally and reports cancelled, as indicated by
+     * methods isDone, isCancelled, join, get, and getNow
+     */
+    public void testCancel() {
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        assertTrue(f.cancel(!mayInterruptIfRunning));
+        checkCancelled(f);
+    }}
+
+    /**
+     * obtrudeValue forces completion with given value
+     */
+    public void testObtrudeValue() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        checkIncomplete(f);
+        assertTrue(f.complete(one));
+        checkCompletedNormally(f, one);
+        f.obtrudeValue(three);
+        checkCompletedNormally(f, three);
+        f.obtrudeValue(two);
+        checkCompletedNormally(f, two);
+        f = new CompletableFuture<>();
+        f.obtrudeValue(three);
+        checkCompletedNormally(f, three);
+        f.obtrudeValue(null);
+        checkCompletedNormally(f, null);
+        f = new CompletableFuture<>();
+        f.completeExceptionally(new CFException());
+        f.obtrudeValue(four);
+        checkCompletedNormally(f, four);
+    }
+
+    /**
+     * obtrudeException forces completion with given exception
+     */
+    public void testObtrudeException() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CFException ex;
+        CompletableFuture<Integer> f;
+
+        f = new CompletableFuture<>();
+        assertTrue(f.complete(v1));
+        for (int i = 0; i < 2; i++) {
+            f.obtrudeException(ex = new CFException());
+            checkCompletedExceptionally(f, ex);
+        }
+
+        f = new CompletableFuture<>();
+        for (int i = 0; i < 2; i++) {
+            f.obtrudeException(ex = new CFException());
+            checkCompletedExceptionally(f, ex);
+        }
+
+        f = new CompletableFuture<>();
+        f.completeExceptionally(ex = new CFException());
+        f.obtrudeValue(v1);
+        checkCompletedNormally(f, v1);
+        f.obtrudeException(ex = new CFException());
+        checkCompletedExceptionally(f, ex);
+        f.completeExceptionally(new CFException());
+        checkCompletedExceptionally(f, ex);
+        assertFalse(f.complete(v1));
+        checkCompletedExceptionally(f, ex);
+    }}
+
+    /**
+     * getNumberOfDependents returns number of dependent tasks
+     */
+    public void testGetNumberOfDependents() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        assertEquals(0, f.getNumberOfDependents());
+        final CompletableFuture<Void> g = m.thenRun(f, new Noop(m));
+        assertEquals(1, f.getNumberOfDependents());
+        assertEquals(0, g.getNumberOfDependents());
+        final CompletableFuture<Void> h = m.thenRun(f, new Noop(m));
+        assertEquals(2, f.getNumberOfDependents());
+        assertEquals(0, h.getNumberOfDependents());
+        assertTrue(f.complete(v1));
+        checkCompletedNormally(g, null);
+        checkCompletedNormally(h, null);
+        assertEquals(0, f.getNumberOfDependents());
+        assertEquals(0, g.getNumberOfDependents());
+        assertEquals(0, h.getNumberOfDependents());
+    }}
+
+    /**
+     * toString indicates current completion state
+     */
+    public void testToString() {
+        CompletableFuture<String> f;
+
+        f = new CompletableFuture<String>();
+        assertTrue(f.toString().contains("[Not completed]"));
+
+        assertTrue(f.complete("foo"));
+        assertTrue(f.toString().contains("[Completed normally]"));
+
+        f = new CompletableFuture<String>();
+        assertTrue(f.completeExceptionally(new IndexOutOfBoundsException()));
+        assertTrue(f.toString().contains("[Completed exceptionally]"));
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+            f = new CompletableFuture<String>();
+            assertTrue(f.cancel(mayInterruptIfRunning));
+            assertTrue(f.toString().contains("[Completed exceptionally]"));
+        }
+    }
+
+    /**
+     * completedFuture returns a completed CompletableFuture with given value
+     */
+    public void testCompletedFuture() {
+        CompletableFuture<String> f = CompletableFuture.completedFuture("test");
+        checkCompletedNormally(f, "test");
+    }
+
+    abstract static class CheckedAction {
+        int invocationCount = 0;
+        final ExecutionMode m;
+        CheckedAction(ExecutionMode m) { this.m = m; }
+        void invoked() {
+            m.checkExecutionMode();
+            assertEquals(0, invocationCount++);
+        }
+        void assertNotInvoked() { assertEquals(0, invocationCount); }
+        void assertInvoked() { assertEquals(1, invocationCount); }
+    }
+
+    abstract static class CheckedIntegerAction extends CheckedAction {
+        Integer value;
+        CheckedIntegerAction(ExecutionMode m) { super(m); }
+        void assertValue(Integer expected) {
+            assertInvoked();
+            assertEquals(expected, value);
+        }
+    }
+
+    static class IntegerSupplier extends CheckedAction
+        implements Supplier<Integer>
+    {
+        final Integer value;
+        IntegerSupplier(ExecutionMode m, Integer value) {
+            super(m);
+            this.value = value;
+        }
+        public Integer get() {
+            invoked();
+            return value;
+        }
+    }
+
+    // A function that handles and produces null values as well.
+    static Integer inc(Integer x) {
+        return (x == null) ? null : x + 1;
+    }
+
+    static class NoopConsumer extends CheckedIntegerAction
+        implements Consumer<Integer>
+    {
+        NoopConsumer(ExecutionMode m) { super(m); }
+        public void accept(Integer x) {
+            invoked();
+            value = x;
+        }
+    }
+
+    static class IncFunction extends CheckedIntegerAction
+        implements Function<Integer,Integer>
+    {
+        IncFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x) {
+            invoked();
+            return value = inc(x);
+        }
+    }
+
+    // Choose non-commutative actions for better coverage
+    // A non-commutative function that handles and produces null values as well.
+    static Integer subtract(Integer x, Integer y) {
+        return (x == null && y == null) ? null :
+            ((x == null) ? 42 : x.intValue())
+            - ((y == null) ? 99 : y.intValue());
+    }
+
+    static class SubtractAction extends CheckedIntegerAction
+        implements BiConsumer<Integer, Integer>
+    {
+        SubtractAction(ExecutionMode m) { super(m); }
+        public void accept(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+        }
+    }
+
+    static class SubtractFunction extends CheckedIntegerAction
+        implements BiFunction<Integer, Integer, Integer>
+    {
+        SubtractFunction(ExecutionMode m) { super(m); }
+        public Integer apply(Integer x, Integer y) {
+            invoked();
+            return value = subtract(x, y);
+        }
+    }
+
+    static class Noop extends CheckedAction implements Runnable {
+        Noop(ExecutionMode m) { super(m); }
+        public void run() {
+            invoked();
+        }
+    }
+
+    static class FailingSupplier extends CheckedAction
+        implements Supplier<Integer>
+    {
+        final CFException ex;
+        FailingSupplier(ExecutionMode m) { super(m); ex = new CFException(); }
+        public Integer get() {
+            invoked();
+            throw ex;
+        }
+    }
+
+    static class FailingConsumer extends CheckedIntegerAction
+        implements Consumer<Integer>
+    {
+        final CFException ex;
+        FailingConsumer(ExecutionMode m) { super(m); ex = new CFException(); }
+        public void accept(Integer x) {
+            invoked();
+            value = x;
+            throw ex;
+        }
+    }
+
+    static class FailingBiConsumer extends CheckedIntegerAction
+        implements BiConsumer<Integer, Integer>
+    {
+        final CFException ex;
+        FailingBiConsumer(ExecutionMode m) { super(m); ex = new CFException(); }
+        public void accept(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+            throw ex;
+        }
+    }
+
+    static class FailingFunction extends CheckedIntegerAction
+        implements Function<Integer, Integer>
+    {
+        final CFException ex;
+        FailingFunction(ExecutionMode m) { super(m); ex = new CFException(); }
+        public Integer apply(Integer x) {
+            invoked();
+            value = x;
+            throw ex;
+        }
+    }
+
+    static class FailingBiFunction extends CheckedIntegerAction
+        implements BiFunction<Integer, Integer, Integer>
+    {
+        final CFException ex;
+        FailingBiFunction(ExecutionMode m) { super(m); ex = new CFException(); }
+        public Integer apply(Integer x, Integer y) {
+            invoked();
+            value = subtract(x, y);
+            throw ex;
+        }
+    }
+
+    static class FailingRunnable extends CheckedAction implements Runnable {
+        final CFException ex;
+        FailingRunnable(ExecutionMode m) { super(m); ex = new CFException(); }
+        public void run() {
+            invoked();
+            throw ex;
+        }
+    }
+
+    static class CompletableFutureInc extends CheckedIntegerAction
+        implements Function<Integer, CompletableFuture<Integer>>
+    {
+        CompletableFutureInc(ExecutionMode m) { super(m); }
+        public CompletableFuture<Integer> apply(Integer x) {
+            invoked();
+            value = x;
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            assertTrue(f.complete(inc(x)));
+            return f;
+        }
+    }
+
+    static class FailingCompletableFutureFunction extends CheckedIntegerAction
+        implements Function<Integer, CompletableFuture<Integer>>
+    {
+        final CFException ex;
+        FailingCompletableFutureFunction(ExecutionMode m) { super(m); ex = new CFException(); }
+        public CompletableFuture<Integer> apply(Integer x) {
+            invoked();
+            value = x;
+            throw ex;
+        }
+    }
+
+    static class CountingRejectingExecutor implements Executor {
+        final RejectedExecutionException ex = new RejectedExecutionException();
+        final AtomicInteger count = new AtomicInteger(0);
+        public void execute(Runnable r) {
+            count.getAndIncrement();
+            throw ex;
+        }
+    }
+
+    // Used for explicit executor tests
+    static final class ThreadExecutor implements Executor {
+        final AtomicInteger count = new AtomicInteger(0);
+        static final ThreadGroup tg = new ThreadGroup("ThreadExecutor");
+        static boolean startedCurrentThread() {
+            return Thread.currentThread().getThreadGroup() == tg;
+        }
+
+        public void execute(Runnable r) {
+            count.getAndIncrement();
+            new Thread(tg, r).start();
+        }
+    }
+
+    static final boolean defaultExecutorIsCommonPool
+        = ForkJoinPool.getCommonPoolParallelism() > 1;
+
+    /**
+     * Permits the testing of parallel code for the 3 different
+     * execution modes without copy/pasting all the test methods.
+     */
+    enum ExecutionMode {
+        SYNC {
+            public void checkExecutionMode() {
+                assertFalse(ThreadExecutor.startedCurrentThread());
+                assertNull(ForkJoinTask.getPool());
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                throw new UnsupportedOperationException();
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                throw new UnsupportedOperationException();
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRun(a);
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAccept(a);
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApply(a);
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenCompose(a);
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handle(a);
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenComplete(a);
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBoth(g, a);
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBoth(g, a);
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombine(g, a);
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEither(g, a);
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEither(g, a);
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEither(g, a);
+            }
+        },
+
+        ASYNC {
+            public void checkExecutionMode() {
+                assertEquals(defaultExecutorIsCommonPool,
+                             (ForkJoinPool.commonPool() == ForkJoinTask.getPool()));
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                return CompletableFuture.runAsync(a);
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                return CompletableFuture.supplyAsync(a);
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRunAsync(a);
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAcceptAsync(a);
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApplyAsync(a);
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenComposeAsync(a);
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handleAsync(a);
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenCompleteAsync(a);
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBothAsync(g, a);
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBothAsync(g, a);
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombineAsync(g, a);
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEitherAsync(g, a);
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEitherAsync(g, a);
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEitherAsync(g, a);
+            }
+        },
+
+        EXECUTOR {
+            public void checkExecutionMode() {
+                assertTrue(ThreadExecutor.startedCurrentThread());
+            }
+            public CompletableFuture<Void> runAsync(Runnable a) {
+                return CompletableFuture.runAsync(a, new ThreadExecutor());
+            }
+            public <U> CompletableFuture<U> supplyAsync(Supplier<U> a) {
+                return CompletableFuture.supplyAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> thenRun
+                (CompletableFuture<T> f, Runnable a) {
+                return f.thenRunAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> thenAccept
+                (CompletableFuture<T> f, Consumer<? super T> a) {
+                return f.thenAcceptAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> thenApply
+                (CompletableFuture<T> f, Function<? super T,U> a) {
+                return f.thenApplyAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> thenCompose
+                (CompletableFuture<T> f,
+                 Function<? super T,? extends CompletionStage<U>> a) {
+                return f.thenComposeAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> handle
+                (CompletableFuture<T> f,
+                 BiFunction<? super T,Throwable,? extends U> a) {
+                return f.handleAsync(a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<T> whenComplete
+                (CompletableFuture<T> f,
+                 BiConsumer<? super T,? super Throwable> a) {
+                return f.whenCompleteAsync(a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<Void> runAfterBoth
+                (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a) {
+                return f.runAfterBothAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<Void> thenAcceptBoth
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiConsumer<? super T,? super U> a) {
+                return f.thenAcceptBothAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U,V> CompletableFuture<V> thenCombine
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends U> g,
+                 BiFunction<? super T,? super U,? extends V> a) {
+                return f.thenCombineAsync(g, a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> runAfterEither
+                (CompletableFuture<T> f,
+                 CompletionStage<?> g,
+                 java.lang.Runnable a) {
+                return f.runAfterEitherAsync(g, a, new ThreadExecutor());
+            }
+            public <T> CompletableFuture<Void> acceptEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Consumer<? super T> a) {
+                return f.acceptEitherAsync(g, a, new ThreadExecutor());
+            }
+            public <T,U> CompletableFuture<U> applyToEither
+                (CompletableFuture<T> f,
+                 CompletionStage<? extends T> g,
+                 Function<? super T,U> a) {
+                return f.applyToEitherAsync(g, a, new ThreadExecutor());
+            }
+        };
+
+        public abstract void checkExecutionMode();
+        public abstract CompletableFuture<Void> runAsync(Runnable a);
+        public abstract <U> CompletableFuture<U> supplyAsync(Supplier<U> a);
+        public abstract <T> CompletableFuture<Void> thenRun
+            (CompletableFuture<T> f, Runnable a);
+        public abstract <T> CompletableFuture<Void> thenAccept
+            (CompletableFuture<T> f, Consumer<? super T> a);
+        public abstract <T,U> CompletableFuture<U> thenApply
+            (CompletableFuture<T> f, Function<? super T,U> a);
+        public abstract <T,U> CompletableFuture<U> thenCompose
+            (CompletableFuture<T> f,
+             Function<? super T,? extends CompletionStage<U>> a);
+        public abstract <T,U> CompletableFuture<U> handle
+            (CompletableFuture<T> f,
+             BiFunction<? super T,Throwable,? extends U> a);
+        public abstract <T> CompletableFuture<T> whenComplete
+            (CompletableFuture<T> f,
+             BiConsumer<? super T,? super Throwable> a);
+        public abstract <T,U> CompletableFuture<Void> runAfterBoth
+            (CompletableFuture<T> f, CompletableFuture<U> g, Runnable a);
+        public abstract <T,U> CompletableFuture<Void> thenAcceptBoth
+            (CompletableFuture<T> f,
+             CompletionStage<? extends U> g,
+             BiConsumer<? super T,? super U> a);
+        public abstract <T,U,V> CompletableFuture<V> thenCombine
+            (CompletableFuture<T> f,
+             CompletionStage<? extends U> g,
+             BiFunction<? super T,? super U,? extends V> a);
+        public abstract <T> CompletableFuture<Void> runAfterEither
+            (CompletableFuture<T> f,
+             CompletionStage<?> g,
+             java.lang.Runnable a);
+        public abstract <T> CompletableFuture<Void> acceptEither
+            (CompletableFuture<T> f,
+             CompletionStage<? extends T> g,
+             Consumer<? super T> a);
+        public abstract <T,U> CompletableFuture<U> applyToEither
+            (CompletableFuture<T> f,
+             CompletionStage<? extends T> g,
+             Function<? super T,U> a);
+    }
+
+    /**
+     * exceptionally action is not invoked when source completes
+     * normally, and source result is propagated
+     */
+    public void testExceptionally_normalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                a.getAndIncrement();
+                threadFail("should not be called");
+                return null;            // unreached
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(0, a.get());
+    }}
+
+    /**
+     * exceptionally action completes with function value on source
+     * exception
+     */
+    public void testExceptionally_exceptionalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                ExecutionMode.SYNC.checkExecutionMode();
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedNormally(g, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If an "exceptionally action" throws an exception, it completes
+     * exceptionally with that exception
+     */
+    public void testExceptionally_exceptionalCompletionActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = f.exceptionally
+            ((Throwable t) -> {
+                ExecutionMode.SYNC.checkExecutionMode();
+                threadAssertSame(t, ex1);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex2);
+        checkCompletedExceptionally(f, ex1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on normal completion, propagating
+     * source result.
+     */
+    public void testWhenComplete_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on exceptional completion, propagating
+     * source result.
+     */
+    public void testWhenComplete_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * whenComplete action executes on cancelled source, propagating
+     * CancellationException.
+     */
+    public void testWhenComplete_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertTrue(t instanceof CancellationException);
+                a.getAndIncrement();
+            });
+        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+
+        checkCompletedWithWrappedCancellationException(g);
+        checkCancelled(f);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a whenComplete action throws an exception when triggered by
+     * a normal completion, it completes exceptionally
+     */
+    public void testWhenComplete_sourceCompletedNormallyActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                throw ex;
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a whenComplete action throws an exception when triggered by
+     * a source completion that also throws an exception, the source
+     * exception takes precedence (unlike handle)
+     */
+    public void testWhenComplete_sourceFailedActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = m.whenComplete
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(t, ex1);
+                threadAssertNull(result);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex1);
+        checkCompletedExceptionally(f, ex1);
+        if (testImplementationDetails) {
+            assertEquals(1, ex1.getSuppressed().length);
+            assertSame(ex2, ex1.getSuppressed()[0]);
+        }
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on normal
+     * completion of source
+     */
+    public void testHandle_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                return inc(v1);
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, inc(v1));
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on
+     * exceptional completion of source
+     */
+    public void testHandle_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(t, ex);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedNormally(g, v1);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * handle action completes normally with function value on
+     * cancelled source
+     */
+    public void testHandle_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertTrue(t instanceof CancellationException);
+                a.getAndIncrement();
+                return v1;
+            });
+        if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+
+        checkCompletedNormally(g, v1);
+        checkCancelled(f);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a "handle action" throws an exception when triggered by
+     * a normal completion, it completes exceptionally
+     */
+    public void testHandle_sourceCompletedNormallyActionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex = new CFException();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertSame(result, v1);
+                threadAssertNull(t);
+                a.getAndIncrement();
+                throw ex;
+            });
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedNormally(f, v1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * If a "handle action" throws an exception when triggered by
+     * a source completion that also throws an exception, the action
+     * exception takes precedence (unlike whenComplete)
+     */
+    public void testHandle_sourceFailedActionFailed() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final AtomicInteger a = new AtomicInteger(0);
+        final CFException ex1 = new CFException();
+        final CFException ex2 = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+
+        if (!createIncomplete) f.completeExceptionally(ex1);
+        final CompletableFuture<Integer> g = m.handle
+            (f,
+             (Integer result, Throwable t) -> {
+                m.checkExecutionMode();
+                threadAssertNull(result);
+                threadAssertSame(ex1, t);
+                a.getAndIncrement();
+                throw ex2;
+            });
+        if (createIncomplete) f.completeExceptionally(ex1);
+
+        checkCompletedWithWrappedException(g, ex2);
+        checkCompletedExceptionally(f, ex1);
+        assertEquals(1, a.get());
+    }}
+
+    /**
+     * runAsync completes after running Runnable
+     */
+    public void testRunAsync_normalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        final Noop r = new Noop(m);
+        final CompletableFuture<Void> f = m.runAsync(r);
+        assertNull(f.join());
+        checkCompletedNormally(f, null);
+        r.assertInvoked();
+    }}
+
+    /**
+     * failing runAsync completes exceptionally after running Runnable
+     */
+    public void testRunAsync_exceptionalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        final FailingRunnable r = new FailingRunnable(m);
+        final CompletableFuture<Void> f = m.runAsync(r);
+        checkCompletedWithWrappedException(f, r.ex);
+        r.assertInvoked();
+    }}
+
+    public void testRunAsync_rejectingExecutor() {
+        CountingRejectingExecutor e = new CountingRejectingExecutor();
+        try {
+            CompletableFuture.runAsync(() -> {}, e);
+            shouldThrow();
+        } catch (Throwable t) {
+            assertSame(e.ex, t);
+        }
+
+        assertEquals(1, e.count.get());
+    }
+
+    /**
+     * supplyAsync completes with result of supplier
+     */
+    public void testSupplyAsync_normalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final IntegerSupplier r = new IntegerSupplier(m, v1);
+        final CompletableFuture<Integer> f = m.supplyAsync(r);
+        assertSame(v1, f.join());
+        checkCompletedNormally(f, v1);
+        r.assertInvoked();
+    }}
+
+    /**
+     * Failing supplyAsync completes exceptionally
+     */
+    public void testSupplyAsync_exceptionalCompletion() {
+        ExecutionMode[] executionModes = {
+            ExecutionMode.ASYNC,
+            ExecutionMode.EXECUTOR,
+        };
+        for (ExecutionMode m : executionModes)
+    {
+        FailingSupplier r = new FailingSupplier(m);
+        CompletableFuture<Integer> f = m.supplyAsync(r);
+        checkCompletedWithWrappedException(f, r.ex);
+        r.assertInvoked();
+    }}
+
+    public void testSupplyAsync_rejectingExecutor() {
+        CountingRejectingExecutor e = new CountingRejectingExecutor();
+        try {
+            CompletableFuture.supplyAsync(() -> null, e);
+            shouldThrow();
+        } catch (Throwable t) {
+            assertSame(e.ex, t);
+        }
+
+        assertEquals(1, e.count.get());
+    }
+
+    // seq completion methods
+
+    /**
+     * thenRun result completes normally after normal completion of source
+     */
+    public void testThenRun_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        checkCompletedNormally(f, v1);
+        for (Noop r : rs) r.assertInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenRun_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        checkCompletedWithWrappedException(h5, ex);
+        checkCompletedExceptionally(f, ex);
+        for (Noop r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally if source cancelled
+     */
+    public void testThenRun_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCompletedWithWrappedCancellationException(h4);
+        checkCompletedWithWrappedCancellationException(h5);
+        checkCancelled(f);
+        for (Noop r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenRun result completes exceptionally if action does
+     */
+    public void testThenRun_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingRunnable[] rs = new FailingRunnable[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
+
+        final CompletableFuture<Void> h0 = m.thenRun(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, f, rs[1]);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, f, rs[2]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h3 = m.thenRun(f, rs[3]);
+        final CompletableFuture<Void> h4 = m.runAfterBoth(f, f, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(f, f, rs[5]);
+
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        checkCompletedWithWrappedException(h4, rs[4].ex);
+        checkCompletedWithWrappedException(h5, rs[5].ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenApply result completes normally after normal completion of source
+     */
+    public void testThenApply_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        checkCompletedNormally(f, v1);
+        for (IncFunction r : rs) r.assertValue(inc(v1));
+    }}
+
+    /**
+     * thenApply result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenApply_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedExceptionally(f, ex);
+        for (IncFunction r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenApply result completes exceptionally if source cancelled
+     */
+    public void testThenApply_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCancelled(f);
+        for (IncFunction r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenApply result completes exceptionally if action does
+     */
+    public void testThenApply_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingFunction[] rs = new FailingFunction[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.thenApply(f, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(f, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> h2 = m.thenApply(f, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenAccept result completes normally after normal completion of source
+     */
+    public void testThenAccept_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(f, v1);
+        for (NoopConsumer r : rs) r.assertValue(v1);
+    }}
+
+    /**
+     * thenAccept result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenAccept_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedExceptionally(f, ex);
+        for (NoopConsumer r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenAccept result completes exceptionally if source cancelled
+     */
+    public void testThenAccept_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        checkCancelled(f);
+        for (NoopConsumer r : rs) r.assertNotInvoked();
+    }}
+
+    /**
+     * thenAccept result completes exceptionally if action does
+     */
+    public void testThenAccept_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingConsumer[] rs = new FailingConsumer[4];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.thenAccept(f, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(f, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.thenAccept(f, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(f, f, rs[3]);
+
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenCombine result completes normally after normal completion
+     * of sources
+     */
+    public void testThenCombine_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractFunction[] rs = new SubtractFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Integer> h0 = m.thenCombine(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.thenCombine(fst, fst, rs[1]);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.thenCombine(fst, fst, rs[3]);
+        checkIncomplete(h0); rs[0].assertNotInvoked();
+        checkIncomplete(h2); rs[2].assertNotInvoked();
+        checkCompletedNormally(h1, subtract(w1, w1));
+        checkCompletedNormally(h3, subtract(w1, w1));
+        rs[1].assertValue(subtract(w1, w1));
+        rs[3].assertValue(subtract(w1, w1));
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Integer> h4 = m.thenCombine(f, g, rs[4]);
+
+        checkCompletedNormally(h0, subtract(v1, v2));
+        checkCompletedNormally(h2, subtract(v1, v2));
+        checkCompletedNormally(h4, subtract(v1, v2));
+        rs[0].assertValue(subtract(v1, v2));
+        rs[2].assertValue(subtract(v1, v2));
+        rs[4].assertValue(subtract(v1, v2));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testThenCombine_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final SubtractFunction r1 = new SubtractFunction(m);
+        final SubtractFunction r2 = new SubtractFunction(m);
+        final SubtractFunction r3 = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally if either source cancelled
+     */
+    public void testThenCombine_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractFunction r1 = new SubtractFunction(m);
+        final SubtractFunction r2 = new SubtractFunction(m);
+        final SubtractFunction r3 = new SubtractFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * thenCombine result completes exceptionally if action does
+     */
+    public void testThenCombine_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingBiFunction r1 = new FailingBiFunction(m);
+        final FailingBiFunction r2 = new FailingBiFunction(m);
+        final FailingBiFunction r3 = new FailingBiFunction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Integer> h1 = m.thenCombine(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Integer> h2 = m.thenCombine(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Integer> h3 = m.thenCombine(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, r1.ex);
+        checkCompletedWithWrappedException(h2, r2.ex);
+        checkCompletedWithWrappedException(h3, r3.ex);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenAcceptBoth result completes normally after normal
+     * completion of sources
+     */
+    public void testThenAcceptBoth_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        r1.assertValue(subtract(v1, v2));
+        r2.assertValue(subtract(v1, v2));
+        r3.assertValue(subtract(v1, v2));
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testThenAcceptBoth_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally if either source cancelled
+     */
+    public void testThenAcceptBoth_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final SubtractAction r1 = new SubtractAction(m);
+        final SubtractAction r2 = new SubtractAction(m);
+        final SubtractAction r3 = new SubtractAction(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * thenAcceptBoth result completes exceptionally if action does
+     */
+    public void testThenAcceptBoth_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingBiConsumer r1 = new FailingBiConsumer(m);
+        final FailingBiConsumer r2 = new FailingBiConsumer(m);
+        final FailingBiConsumer r3 = new FailingBiConsumer(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.thenAcceptBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.thenAcceptBoth(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.thenAcceptBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, r1.ex);
+        checkCompletedWithWrappedException(h2, r2.ex);
+        checkCompletedWithWrappedException(h3, r3.ex);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterBoth result completes normally after normal
+     * completion of sources
+     */
+    public void testRunAfterBoth_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testRunAfterBoth_exceptionalCompletion() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.completeExceptionally(ex) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.completeExceptionally(ex);
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCompletedExceptionally(failFirst ? fst : snd, ex);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally if either source cancelled
+     */
+    public void testRunAfterBoth_sourceCancelled() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (boolean failFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop r1 = new Noop(m);
+        final Noop r2 = new Noop(m);
+        final Noop r3 = new Noop(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Callable<Boolean> complete1 = failFirst ?
+            () -> fst.cancel(mayInterruptIfRunning) :
+            () -> fst.complete(v1);
+        final Callable<Boolean> complete2 = failFirst ?
+            () -> snd.complete(v1) :
+            () -> snd.cancel(mayInterruptIfRunning);
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(complete1.call());
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        checkIncomplete(h1);
+        checkIncomplete(h2);
+        assertTrue(complete2.call());
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        r1.assertNotInvoked();
+        r2.assertNotInvoked();
+        r3.assertNotInvoked();
+        checkCompletedNormally(failFirst ? snd : fst, v1);
+        checkCancelled(failFirst ? fst : snd);
+    }}
+
+    /**
+     * runAfterBoth result completes exceptionally if action does
+     */
+    public void testRunAfterBoth_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingRunnable r1 = new FailingRunnable(m);
+        final FailingRunnable r2 = new FailingRunnable(m);
+        final FailingRunnable r3 = new FailingRunnable(m);
+
+        final CompletableFuture<Integer> fst =  fFirst ? f : g;
+        final CompletableFuture<Integer> snd = !fFirst ? f : g;
+        final Integer w1 =  fFirst ? v1 : v2;
+        final Integer w2 = !fFirst ? v1 : v2;
+
+        final CompletableFuture<Void> h1 = m.runAfterBoth(f, g, r1);
+        assertTrue(fst.complete(w1));
+        final CompletableFuture<Void> h2 = m.runAfterBoth(f, g, r2);
+        assertTrue(snd.complete(w2));
+        final CompletableFuture<Void> h3 = m.runAfterBoth(f, g, r3);
+
+        checkCompletedWithWrappedException(h1, r1.ex);
+        checkCompletedWithWrappedException(h2, r2.ex);
+        checkCompletedWithWrappedException(h3, r3.ex);
+        r1.assertInvoked();
+        r2.assertInvoked();
+        r3.assertInvoked();
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * applyToEither result completes normally after normal completion
+     * of either source
+     */
+    public void testApplyToEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.complete(v1);
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        rs[4].assertValue(h4.join());
+        rs[5].assertValue(h5.join());
+        assertTrue(Objects.equals(inc(v1), h4.join()) ||
+                   Objects.equals(inc(v2), h4.join()));
+        assertTrue(Objects.equals(inc(v1), h5.join()) ||
+                   Objects.equals(inc(v2), h5.join()));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, inc(v1));
+        checkCompletedNormally(h1, inc(v1));
+        checkCompletedNormally(h2, inc(v1));
+        checkCompletedNormally(h3, inc(v1));
+        for (int i = 0; i < 4; i++) rs[i].assertValue(inc(v1));
+    }}
+
+    /**
+     * applyToEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testApplyToEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.completeExceptionally(ex);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        try {
+            assertEquals(inc(v1), h4.join());
+            rs[4].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h5.join());
+            rs[5].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testApplyToEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(inc(v1), h0.join());
+            rs[0].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h1.join());
+            rs[1].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h2.join());
+            rs[2].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h3.join());
+            rs[3].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * applyToEither result completes exceptionally if either source cancelled
+     */
+    public void testApplyToEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+        try {
+            assertEquals(inc(v1), h4.join());
+            rs[4].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h5.join());
+            rs[5].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testApplyToEither_sourceCancelled2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final IncFunction[] rs = new IncFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new IncFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
+        assertTrue(!fFirst ? f.complete(v1) : g.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(inc(v1), h0.join());
+            rs[0].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h0);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h1.join());
+            rs[1].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h1);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h2.join());
+            rs[2].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h2);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(inc(v1), h3.join());
+            rs[3].assertValue(inc(v1));
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h3);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCancelled(g);
+    }}
+
+    /**
+     * applyToEither result completes exceptionally if action does
+     */
+    public void testApplyToEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingFunction[] rs = new FailingFunction[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingFunction(m);
+
+        final CompletableFuture<Integer> h0 = m.applyToEither(f, g, rs[0]);
+        final CompletableFuture<Integer> h1 = m.applyToEither(g, f, rs[1]);
+        f.complete(v1);
+        final CompletableFuture<Integer> h2 = m.applyToEither(f, g, rs[2]);
+        final CompletableFuture<Integer> h3 = m.applyToEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Integer> h4 = m.applyToEither(f, g, rs[4]);
+        final CompletableFuture<Integer> h5 = m.applyToEither(g, f, rs[5]);
+
+        checkCompletedWithWrappedException(h4, rs[4].ex);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        checkCompletedWithWrappedException(h5, rs[5].ex);
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * acceptEither result completes normally after normal completion
+     * of either source
+     */
+    public void testAcceptEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.complete(v1);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        rs[0].assertValue(v1);
+        rs[1].assertValue(v1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        rs[2].assertValue(v1);
+        rs[3].assertValue(v1);
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+    }}
+
+    /**
+     * acceptEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testAcceptEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.completeExceptionally(ex);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testAcceptEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        assertTrue(fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(null, h0.join());
+            rs[0].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h1.join());
+            rs[1].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h2.join());
+            rs[2].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h3.join());
+            rs[3].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * acceptEither result completes exceptionally if either source cancelled
+     */
+    public void testAcceptEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final NoopConsumer[] rs = new NoopConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new NoopConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+
+        g.complete(v1);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertValue(v1);
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    /**
+     * acceptEither result completes exceptionally if action does
+     */
+    public void testAcceptEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingConsumer[] rs = new FailingConsumer[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingConsumer(m);
+
+        final CompletableFuture<Void> h0 = m.acceptEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.acceptEither(g, f, rs[1]);
+        f.complete(v1);
+        final CompletableFuture<Void> h2 = m.acceptEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.acceptEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        for (int i = 0; i < 4; i++) rs[i].assertValue(v1);
+
+        g.complete(v2);
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.acceptEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.acceptEither(g, f, rs[5]);
+
+        checkCompletedWithWrappedException(h4, rs[4].ex);
+        assertTrue(Objects.equals(v1, rs[4].value) ||
+                   Objects.equals(v2, rs[4].value));
+        checkCompletedWithWrappedException(h5, rs[5].ex);
+        assertTrue(Objects.equals(v1, rs[5].value) ||
+                   Objects.equals(v2, rs[5].value));
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+    }}
+
+    /**
+     * runAfterEither result completes normally after normal completion
+     * of either source
+     */
+    public void testRunAfterEither_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+        for (boolean pushNop : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        if (pushNop) {          // ad hoc test of intra-completion interference
+            m.thenRun(f, () -> {});
+            m.thenRun(g, () -> {});
+        }
+        f.complete(v1);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        rs[0].assertInvoked();
+        rs[1].assertInvoked();
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        rs[2].assertInvoked();
+        rs[3].assertInvoked();
+
+        g.complete(v2);
+
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        checkCompletedNormally(h0, null);
+        checkCompletedNormally(h1, null);
+        checkCompletedNormally(h2, null);
+        checkCompletedNormally(h3, null);
+        checkCompletedNormally(h4, null);
+        checkCompletedNormally(h5, null);
+        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally after exceptional
+     * completion of either source
+     */
+    public void testRunAfterEither_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        assertTrue(f.completeExceptionally(ex));
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+
+        assertTrue(g.complete(v1));
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h4, ex);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h5, ex);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCompletedExceptionally(f, ex);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedException(h0, ex);
+        checkCompletedWithWrappedException(h1, ex);
+        checkCompletedWithWrappedException(h2, ex);
+        checkCompletedWithWrappedException(h3, ex);
+        checkCompletedWithWrappedException(h4, ex);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    public void testRunAfterEither_exceptionalCompletion2() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean fFirst : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CFException ex = new CFException();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        assertTrue( fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        assertTrue(!fFirst ? f.complete(v1) : g.completeExceptionally(ex));
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+
+        // unspecified behavior - both source completions available
+        try {
+            assertEquals(null, h0.join());
+            rs[0].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h0, ex);
+            rs[0].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h1.join());
+            rs[1].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h1, ex);
+            rs[1].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h2.join());
+            rs[2].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h2, ex);
+            rs[2].assertNotInvoked();
+        }
+        try {
+            assertEquals(null, h3.join());
+            rs[3].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedException(h3, ex);
+            rs[3].assertNotInvoked();
+        }
+
+        checkCompletedNormally(f, v1);
+        checkCompletedExceptionally(g, ex);
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally if either source cancelled
+     */
+    public void testRunAfterEither_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final Noop[] rs = new Noop[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new Noop(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        checkIncomplete(h0);
+        checkIncomplete(h1);
+        rs[0].assertNotInvoked();
+        rs[1].assertNotInvoked();
+        f.cancel(mayInterruptIfRunning);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+
+        assertTrue(g.complete(v1));
+
+        // unspecified behavior - both source completions available
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        try {
+            assertNull(h4.join());
+            rs[4].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h4);
+            rs[4].assertNotInvoked();
+        }
+        try {
+            assertNull(h5.join());
+            rs[5].assertInvoked();
+        } catch (CompletionException ok) {
+            checkCompletedWithWrappedCancellationException(h5);
+            rs[5].assertNotInvoked();
+        }
+
+        checkCancelled(f);
+        checkCompletedNormally(g, v1);
+        checkCompletedWithWrappedCancellationException(h0);
+        checkCompletedWithWrappedCancellationException(h1);
+        checkCompletedWithWrappedCancellationException(h2);
+        checkCompletedWithWrappedCancellationException(h3);
+        for (int i = 0; i < 4; i++) rs[i].assertNotInvoked();
+    }}
+
+    /**
+     * runAfterEither result completes exceptionally if action does
+     */
+    public void testRunAfterEither_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (Integer v1 : new Integer[] { 1, null })
+        for (Integer v2 : new Integer[] { 2, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final FailingRunnable[] rs = new FailingRunnable[6];
+        for (int i = 0; i < rs.length; i++) rs[i] = new FailingRunnable(m);
+
+        final CompletableFuture<Void> h0 = m.runAfterEither(f, g, rs[0]);
+        final CompletableFuture<Void> h1 = m.runAfterEither(g, f, rs[1]);
+        assertTrue(f.complete(v1));
+        final CompletableFuture<Void> h2 = m.runAfterEither(f, g, rs[2]);
+        final CompletableFuture<Void> h3 = m.runAfterEither(g, f, rs[3]);
+        checkCompletedWithWrappedException(h0, rs[0].ex);
+        checkCompletedWithWrappedException(h1, rs[1].ex);
+        checkCompletedWithWrappedException(h2, rs[2].ex);
+        checkCompletedWithWrappedException(h3, rs[3].ex);
+        for (int i = 0; i < 4; i++) rs[i].assertInvoked();
+        assertTrue(g.complete(v2));
+        final CompletableFuture<Void> h4 = m.runAfterEither(f, g, rs[4]);
+        final CompletableFuture<Void> h5 = m.runAfterEither(g, f, rs[5]);
+        checkCompletedWithWrappedException(h4, rs[4].ex);
+        checkCompletedWithWrappedException(h5, rs[5].ex);
+
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v2);
+        for (int i = 0; i < 6; i++) rs[i].assertInvoked();
+    }}
+
+    /**
+     * thenCompose result completes normally after normal completion of source
+     */
+    public void testThenCompose_normalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedNormally(g, inc(v1));
+        checkCompletedNormally(f, v1);
+        r.assertValue(v1);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally after exceptional
+     * completion of source
+     */
+    public void testThenCompose_exceptionalCompletion() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        final CFException ex = new CFException();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) f.completeExceptionally(ex);
+
+        checkCompletedWithWrappedException(g, ex);
+        checkCompletedExceptionally(f, ex);
+        r.assertNotInvoked();
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if action does
+     */
+    public void testThenCompose_actionFailed() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final FailingCompletableFutureFunction r
+            = new FailingCompletableFutureFunction(m);
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) assertTrue(f.complete(v1));
+
+        checkCompletedWithWrappedException(g, r.ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if source cancelled
+     */
+    public void testThenCompose_sourceCancelled() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+    {
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFutureInc r = new CompletableFutureInc(m);
+        if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
+        final CompletableFuture<Integer> g = m.thenCompose(f, r);
+        if (createIncomplete) {
+            checkIncomplete(g);
+            assertTrue(f.cancel(mayInterruptIfRunning));
+        }
+
+        checkCompletedWithWrappedCancellationException(g);
+        checkCancelled(f);
+    }}
+
+    /**
+     * thenCompose result completes exceptionally if the result of the action does
+     */
+    public void testThenCompose_actionReturnsFailingFuture() {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (int order = 0; order < 6; order++)
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> f = new CompletableFuture<>();
+        final CompletableFuture<Integer> g = new CompletableFuture<>();
+        final CompletableFuture<Integer> h;
+        // Test all permutations of orders
+        switch (order) {
+        case 0:
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            h = m.thenCompose(f, (x -> g));
+            break;
+        case 1:
+            assertTrue(f.complete(v1));
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        case 2:
+            assertTrue(g.completeExceptionally(ex));
+            assertTrue(f.complete(v1));
+            h = m.thenCompose(f, (x -> g));
+            break;
+        case 3:
+            assertTrue(g.completeExceptionally(ex));
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            break;
+        case 4:
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        case 5:
+            h = m.thenCompose(f, (x -> g));
+            assertTrue(f.complete(v1));
+            assertTrue(g.completeExceptionally(ex));
+            break;
+        default: throw new AssertionError();
+        }
+
+        checkCompletedExceptionally(g, ex);
+        checkCompletedWithWrappedException(h, ex);
+        checkCompletedNormally(f, v1);
+    }}
+
+    // other static methods
+
+    /**
+     * allOf(no component futures) returns a future completed normally
+     * with the value null
+     */
+    public void testAllOf_empty() throws Exception {
+        CompletableFuture<Void> f = CompletableFuture.allOf();
+        checkCompletedNormally(f, null);
+    }
+
+    /**
+     * allOf returns a future completed normally with the value null
+     * when all components complete normally
+     */
+    public void testAllOf_normal() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = 0; i < k; i++) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                fs[i].complete(one);
+            }
+            checkCompletedNormally(f, null);
+            checkCompletedNormally(CompletableFuture.allOf(fs), null);
+        }
+    }
+
+    public void testAllOf_normal_backwards() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = k - 1; i >= 0; i--) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                fs[i].complete(one);
+            }
+            checkCompletedNormally(f, null);
+            checkCompletedNormally(CompletableFuture.allOf(fs), null);
+        }
+    }
+
+    public void testAllOf_exceptional() throws Exception {
+        for (int k = 1; k < 10; k++) {
+            CompletableFuture<Integer>[] fs
+                = (CompletableFuture<Integer>[]) new CompletableFuture[k];
+            CFException ex = new CFException();
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Void> f = CompletableFuture.allOf(fs);
+            for (int i = 0; i < k; i++) {
+                checkIncomplete(f);
+                checkIncomplete(CompletableFuture.allOf(fs));
+                if (i != k / 2) {
+                    fs[i].complete(i);
+                    checkCompletedNormally(fs[i], i);
+                } else {
+                    fs[i].completeExceptionally(ex);
+                    checkCompletedExceptionally(fs[i], ex);
+                }
+            }
+            checkCompletedWithWrappedException(f, ex);
+            checkCompletedWithWrappedException(CompletableFuture.allOf(fs), ex);
+        }
+    }
+
+    /**
+     * anyOf(no component futures) returns an incomplete future
+     */
+    public void testAnyOf_empty() throws Exception {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Object> f = CompletableFuture.anyOf();
+        checkIncomplete(f);
+
+        f.complete(v1);
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * anyOf returns a future completed normally with a value when
+     * a component future does
+     */
+    public void testAnyOf_normal() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = 0; i < k; i++) {
+                fs[i].complete(i);
+                checkCompletedNormally(f, 0);
+                int x = (int) CompletableFuture.anyOf(fs).join();
+                assertTrue(0 <= x && x <= i);
+            }
+        }
+    }
+    public void testAnyOf_normal_backwards() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            for (int i = 0; i < k; i++)
+                fs[i] = new CompletableFuture<>();
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = k - 1; i >= 0; i--) {
+                fs[i].complete(i);
+                checkCompletedNormally(f, k - 1);
+                int x = (int) CompletableFuture.anyOf(fs).join();
+                assertTrue(i <= x && x <= k - 1);
+            }
+        }
+    }
+
+    /**
+     * anyOf result completes exceptionally when any component does.
+     */
+    public void testAnyOf_exceptional() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            CFException[] exs = new CFException[k];
+            for (int i = 0; i < k; i++) {
+                fs[i] = new CompletableFuture<>();
+                exs[i] = new CFException();
+            }
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = 0; i < k; i++) {
+                fs[i].completeExceptionally(exs[i]);
+                checkCompletedWithWrappedException(f, exs[0]);
+                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
+            }
+        }
+    }
+
+    public void testAnyOf_exceptional_backwards() throws Exception {
+        for (int k = 0; k < 10; k++) {
+            CompletableFuture[] fs = new CompletableFuture[k];
+            CFException[] exs = new CFException[k];
+            for (int i = 0; i < k; i++) {
+                fs[i] = new CompletableFuture<>();
+                exs[i] = new CFException();
+            }
+            CompletableFuture<Object> f = CompletableFuture.anyOf(fs);
+            checkIncomplete(f);
+            for (int i = k - 1; i >= 0; i--) {
+                fs[i].completeExceptionally(exs[i]);
+                checkCompletedWithWrappedException(f, exs[k - 1]);
+                checkCompletedWithWrappedCFException(CompletableFuture.anyOf(fs));
+            }
+        }
+    }
+
+    /**
+     * Completion methods throw NullPointerException with null arguments
+     */
+    public void testNPE() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        CompletableFuture<Integer> nullFuture = (CompletableFuture<Integer>)null;
+        ThreadExecutor exec = new ThreadExecutor();
+
+        Runnable[] throwingActions = {
+            () -> CompletableFuture.supplyAsync(null),
+            () -> CompletableFuture.supplyAsync(null, exec),
+            () -> CompletableFuture.supplyAsync(new IntegerSupplier(ExecutionMode.SYNC, 42), null),
+
+            () -> CompletableFuture.runAsync(null),
+            () -> CompletableFuture.runAsync(null, exec),
+            () -> CompletableFuture.runAsync(() -> {}, null),
+
+            () -> f.completeExceptionally(null),
+
+            () -> f.thenApply(null),
+            () -> f.thenApplyAsync(null),
+            () -> f.thenApplyAsync(x -> x, null),
+            () -> f.thenApplyAsync(null, exec),
+
+            () -> f.thenAccept(null),
+            () -> f.thenAcceptAsync(null),
+            () -> f.thenAcceptAsync(x -> {} , null),
+            () -> f.thenAcceptAsync(null, exec),
+
+            () -> f.thenRun(null),
+            () -> f.thenRunAsync(null),
+            () -> f.thenRunAsync(() -> {} , null),
+            () -> f.thenRunAsync(null, exec),
+
+            () -> f.thenCombine(g, null),
+            () -> f.thenCombineAsync(g, null),
+            () -> f.thenCombineAsync(g, null, exec),
+            () -> f.thenCombine(nullFuture, (x, y) -> x),
+            () -> f.thenCombineAsync(nullFuture, (x, y) -> x),
+            () -> f.thenCombineAsync(nullFuture, (x, y) -> x, exec),
+            () -> f.thenCombineAsync(g, (x, y) -> x, null),
+
+            () -> f.thenAcceptBoth(g, null),
+            () -> f.thenAcceptBothAsync(g, null),
+            () -> f.thenAcceptBothAsync(g, null, exec),
+            () -> f.thenAcceptBoth(nullFuture, (x, y) -> {}),
+            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}),
+            () -> f.thenAcceptBothAsync(nullFuture, (x, y) -> {}, exec),
+            () -> f.thenAcceptBothAsync(g, (x, y) -> {}, null),
+
+            () -> f.runAfterBoth(g, null),
+            () -> f.runAfterBothAsync(g, null),
+            () -> f.runAfterBothAsync(g, null, exec),
+            () -> f.runAfterBoth(nullFuture, () -> {}),
+            () -> f.runAfterBothAsync(nullFuture, () -> {}),
+            () -> f.runAfterBothAsync(nullFuture, () -> {}, exec),
+            () -> f.runAfterBothAsync(g, () -> {}, null),
+
+            () -> f.applyToEither(g, null),
+            () -> f.applyToEitherAsync(g, null),
+            () -> f.applyToEitherAsync(g, null, exec),
+            () -> f.applyToEither(nullFuture, x -> x),
+            () -> f.applyToEitherAsync(nullFuture, x -> x),
+            () -> f.applyToEitherAsync(nullFuture, x -> x, exec),
+            () -> f.applyToEitherAsync(g, x -> x, null),
+
+            () -> f.acceptEither(g, null),
+            () -> f.acceptEitherAsync(g, null),
+            () -> f.acceptEitherAsync(g, null, exec),
+            () -> f.acceptEither(nullFuture, x -> {}),
+            () -> f.acceptEitherAsync(nullFuture, x -> {}),
+            () -> f.acceptEitherAsync(nullFuture, x -> {}, exec),
+            () -> f.acceptEitherAsync(g, x -> {}, null),
+
+            () -> f.runAfterEither(g, null),
+            () -> f.runAfterEitherAsync(g, null),
+            () -> f.runAfterEitherAsync(g, null, exec),
+            () -> f.runAfterEither(nullFuture, () -> {}),
+            () -> f.runAfterEitherAsync(nullFuture, () -> {}),
+            () -> f.runAfterEitherAsync(nullFuture, () -> {}, exec),
+            () -> f.runAfterEitherAsync(g, () -> {}, null),
+
+            () -> f.thenCompose(null),
+            () -> f.thenComposeAsync(null),
+            () -> f.thenComposeAsync(new CompletableFutureInc(ExecutionMode.EXECUTOR), null),
+            () -> f.thenComposeAsync(null, exec),
+
+            () -> f.exceptionally(null),
+
+            () -> f.handle(null),
+
+            () -> CompletableFuture.allOf((CompletableFuture<?>)null),
+            () -> CompletableFuture.allOf((CompletableFuture<?>[])null),
+            () -> CompletableFuture.allOf(f, null),
+            () -> CompletableFuture.allOf(null, f),
+
+            () -> CompletableFuture.anyOf((CompletableFuture<?>)null),
+            () -> CompletableFuture.anyOf((CompletableFuture<?>[])null),
+            () -> CompletableFuture.anyOf(f, null),
+            () -> CompletableFuture.anyOf(null, f),
+
+            () -> f.obtrudeException(null),
+
+            () -> CompletableFuture.delayedExecutor(1L, SECONDS, null),
+            () -> CompletableFuture.delayedExecutor(1L, null, exec),
+            () -> CompletableFuture.delayedExecutor(1L, null),
+
+            () -> f.orTimeout(1L, null),
+            () -> f.completeOnTimeout(42, 1L, null),
+
+            () -> CompletableFuture.failedFuture(null),
+            () -> CompletableFuture.failedStage(null),
+        };
+
+        assertThrows(NullPointerException.class, throwingActions);
+        assertEquals(0, exec.count.get());
+    }
+
+    /**
+     * Test submissions to an executor that rejects all tasks.
+     */
+    public void testRejectingExecutor() {
+        for (Integer v : new Integer[] { 1, null })
+    {
+        final CountingRejectingExecutor e = new CountingRejectingExecutor();
+
+        final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
+        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
+
+        List<CompletableFuture<?>> futures = new ArrayList<>();
+
+        List<CompletableFuture<Integer>> srcs = new ArrayList<>();
+        srcs.add(complete);
+        srcs.add(incomplete);
+
+        for (CompletableFuture<Integer> src : srcs) {
+            List<CompletableFuture<?>> fs = new ArrayList<>();
+            fs.add(src.thenRunAsync(() -> {}, e));
+            fs.add(src.thenAcceptAsync(z -> {}, e));
+            fs.add(src.thenApplyAsync(z -> z, e));
+
+            fs.add(src.thenCombineAsync(src, (x, y) -> x, e));
+            fs.add(src.thenAcceptBothAsync(src, (x, y) -> {}, e));
+            fs.add(src.runAfterBothAsync(src, () -> {}, e));
+
+            fs.add(src.applyToEitherAsync(src, z -> z, e));
+            fs.add(src.acceptEitherAsync(src, z -> {}, e));
+            fs.add(src.runAfterEitherAsync(src, () -> {}, e));
+
+            fs.add(src.thenComposeAsync(z -> null, e));
+            fs.add(src.whenCompleteAsync((z, t) -> {}, e));
+            fs.add(src.handleAsync((z, t) -> null, e));
+
+            for (CompletableFuture<?> future : fs) {
+                if (src.isDone())
+                    checkCompletedWithWrappedException(future, e.ex);
+                else
+                    checkIncomplete(future);
+            }
+            futures.addAll(fs);
+        }
+
+        {
+            List<CompletableFuture<?>> fs = new ArrayList<>();
+
+            fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
+            fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
+
+            fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e));
+            fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {}, e));
+
+            fs.add(complete.runAfterBothAsync(incomplete, () -> {}, e));
+            fs.add(incomplete.runAfterBothAsync(complete, () -> {}, e));
+
+            for (CompletableFuture<?> future : fs)
+                checkIncomplete(future);
+            futures.addAll(fs);
+        }
+
+        {
+            List<CompletableFuture<?>> fs = new ArrayList<>();
+
+            fs.add(complete.applyToEitherAsync(incomplete, z -> z, e));
+            fs.add(incomplete.applyToEitherAsync(complete, z -> z, e));
+
+            fs.add(complete.acceptEitherAsync(incomplete, z -> {}, e));
+            fs.add(incomplete.acceptEitherAsync(complete, z -> {}, e));
+
+            fs.add(complete.runAfterEitherAsync(incomplete, () -> {}, e));
+            fs.add(incomplete.runAfterEitherAsync(complete, () -> {}, e));
+
+            for (CompletableFuture<?> future : fs)
+                checkCompletedWithWrappedException(future, e.ex);
+            futures.addAll(fs);
+        }
+
+        incomplete.complete(v);
+
+        for (CompletableFuture<?> future : futures)
+            checkCompletedWithWrappedException(future, e.ex);
+
+        assertEquals(futures.size(), e.count.get());
+    }}
+
+    /**
+     * Test submissions to an executor that rejects all tasks, but
+     * should never be invoked because the dependent future is
+     * explicitly completed.
+     */
+    public void testRejectingExecutorNeverInvoked() {
+        for (Integer v : new Integer[] { 1, null })
+    {
+        final CountingRejectingExecutor e = new CountingRejectingExecutor();
+
+        final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
+        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
+
+        List<CompletableFuture<?>> futures = new ArrayList<>();
+
+        List<CompletableFuture<Integer>> srcs = new ArrayList<>();
+        srcs.add(complete);
+        srcs.add(incomplete);
+
+        List<CompletableFuture<?>> fs = new ArrayList<>();
+        fs.add(incomplete.thenRunAsync(() -> {}, e));
+        fs.add(incomplete.thenAcceptAsync(z -> {}, e));
+        fs.add(incomplete.thenApplyAsync(z -> z, e));
+
+        fs.add(incomplete.thenCombineAsync(incomplete, (x, y) -> x, e));
+        fs.add(incomplete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e));
+        fs.add(incomplete.runAfterBothAsync(incomplete, () -> {}, e));
+
+        fs.add(incomplete.applyToEitherAsync(incomplete, z -> z, e));
+        fs.add(incomplete.acceptEitherAsync(incomplete, z -> {}, e));
+        fs.add(incomplete.runAfterEitherAsync(incomplete, () -> {}, e));
+
+        fs.add(incomplete.thenComposeAsync(z -> null, e));
+        fs.add(incomplete.whenCompleteAsync((z, t) -> {}, e));
+        fs.add(incomplete.handleAsync((z, t) -> null, e));
+
+        fs.add(complete.thenCombineAsync(incomplete, (x, y) -> x, e));
+        fs.add(incomplete.thenCombineAsync(complete, (x, y) -> x, e));
+
+        fs.add(complete.thenAcceptBothAsync(incomplete, (x, y) -> {}, e));
+        fs.add(incomplete.thenAcceptBothAsync(complete, (x, y) -> {}, e));
+
+        fs.add(complete.runAfterBothAsync(incomplete, () -> {}, e));
+        fs.add(incomplete.runAfterBothAsync(complete, () -> {}, e));
+
+        for (CompletableFuture<?> future : fs)
+            checkIncomplete(future);
+
+        for (CompletableFuture<?> future : fs)
+            future.complete(null);
+
+        incomplete.complete(v);
+
+        for (CompletableFuture<?> future : fs)
+            checkCompletedNormally(future, null);
+
+        assertEquals(0, e.count.get());
+    }}
+
+    /**
+     * toCompletableFuture returns this CompletableFuture.
+     */
+    public void testToCompletableFuture() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        assertSame(f, f.toCompletableFuture());
+    }
+
+    // jdk9
+
+    /**
+     * newIncompleteFuture returns an incomplete CompletableFuture
+     */
+    public void testNewIncompleteFuture() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = f.newIncompleteFuture();
+        checkIncomplete(f);
+        checkIncomplete(g);
+        f.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkIncomplete(g);
+        g.complete(v1);
+        checkCompletedNormally(g, v1);
+        assertSame(g.getClass(), CompletableFuture.class);
+    }}
+
+    /**
+     * completedStage returns a completed CompletionStage
+     */
+    public void testCompletedStage() {
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<>();
+        CompletionStage<Integer> f = CompletableFuture.completedStage(1);
+        f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        assertEquals(x.get(), 1);
+        assertNull(r.get());
+    }
+
+    /**
+     * defaultExecutor by default returns the commonPool if
+     * it supports more than one thread.
+     */
+    public void testDefaultExecutor() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        Executor e = f.defaultExecutor();
+        Executor c = ForkJoinPool.commonPool();
+        if (ForkJoinPool.getCommonPoolParallelism() > 1)
+            assertSame(e, c);
+        else
+            assertNotSame(e, c);
+    }
+
+    /**
+     * failedFuture returns a CompletableFuture completed
+     * exceptionally with the given Exception
+     */
+    public void testFailedFuture() {
+        CFException ex = new CFException();
+        CompletableFuture<Integer> f = CompletableFuture.failedFuture(ex);
+        checkCompletedExceptionally(f, ex);
+    }
+
+    /**
+     * failedFuture(null) throws NPE
+     */
+    public void testFailedFuture_null() {
+        try {
+            CompletableFuture<Integer> f = CompletableFuture.failedFuture(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * copy returns a CompletableFuture that is completed normally,
+     * with the same value, when source is.
+     */
+    public void testCopy_normalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        CompletableFuture<Integer> g = f.copy();
+        if (createIncomplete) {
+            checkIncomplete(f);
+            checkIncomplete(g);
+            assertTrue(f.complete(v1));
+        }
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+    }}
+
+    /**
+     * copy returns a CompletableFuture that is completed exceptionally
+     * when source is.
+     */
+    public void testCopy_exceptionalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        CFException ex = new CFException();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        CompletableFuture<Integer> g = f.copy();
+        if (createIncomplete) {
+            checkIncomplete(f);
+            checkIncomplete(g);
+            f.completeExceptionally(ex);
+        }
+        checkCompletedExceptionally(f, ex);
+        checkCompletedWithWrappedException(g, ex);
+    }}
+
+    /**
+     * Completion of a copy does not complete its source.
+     */
+    public void testCopy_oneWayPropagation() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        assertTrue(f.copy().complete(1));
+        assertTrue(f.copy().complete(null));
+        assertTrue(f.copy().cancel(true));
+        assertTrue(f.copy().cancel(false));
+        assertTrue(f.copy().completeExceptionally(new CFException()));
+        checkIncomplete(f);
+    }
+
+    /**
+     * minimalCompletionStage returns a CompletableFuture that is
+     * completed normally, with the same value, when source is.
+     */
+    public void testMinimalCompletionStage() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> g = f.minimalCompletionStage();
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<>();
+        checkIncomplete(f);
+        g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        f.complete(1);
+        checkCompletedNormally(f, 1);
+        assertEquals(x.get(), 1);
+        assertNull(r.get());
+    }
+
+    /**
+     * minimalCompletionStage returns a CompletableFuture that is
+     * completed exceptionally when source is.
+     */
+    public void testMinimalCompletionStage2() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> g = f.minimalCompletionStage();
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<>();
+        g.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        checkIncomplete(f);
+        CFException ex = new CFException();
+        f.completeExceptionally(ex);
+        checkCompletedExceptionally(f, ex);
+        assertEquals(x.get(), 0);
+        assertEquals(r.get().getCause(), ex);
+    }
+
+    /**
+     * failedStage returns a CompletionStage completed
+     * exceptionally with the given Exception
+     */
+    public void testFailedStage() {
+        CFException ex = new CFException();
+        CompletionStage<Integer> f = CompletableFuture.failedStage(ex);
+        AtomicInteger x = new AtomicInteger(0);
+        AtomicReference<Throwable> r = new AtomicReference<>();
+        f.whenComplete((v, e) -> {if (e != null) r.set(e); else x.set(v);});
+        assertEquals(x.get(), 0);
+        assertEquals(r.get(), ex);
+    }
+
+    /**
+     * completeAsync completes with value of given supplier
+     */
+    public void testCompleteAsync() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        f.completeAsync(() -> v1);
+        f.join();
+        checkCompletedNormally(f, v1);
+    }}
+
+    /**
+     * completeAsync completes exceptionally if given supplier throws
+     */
+    public void testCompleteAsync2() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        f.completeAsync(() -> { throw ex; });
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {}
+        checkCompletedWithWrappedException(f, ex);
+    }
+
+    /**
+     * completeAsync with given executor completes with value of given supplier
+     */
+    public void testCompleteAsync3() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        ThreadExecutor executor = new ThreadExecutor();
+        f.completeAsync(() -> v1, executor);
+        assertSame(v1, f.join());
+        checkCompletedNormally(f, v1);
+        assertEquals(1, executor.count.get());
+    }}
+
+    /**
+     * completeAsync with given executor completes exceptionally if
+     * given supplier throws
+     */
+    public void testCompleteAsync4() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CFException ex = new CFException();
+        ThreadExecutor executor = new ThreadExecutor();
+        f.completeAsync(() -> { throw ex; }, executor);
+        try {
+            f.join();
+            shouldThrow();
+        } catch (CompletionException success) {}
+        checkCompletedWithWrappedException(f, ex);
+        assertEquals(1, executor.count.get());
+    }
+
+    /**
+     * orTimeout completes with TimeoutException if not complete
+     */
+    public void testOrTimeout_timesOut() {
+        long timeoutMillis = timeoutMillis();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        assertSame(f, f.orTimeout(timeoutMillis, MILLISECONDS));
+        checkCompletedWithTimeoutException(f);
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+    }
+
+    /**
+     * orTimeout completes normally if completed before timeout
+     */
+    public void testOrTimeout_completed() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.complete(v1);
+        assertSame(f, f.orTimeout(LONG_DELAY_MS, MILLISECONDS));
+        assertSame(g, g.orTimeout(LONG_DELAY_MS, MILLISECONDS));
+        g.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+    }}
+
+    /**
+     * completeOnTimeout completes with given value if not complete
+     */
+    public void testCompleteOnTimeout_timesOut() {
+        testInParallel(() -> testCompleteOnTimeout_timesOut(42),
+                       () -> testCompleteOnTimeout_timesOut(null));
+    }
+
+    /**
+     * completeOnTimeout completes with given value if not complete
+     */
+    public void testCompleteOnTimeout_timesOut(Integer v) {
+        long timeoutMillis = timeoutMillis();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        assertSame(f, f.completeOnTimeout(v, timeoutMillis, MILLISECONDS));
+        assertSame(v, f.join());
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        f.complete(99);         // should have no effect
+        checkCompletedNormally(f, v);
+    }
+
+    /**
+     * completeOnTimeout has no effect if completed within timeout
+     */
+    public void testCompleteOnTimeout_completed() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        long startTime = System.nanoTime();
+        f.complete(v1);
+        assertSame(f, f.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
+        assertSame(g, g.completeOnTimeout(-1, LONG_DELAY_MS, MILLISECONDS));
+        g.complete(v1);
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS / 2);
+    }}
+
+    /**
+     * delayedExecutor returns an executor that delays submission
+     */
+    public void testDelayedExecutor() {
+        testInParallel(() -> testDelayedExecutor(null, null),
+                       () -> testDelayedExecutor(null, 1),
+                       () -> testDelayedExecutor(new ThreadExecutor(), 1),
+                       () -> testDelayedExecutor(new ThreadExecutor(), 1));
+    }
+
+    public void testDelayedExecutor(Executor executor, Integer v) throws Exception {
+        long timeoutMillis = timeoutMillis();
+        // Use an "unreasonably long" long timeout to catch lingering threads
+        long longTimeoutMillis = 1000 * 60 * 60 * 24;
+        final Executor delayer, longDelayer;
+        if (executor == null) {
+            delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS);
+            longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS);
+        } else {
+            delayer = CompletableFuture.delayedExecutor(timeoutMillis, MILLISECONDS, executor);
+            longDelayer = CompletableFuture.delayedExecutor(longTimeoutMillis, MILLISECONDS, executor);
+        }
+        long startTime = System.nanoTime();
+        CompletableFuture<Integer> f =
+            CompletableFuture.supplyAsync(() -> v, delayer);
+        CompletableFuture<Integer> g =
+            CompletableFuture.supplyAsync(() -> v, longDelayer);
+
+        assertNull(g.getNow(null));
+
+        assertSame(v, f.get(LONG_DELAY_MS, MILLISECONDS));
+        long millisElapsed = millisElapsedSince(startTime);
+        assertTrue(millisElapsed >= timeoutMillis);
+        assertTrue(millisElapsed < LONG_DELAY_MS / 2);
+
+        checkCompletedNormally(f, v);
+
+        checkIncomplete(g);
+        assertTrue(g.cancel(true));
+    }
+
+    //--- tests of implementation details; not part of official tck ---
+
+    Object resultOf(CompletableFuture<?> f) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                System.setSecurityManager(null);
+            } catch (SecurityException giveUp) {
+                return "Reflection not available";
+            }
+        }
+
+        try {
+            java.lang.reflect.Field resultField
+                = CompletableFuture.class.getDeclaredField("result");
+            resultField.setAccessible(true);
+            return resultField.get(f);
+        } catch (Throwable t) {
+            throw new AssertionError(t);
+        } finally {
+            if (sm != null) System.setSecurityManager(sm);
+        }
+    }
+
+    public void testExceptionPropagationReusesResultObject() {
+        if (!testImplementationDetails) return;
+        for (ExecutionMode m : ExecutionMode.values())
+    {
+        final CFException ex = new CFException();
+        final CompletableFuture<Integer> v42 = CompletableFuture.completedFuture(42);
+        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
+
+        final Runnable noopRunnable = new Noop(m);
+        final Consumer<Integer> noopConsumer = new NoopConsumer(m);
+        final Function<Integer, Integer> incFunction = new IncFunction(m);
+
+        List<Function<CompletableFuture<Integer>, CompletableFuture<?>>> funs
+            = new ArrayList<>();
+
+        funs.add(y -> m.thenRun(y, noopRunnable));
+        funs.add(y -> m.thenAccept(y, noopConsumer));
+        funs.add(y -> m.thenApply(y, incFunction));
+
+        funs.add(y -> m.runAfterEither(y, incomplete, noopRunnable));
+        funs.add(y -> m.acceptEither(y, incomplete, noopConsumer));
+        funs.add(y -> m.applyToEither(y, incomplete, incFunction));
+
+        funs.add(y -> m.runAfterBoth(y, v42, noopRunnable));
+        funs.add(y -> m.runAfterBoth(v42, y, noopRunnable));
+        funs.add(y -> m.thenAcceptBoth(y, v42, new SubtractAction(m)));
+        funs.add(y -> m.thenAcceptBoth(v42, y, new SubtractAction(m)));
+        funs.add(y -> m.thenCombine(y, v42, new SubtractFunction(m)));
+        funs.add(y -> m.thenCombine(v42, y, new SubtractFunction(m)));
+
+        funs.add(y -> m.whenComplete(y, (Integer r, Throwable t) -> {}));
+
+        funs.add(y -> m.thenCompose(y, new CompletableFutureInc(m)));
+
+        funs.add(y -> CompletableFuture.allOf(y));
+        funs.add(y -> CompletableFuture.allOf(y, v42));
+        funs.add(y -> CompletableFuture.allOf(v42, y));
+        funs.add(y -> CompletableFuture.anyOf(y));
+        funs.add(y -> CompletableFuture.anyOf(y, incomplete));
+        funs.add(y -> CompletableFuture.anyOf(incomplete, y));
+
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            f.completeExceptionally(ex);
+            CompletableFuture<Integer> src = m.thenApply(f, incFunction);
+            checkCompletedWithWrappedException(src, ex);
+            CompletableFuture<?> dep = fun.apply(src);
+            checkCompletedWithWrappedException(dep, ex);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            CompletableFuture<Integer> src = m.thenApply(f, incFunction);
+            CompletableFuture<?> dep = fun.apply(src);
+            f.completeExceptionally(ex);
+            checkCompletedWithWrappedException(src, ex);
+            checkCompletedWithWrappedException(dep, ex);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            f.cancel(mayInterruptIfRunning);
+            checkCancelled(f);
+            CompletableFuture<Integer> src = m.thenApply(f, incFunction);
+            checkCompletedWithWrappedCancellationException(src);
+            CompletableFuture<?> dep = fun.apply(src);
+            checkCompletedWithWrappedCancellationException(dep);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false })
+        for (Function<CompletableFuture<Integer>, CompletableFuture<?>>
+                 fun : funs) {
+            CompletableFuture<Integer> f = new CompletableFuture<>();
+            CompletableFuture<Integer> src = m.thenApply(f, incFunction);
+            CompletableFuture<?> dep = fun.apply(src);
+            f.cancel(mayInterruptIfRunning);
+            checkCancelled(f);
+            checkCompletedWithWrappedCancellationException(src);
+            checkCompletedWithWrappedCancellationException(dep);
+            assertSame(resultOf(src), resultOf(dep));
+        }
+    }}
+
+    /**
+     * Minimal completion stages throw UOE for most non-CompletionStage methods
+     */
+    public void testMinimalCompletionStage_minimality() {
+        if (!testImplementationDetails) return;
+        Function<Method, String> toSignature =
+            method -> method.getName() + Arrays.toString(method.getParameterTypes());
+        Predicate<Method> isNotStatic =
+            method -> (method.getModifiers() & Modifier.STATIC) == 0;
+        List<Method> minimalMethods =
+            Stream.of(Object.class, CompletionStage.class)
+            .flatMap(klazz -> Stream.of(klazz.getMethods()))
+            .filter(isNotStatic)
+            .collect(Collectors.toList());
+        // Methods from CompletableFuture permitted NOT to throw UOE
+        String[] signatureWhitelist = {
+            "newIncompleteFuture[]",
+            "defaultExecutor[]",
+            "minimalCompletionStage[]",
+            "copy[]",
+        };
+        Set<String> permittedMethodSignatures =
+            Stream.concat(minimalMethods.stream().map(toSignature),
+                          Stream.of(signatureWhitelist))
+            .collect(Collectors.toSet());
+        List<Method> allMethods = Stream.of(CompletableFuture.class.getMethods())
+            .filter(isNotStatic)
+            .filter(method -> !permittedMethodSignatures.contains(toSignature.apply(method)))
+            .collect(Collectors.toList());
+
+        List<CompletionStage<Integer>> stages = new ArrayList<>();
+        CompletionStage<Integer> min =
+            new CompletableFuture<Integer>().minimalCompletionStage();
+        stages.add(min);
+        stages.add(min.thenApply(x -> x));
+        stages.add(CompletableFuture.completedStage(1));
+        stages.add(CompletableFuture.failedStage(new CFException()));
+
+        List<Method> bugs = new ArrayList<>();
+        for (Method method : allMethods) {
+            Class<?>[] parameterTypes = method.getParameterTypes();
+            Object[] args = new Object[parameterTypes.length];
+            // Manufacture boxed primitives for primitive params
+            for (int i = 0; i < args.length; i++) {
+                Class<?> type = parameterTypes[i];
+                if (parameterTypes[i] == boolean.class)
+                    args[i] = false;
+                else if (parameterTypes[i] == int.class)
+                    args[i] = 0;
+                else if (parameterTypes[i] == long.class)
+                    args[i] = 0L;
+            }
+            for (CompletionStage<Integer> stage : stages) {
+                try {
+                    method.invoke(stage, args);
+                    bugs.add(method);
+                }
+                catch (java.lang.reflect.InvocationTargetException expected) {
+                    if (! (expected.getCause() instanceof UnsupportedOperationException)) {
+                        bugs.add(method);
+                        // expected.getCause().printStackTrace();
+                    }
+                }
+                catch (ReflectiveOperationException bad) { throw new Error(bad); }
+            }
+        }
+        if (!bugs.isEmpty())
+            throw new Error("Methods did not throw UOE: " + bugs);
+    }
+
+    /**
+     * minimalStage.toCompletableFuture() returns a CompletableFuture that
+     * is completed normally, with the same value, when source is.
+     */
+    public void testMinimalCompletionStage_toCompletableFuture_normalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> minimal = f.minimalCompletionStage();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        CompletableFuture<Integer> g = minimal.toCompletableFuture();
+        if (createIncomplete) {
+            checkIncomplete(f);
+            checkIncomplete(g);
+            assertTrue(f.complete(v1));
+        }
+        checkCompletedNormally(f, v1);
+        checkCompletedNormally(g, v1);
+    }}
+
+    /**
+     * minimalStage.toCompletableFuture() returns a CompletableFuture that
+     * is completed exceptionally when source is.
+     */
+    public void testMinimalCompletionStage_toCompletableFuture_exceptionalCompletion() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+    {
+        CFException ex = new CFException();
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> minimal = f.minimalCompletionStage();
+        if (!createIncomplete) f.completeExceptionally(ex);
+        CompletableFuture<Integer> g = minimal.toCompletableFuture();
+        if (createIncomplete) {
+            checkIncomplete(f);
+            checkIncomplete(g);
+            f.completeExceptionally(ex);
+        }
+        checkCompletedExceptionally(f, ex);
+        checkCompletedWithWrappedException(g, ex);
+    }}
+
+    /**
+     * minimalStage.toCompletableFuture() gives mutable CompletableFuture
+     */
+    public void testMinimalCompletionStage_toCompletableFuture_mutable() {
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage minimal = f.minimalCompletionStage();
+        CompletableFuture<Integer> g = minimal.toCompletableFuture();
+        assertTrue(g.complete(v1));
+        checkCompletedNormally(g, v1);
+        checkIncomplete(f);
+        checkIncomplete(minimal.toCompletableFuture());
+    }}
+
+    /**
+     * minimalStage.toCompletableFuture().join() awaits completion
+     */
+    public void testMinimalCompletionStage_toCompletableFuture_join() throws Exception {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        CompletionStage<Integer> minimal = f.minimalCompletionStage();
+        if (createIncomplete) assertTrue(f.complete(v1));
+        assertEquals(v1, minimal.toCompletableFuture().join());
+        assertEquals(v1, minimal.toCompletableFuture().get());
+        checkCompletedNormally(minimal.toCompletableFuture(), v1);
+    }}
+
+    /**
+     * Completion of a toCompletableFuture copy of a minimal stage
+     * does not complete its source.
+     */
+    public void testMinimalCompletionStage_toCompletableFuture_oneWayPropagation() {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> g = f.minimalCompletionStage();
+        assertTrue(g.toCompletableFuture().complete(1));
+        assertTrue(g.toCompletableFuture().complete(null));
+        assertTrue(g.toCompletableFuture().cancel(true));
+        assertTrue(g.toCompletableFuture().cancel(false));
+        assertTrue(g.toCompletableFuture().completeExceptionally(new CFException()));
+        checkIncomplete(g.toCompletableFuture());
+        f.complete(1);
+        checkCompletedNormally(g.toCompletableFuture(), 1);
+    }
+
+    /** Demo utility method for external reliable toCompletableFuture */
+    static <T> CompletableFuture<T> toCompletableFuture(CompletionStage<T> stage) {
+        CompletableFuture<T> f = new CompletableFuture<>();
+        stage.handle((T t, Throwable ex) -> {
+                         if (ex != null) f.completeExceptionally(ex);
+                         else f.complete(t);
+                         return null;
+                     });
+        return f;
+    }
+
+    /** Demo utility method to join a CompletionStage */
+    static <T> T join(CompletionStage<T> stage) {
+        return toCompletableFuture(stage).join();
+    }
+
+    /**
+     * Joining a minimal stage "by hand" works
+     */
+    public void testMinimalCompletionStage_join_by_hand() {
+        for (boolean createIncomplete : new boolean[] { true, false })
+        for (Integer v1 : new Integer[] { 1, null })
+    {
+        CompletableFuture<Integer> f = new CompletableFuture<>();
+        CompletionStage<Integer> minimal = f.minimalCompletionStage();
+        CompletableFuture<Integer> g = new CompletableFuture<>();
+        if (!createIncomplete) assertTrue(f.complete(v1));
+        minimal.thenAccept(x -> g.complete(x));
+        if (createIncomplete) assertTrue(f.complete(v1));
+        g.join();
+        checkCompletedNormally(g, v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(v1, join(minimal));
+    }}
+
+    static class Monad {
+        static class ZeroException extends RuntimeException {
+            public ZeroException() { super("monadic zero"); }
+        }
+        // "return", "unit"
+        static <T> CompletableFuture<T> unit(T value) {
+            return completedFuture(value);
+        }
+        // monadic zero ?
+        static <T> CompletableFuture<T> zero() {
+            return failedFuture(new ZeroException());
+        }
+        // >=>
+        static <T,U,V> Function<T, CompletableFuture<V>> compose
+            (Function<T, CompletableFuture<U>> f,
+             Function<U, CompletableFuture<V>> g) {
+            return x -> f.apply(x).thenCompose(g);
+        }
+
+        static void assertZero(CompletableFuture<?> f) {
+            try {
+                f.getNow(null);
+                throw new AssertionFailedError("should throw");
+            } catch (CompletionException success) {
+                assertTrue(success.getCause() instanceof ZeroException);
+            }
+        }
+
+        static <T> void assertFutureEquals(CompletableFuture<T> f,
+                                           CompletableFuture<T> g) {
+            T fval = null, gval = null;
+            Throwable fex = null, gex = null;
+
+            try { fval = f.get(); }
+            catch (ExecutionException ex) { fex = ex.getCause(); }
+            catch (Throwable ex) { fex = ex; }
+
+            try { gval = g.get(); }
+            catch (ExecutionException ex) { gex = ex.getCause(); }
+            catch (Throwable ex) { gex = ex; }
+
+            if (fex != null || gex != null)
+                assertSame(fex.getClass(), gex.getClass());
+            else
+                assertEquals(fval, gval);
+        }
+
+        static class PlusFuture<T> extends CompletableFuture<T> {
+            AtomicReference<Throwable> firstFailure = new AtomicReference<>(null);
+        }
+
+        /** Implements "monadic plus". */
+        static <T> CompletableFuture<T> plus(CompletableFuture<? extends T> f,
+                                             CompletableFuture<? extends T> g) {
+            PlusFuture<T> plus = new PlusFuture<T>();
+            BiConsumer<T, Throwable> action = (T result, Throwable ex) -> {
+                try {
+                    if (ex == null) {
+                        if (plus.complete(result))
+                            if (plus.firstFailure.get() != null)
+                                plus.firstFailure.set(null);
+                    }
+                    else if (plus.firstFailure.compareAndSet(null, ex)) {
+                        if (plus.isDone())
+                            plus.firstFailure.set(null);
+                    }
+                    else {
+                        // first failure has precedence
+                        Throwable first = plus.firstFailure.getAndSet(null);
+
+                        // may fail with "Self-suppression not permitted"
+                        try { first.addSuppressed(ex); }
+                        catch (Exception ignored) {}
+
+                        plus.completeExceptionally(first);
+                    }
+                } catch (Throwable unexpected) {
+                    plus.completeExceptionally(unexpected);
+                }
+            };
+            f.whenComplete(action);
+            g.whenComplete(action);
+            return plus;
+        }
+    }
+
+    /**
+     * CompletableFuture is an additive monad - sort of.
+     * https://en.wikipedia.org/wiki/Monad_(functional_programming)#Additive_monads
+     */
+    public void testAdditiveMonad() throws Throwable {
+        Function<Long, CompletableFuture<Long>> unit = Monad::unit;
+        CompletableFuture<Long> zero = Monad.zero();
+
+        // Some mutually non-commutative functions
+        Function<Long, CompletableFuture<Long>> triple
+            = x -> Monad.unit(3 * x);
+        Function<Long, CompletableFuture<Long>> inc
+            = x -> Monad.unit(x + 1);
+
+        // unit is a right identity: m >>= unit === m
+        Monad.assertFutureEquals(inc.apply(5L).thenCompose(unit),
+                                 inc.apply(5L));
+        // unit is a left identity: (unit x) >>= f === f x
+        Monad.assertFutureEquals(unit.apply(5L).thenCompose(inc),
+                                 inc.apply(5L));
+
+        // associativity: (m >>= f) >>= g === m >>= ( \x -> (f x >>= g) )
+        Monad.assertFutureEquals(
+            unit.apply(5L).thenCompose(inc).thenCompose(triple),
+            unit.apply(5L).thenCompose(x -> inc.apply(x).thenCompose(triple)));
+
+        // The case for CompletableFuture as an additive monad is weaker...
+
+        // zero is a monadic zero
+        Monad.assertZero(zero);
+
+        // left zero: zero >>= f === zero
+        Monad.assertZero(zero.thenCompose(inc));
+        // right zero: f >>= (\x -> zero) === zero
+        Monad.assertZero(inc.apply(5L).thenCompose(x -> zero));
+
+        // f plus zero === f
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(Monad.unit(5L), zero));
+        // zero plus f === f
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(zero, Monad.unit(5L)));
+        // zero plus zero === zero
+        Monad.assertZero(Monad.plus(zero, zero));
+        {
+            CompletableFuture<Long> f = Monad.plus(Monad.unit(5L),
+                                                   Monad.unit(8L));
+            // non-determinism
+            assertTrue(f.get() == 5L || f.get() == 8L);
+        }
+
+        CompletableFuture<Long> godot = new CompletableFuture<>();
+        // f plus godot === f (doesn't wait for godot)
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(Monad.unit(5L), godot));
+        // godot plus f === f (doesn't wait for godot)
+        Monad.assertFutureEquals(Monad.unit(5L),
+                                 Monad.plus(godot, Monad.unit(5L)));
+    }
+
+    /** Test long recursive chains of CompletableFutures with cascading completions */
+    public void testRecursiveChains() throws Throwable {
+        for (ExecutionMode m : ExecutionMode.values())
+        for (boolean addDeadEnds : new boolean[] { true, false })
+    {
+        final int val = 42;
+        final int n = expensiveTests ? 1_000 : 2;
+        CompletableFuture<Integer> head = new CompletableFuture<>();
+        CompletableFuture<Integer> tail = head;
+        for (int i = 0; i < n; i++) {
+            if (addDeadEnds) m.thenApply(tail, v -> v + 1);
+            tail = m.thenApply(tail, v -> v + 1);
+            if (addDeadEnds) m.applyToEither(tail, tail, v -> v + 1);
+            tail = m.applyToEither(tail, tail, v -> v + 1);
+            if (addDeadEnds) m.thenCombine(tail, tail, (v, w) -> v + 1);
+            tail = m.thenCombine(tail, tail, (v, w) -> v + 1);
+        }
+        head.complete(val);
+        assertEquals(val + 3 * n, (int) tail.join());
+    }}
+
+    /**
+     * A single CompletableFuture with many dependents.
+     * A demo of scalability - runtime is O(n).
+     */
+    public void testManyDependents() throws Throwable {
+        final int n = expensiveTests ? 1_000_000 : 10;
+        final CompletableFuture<Void> head = new CompletableFuture<>();
+        final CompletableFuture<Void> complete = CompletableFuture.completedFuture((Void)null);
+        final AtomicInteger count = new AtomicInteger(0);
+        for (int i = 0; i < n; i++) {
+            head.thenRun(() -> count.getAndIncrement());
+            head.thenAccept(x -> count.getAndIncrement());
+            head.thenApply(x -> count.getAndIncrement());
+
+            head.runAfterBoth(complete, () -> count.getAndIncrement());
+            head.thenAcceptBoth(complete, (x, y) -> count.getAndIncrement());
+            head.thenCombine(complete, (x, y) -> count.getAndIncrement());
+            complete.runAfterBoth(head, () -> count.getAndIncrement());
+            complete.thenAcceptBoth(head, (x, y) -> count.getAndIncrement());
+            complete.thenCombine(head, (x, y) -> count.getAndIncrement());
+
+            head.runAfterEither(new CompletableFuture<Void>(), () -> count.getAndIncrement());
+            head.acceptEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
+            head.applyToEither(new CompletableFuture<Void>(), x -> count.getAndIncrement());
+            new CompletableFuture<Void>().runAfterEither(head, () -> count.getAndIncrement());
+            new CompletableFuture<Void>().acceptEither(head, x -> count.getAndIncrement());
+            new CompletableFuture<Void>().applyToEither(head, x -> count.getAndIncrement());
+        }
+        head.complete(null);
+        assertEquals(5 * 3 * n, count.get());
+    }
+
+    /** ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest tck */
+    public void testCoCompletionGarbageRetention() throws Throwable {
+        final int n = expensiveTests ? 1_000_000 : 10;
+        final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
+        CompletableFuture<Integer> f;
+        for (int i = 0; i < n; i++) {
+            f = new CompletableFuture<>();
+            f.runAfterEither(incomplete, () -> {});
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            f.acceptEither(incomplete, x -> {});
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            f.applyToEither(incomplete, x -> x);
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            CompletableFuture.anyOf(new CompletableFuture<?>[] { f, incomplete });
+            f.complete(null);
+        }
+
+        for (int i = 0; i < n; i++) {
+            f = new CompletableFuture<>();
+            incomplete.runAfterEither(f, () -> {});
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            incomplete.acceptEither(f, x -> {});
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            incomplete.applyToEither(f, x -> x);
+            f.complete(null);
+
+            f = new CompletableFuture<>();
+            CompletableFuture.anyOf(new CompletableFuture<?>[] { incomplete, f });
+            f.complete(null);
+        }
+    }
+
+    /**
+     * Reproduction recipe for:
+     * 8160402: Garbage retention with CompletableFuture.anyOf
+     * cvs update -D '2016-05-01' ./src/main/java/util/concurrent/CompletableFuture.java && ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testAnyOfGarbageRetention tck; cvs update -A
+     */
+    public void testAnyOfGarbageRetention() throws Throwable {
+        for (Integer v : new Integer[] { 1, null })
+    {
+        final int n = expensiveTests ? 100_000 : 10;
+        CompletableFuture<Integer>[] fs
+            = (CompletableFuture<Integer>[]) new CompletableFuture<?>[100];
+        for (int i = 0; i < fs.length; i++)
+            fs[i] = new CompletableFuture<>();
+        fs[fs.length - 1].complete(v);
+        for (int i = 0; i < n; i++)
+            checkCompletedNormally(CompletableFuture.anyOf(fs), v);
+    }}
+
+    /**
+     * Checks for garbage retention with allOf.
+     *
+     * As of 2016-07, fails with OOME:
+     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledAllOfGarbageRetention tck
+     */
+    public void testCancelledAllOfGarbageRetention() throws Throwable {
+        final int n = expensiveTests ? 100_000 : 10;
+        CompletableFuture<Integer>[] fs
+            = (CompletableFuture<Integer>[]) new CompletableFuture<?>[100];
+        for (int i = 0; i < fs.length; i++)
+            fs[i] = new CompletableFuture<>();
+        for (int i = 0; i < n; i++)
+            assertTrue(CompletableFuture.allOf(fs).cancel(false));
+    }
+
+    /**
+     * Checks for garbage retention when a dependent future is
+     * cancelled and garbage-collected.
+     * 8161600: Garbage retention when source CompletableFutures are never completed
+     *
+     * As of 2016-07, fails with OOME:
+     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testCancelledGarbageRetention tck
+     */
+    public void testCancelledGarbageRetention() throws Throwable {
+        final int n = expensiveTests ? 100_000 : 10;
+        CompletableFuture<Integer> neverCompleted = new CompletableFuture<>();
+        for (int i = 0; i < n; i++)
+            assertTrue(neverCompleted.thenRun(() -> {}).cancel(true));
+    }
+
+    /**
+     * Checks for garbage retention when MinimalStage.toCompletableFuture()
+     * is invoked many times.
+     * 8161600: Garbage retention when source CompletableFutures are never completed
+     *
+     * As of 2016-07, fails with OOME:
+     * ant -Dvmoptions=-Xmx8m -Djsr166.expensiveTests=true -Djsr166.tckTestClass=CompletableFutureTest -Djsr166.methodFilter=testToCompletableFutureGarbageRetention tck
+     */
+    public void testToCompletableFutureGarbageRetention() throws Throwable {
+        final int n = expensiveTests ? 900_000 : 10;
+        CompletableFuture<Integer> neverCompleted = new CompletableFuture<>();
+        CompletionStage minimal = neverCompleted.minimalCompletionStage();
+        for (int i = 0; i < n; i++)
+            assertTrue(minimal.toCompletableFuture().cancel(true));
+    }
+
+//     static <U> U join(CompletionStage<U> stage) {
+//         CompletableFuture<U> f = new CompletableFuture<>();
+//         stage.whenComplete((v, ex) -> {
+//             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
+//         });
+//         return f.join();
+//     }
+
+//     static <U> boolean isDone(CompletionStage<U> stage) {
+//         CompletableFuture<U> f = new CompletableFuture<>();
+//         stage.whenComplete((v, ex) -> {
+//             if (ex != null) f.completeExceptionally(ex); else f.complete(v);
+//         });
+//         return f.isDone();
+//     }
+
+//     static <U> U join2(CompletionStage<U> stage) {
+//         return stage.toCompletableFuture().copy().join();
+//     }
+
+//     static <U> boolean isDone2(CompletionStage<U> stage) {
+//         return stage.toCompletableFuture().copy().isDone();
+//     }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java
new file mode 100644
index 0000000..324a5ef
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMap8Test.java
@@ -0,0 +1,1147 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.Spliterator.CONCURRENT;
+import static java.util.Spliterator.DISTINCT;
+import static java.util.Spliterator.NONNULL;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.function.BiFunction;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentHashMap8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentHashMap8Test.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentHashMap map5() {
+        ConcurrentHashMap map = new ConcurrentHashMap(5);
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(two, "B");
+        map.put(three, "C");
+        map.put(four, "D");
+        map.put(five, "E");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /**
+     * getOrDefault returns value if present, else default
+     */
+    public void testGetOrDefault() {
+        ConcurrentHashMap map = map5();
+        assertEquals(map.getOrDefault(one, "Z"), "A");
+        assertEquals(map.getOrDefault(six, "Z"), "Z");
+    }
+
+    /**
+     * computeIfAbsent adds when the given key is not present
+     */
+    public void testComputeIfAbsent() {
+        ConcurrentHashMap map = map5();
+        map.computeIfAbsent(six, x -> "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * computeIfAbsent does not replace if the key is already present
+     */
+    public void testComputeIfAbsent2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", map.computeIfAbsent(one, x -> "Z"));
+    }
+
+    /**
+     * computeIfAbsent does not add if function returns null
+     */
+    public void testComputeIfAbsent3() {
+        ConcurrentHashMap map = map5();
+        map.computeIfAbsent(six, x -> null);
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * computeIfPresent does not replace if the key is already present
+     */
+    public void testComputeIfPresent() {
+        ConcurrentHashMap map = map5();
+        map.computeIfPresent(six, (x, y) -> "Z");
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * computeIfPresent adds when the given key is not present
+     */
+    public void testComputeIfPresent2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.computeIfPresent(one, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute does not replace if the function returns null
+     */
+    public void testCompute() {
+        ConcurrentHashMap map = map5();
+        map.compute(six, (x, y) -> null);
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * compute adds when the given key is not present
+     */
+    public void testCompute2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.compute(six, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute replaces when the given key is present
+     */
+    public void testCompute3() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.compute(one, (x, y) -> "Z"));
+    }
+
+    /**
+     * compute removes when the given key is present and function returns null
+     */
+    public void testCompute4() {
+        ConcurrentHashMap map = map5();
+        map.compute(one, (x, y) -> null);
+        assertFalse(map.containsKey(one));
+    }
+
+    /**
+     * merge adds when the given key is not present
+     */
+    public void testMerge1() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Y", map.merge(six, "Y", (x, y) -> "Z"));
+    }
+
+    /**
+     * merge replaces when the given key is present
+     */
+    public void testMerge2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("Z", map.merge(one, "Y", (x, y) -> "Z"));
+    }
+
+    /**
+     * merge removes when the given key is present and function returns null
+     */
+    public void testMerge3() {
+        ConcurrentHashMap map = map5();
+        map.merge(one, "Y", (x, y) -> null);
+        assertFalse(map.containsKey(one));
+    }
+
+    static Set<Integer> populatedSet(int n) {
+        Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < n; i++)
+            assertTrue(a.add(i));
+        assertEquals(n == 0, a.isEmpty());
+        assertEquals(n, a.size());
+        return a;
+    }
+
+    static Set populatedSet(Integer[] elements) {
+        Set<Integer> a = ConcurrentHashMap.<Integer>newKeySet();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < elements.length; i++)
+            assertTrue(a.add(elements[i]));
+        assertFalse(a.isEmpty());
+        assertEquals(elements.length, a.size());
+        return a;
+    }
+
+    /**
+     * replaceAll replaces all matching values.
+     */
+    public void testReplaceAll() {
+        ConcurrentHashMap<Integer, String> map = map5();
+        map.replaceAll((x, y) -> { return x > 3 ? "Z" : y; });
+        assertEquals("A", map.get(one));
+        assertEquals("B", map.get(two));
+        assertEquals("C", map.get(three));
+        assertEquals("Z", map.get(four));
+        assertEquals("Z", map.get(five));
+    }
+
+    /**
+     * Default-constructed set is empty
+     */
+    public void testNewKeySet() {
+        Set a = ConcurrentHashMap.newKeySet();
+        assertTrue(a.isEmpty());
+    }
+
+    /**
+     * keySet.add adds the key with the established value to the map;
+     * remove removes it.
+     */
+    public void testKeySetAddRemove() {
+        ConcurrentHashMap map = map5();
+        Set set1 = map.keySet();
+        Set set2 = map.keySet(true);
+        set2.add(six);
+        assertTrue(((ConcurrentHashMap.KeySetView)set2).getMap() == map);
+        assertTrue(((ConcurrentHashMap.KeySetView)set1).getMap() == map);
+        assertEquals(set2.size(), map.size());
+        assertEquals(set1.size(), map.size());
+        assertTrue((Boolean)map.get(six));
+        assertTrue(set1.contains(six));
+        assertTrue(set2.contains(six));
+        set2.remove(six);
+        assertNull(map.get(six));
+        assertFalse(set1.contains(six));
+        assertFalse(set2.contains(six));
+    }
+
+    /**
+     * keySet.addAll adds each element from the given collection
+     */
+    public void testAddAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+    }
+
+    /**
+     * keySet.addAll adds each element from the given collection that did not
+     * already exist in the set
+     */
+    public void testAddAll2() {
+        Set full = populatedSet(3);
+        // "one" is duplicate and will not be added
+        assertTrue(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+    }
+
+    /**
+     * keySet.add will not add the element if it already exists in the set
+     */
+    public void testAdd2() {
+        Set full = populatedSet(3);
+        assertFalse(full.add(one));
+        assertEquals(3, full.size());
+    }
+
+    /**
+     * keySet.add adds the element when it does not exist in the set
+     */
+    public void testAdd3() {
+        Set full = populatedSet(3);
+        assertTrue(full.add(three));
+        assertTrue(full.contains(three));
+        assertFalse(full.add(three));
+        assertTrue(full.contains(three));
+    }
+
+    /**
+     * keySet.add throws UnsupportedOperationException if no default
+     * mapped value
+     */
+    public void testAdd4() {
+        Set full = map5().keySet();
+        try {
+            full.add(three);
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * keySet.add throws NullPointerException if the specified key is
+     * null
+     */
+    public void testAdd5() {
+        Set full = populatedSet(3);
+        try {
+            full.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * KeySetView.getMappedValue returns the map's mapped value
+     */
+    public void testGetMappedValue() {
+        ConcurrentHashMap map = map5();
+        // Android-changed: ConcurrentHashMap.keySet() has 2 return type variants on Android.
+        assertNull(((ConcurrentHashMap.KeySetView)map.keySet()).getMappedValue());
+        try {
+            map.keySet(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+        ConcurrentHashMap.KeySetView set = map.keySet(one);
+        assertFalse(set.add(one));
+        assertTrue(set.add(six));
+        assertTrue(set.add(seven));
+        assertTrue(set.getMappedValue() == one);
+        assertTrue(map.get(one) != one);
+        assertTrue(map.get(six) == one);
+        assertTrue(map.get(seven) == one);
+    }
+
+    void checkSpliteratorCharacteristics(Spliterator<?> sp,
+                                         int requiredCharacteristics) {
+        assertEquals(requiredCharacteristics,
+                     requiredCharacteristics & sp.characteristics());
+    }
+
+    /**
+     * KeySetView.spliterator returns spliterator over the elements in this set
+     */
+    public void testKeySetSpliterator() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap map = map5();
+        Set set = map.keySet();
+        Spliterator<Integer> sp = set.spliterator();
+        checkSpliteratorCharacteristics(sp, CONCURRENT | DISTINCT | NONNULL);
+        assertEquals(sp.estimateSize(), map.size());
+        Spliterator<Integer> sp2 = sp.trySplit();
+        sp.forEachRemaining((Integer x) -> adder.add(x.longValue()));
+        long v = adder.sumThenReset();
+        sp2.forEachRemaining((Integer x) -> adder.add(x.longValue()));
+        long v2 = adder.sum();
+        assertEquals(v + v2, 15);
+    }
+
+    /**
+     * keyset.clear removes all elements from the set
+     */
+    public void testClear() {
+        Set full = populatedSet(3);
+        full.clear();
+        assertEquals(0, full.size());
+    }
+
+    /**
+     * keyset.contains returns true for added elements
+     */
+    public void testContains() {
+        Set full = populatedSet(3);
+        assertTrue(full.contains(one));
+        assertFalse(full.contains(five));
+    }
+
+    /**
+     * KeySets with equal elements are equal
+     */
+    public void testEquals() {
+        Set a = populatedSet(3);
+        Set b = populatedSet(3);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        a.add(m1);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        b.add(m1);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertEquals(a.hashCode(), b.hashCode());
+    }
+
+    /**
+     * KeySet.containsAll returns true for collections with subset of elements
+     */
+    public void testContainsAll() {
+        Collection full = populatedSet(3);
+        assertTrue(full.containsAll(Arrays.asList()));
+        assertTrue(full.containsAll(Arrays.asList(one)));
+        assertTrue(full.containsAll(Arrays.asList(one, two)));
+        assertFalse(full.containsAll(Arrays.asList(one, two, six)));
+        assertFalse(full.containsAll(Arrays.asList(six)));
+    }
+
+    /**
+     * KeySet.isEmpty is true when empty, else false
+     */
+    public void testIsEmpty() {
+        assertTrue(populatedSet(0).isEmpty());
+        assertFalse(populatedSet(3).isEmpty());
+    }
+
+    /**
+     * KeySet.iterator() returns an iterator containing the elements of the
+     * set
+     */
+    public void testIterator() {
+        Collection empty = ConcurrentHashMap.newKeySet();
+        int size = 20;
+        assertFalse(empty.iterator().hasNext());
+        try {
+            empty.iterator().next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        Iterator it = full.iterator();
+        for (int j = 0; j < size; j++) {
+            assertTrue(it.hasNext());
+            it.next();
+        }
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collections has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(ConcurrentHashMap.newKeySet().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().entrySet().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().values().iterator());
+        assertIteratorExhausted(new ConcurrentHashMap().keySet().iterator());
+    }
+
+    /**
+     * KeySet.iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        Set q = populatedSet(3);
+        Iterator it = q.iterator();
+        Object removed = it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertFalse(it.next().equals(removed));
+        assertFalse(it.next().equals(removed));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * KeySet.toString holds toString of elements
+     */
+    public void testToString() {
+        assertEquals("[]", ConcurrentHashMap.newKeySet().toString());
+        Set full = populatedSet(3);
+        String s = full.toString();
+        for (int i = 0; i < 3; ++i)
+            assertTrue(s.contains(String.valueOf(i)));
+    }
+
+    /**
+     * KeySet.removeAll removes all elements from the given collection
+     */
+    public void testRemoveAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+        assertFalse(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+    }
+
+    /**
+     * KeySet.remove removes an element
+     */
+    public void testRemove() {
+        Set full = populatedSet(3);
+        full.remove(one);
+        assertFalse(full.contains(one));
+        assertEquals(2, full.size());
+    }
+
+    /**
+     * keySet.size returns the number of elements
+     */
+    public void testSize() {
+        Set empty = ConcurrentHashMap.newKeySet();
+        Set full = populatedSet(3);
+        assertEquals(3, full.size());
+        assertEquals(0, empty.size());
+    }
+
+    /**
+     * KeySet.toArray() returns an Object array containing all elements from
+     * the set
+     */
+    public void testToArray() {
+        Object[] a = ConcurrentHashMap.newKeySet().toArray();
+        assertTrue(Arrays.equals(new Object[0], a));
+        assertSame(Object[].class, a.getClass());
+        int size = 20;
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray())));
+        assertTrue(full.containsAll(Arrays.asList(full.toArray())));
+        assertSame(Object[].class, full.toArray().getClass());
+    }
+
+    /**
+     * toArray(Integer array) returns an Integer array containing all
+     * elements from the set
+     */
+    public void testToArray2() {
+        Collection empty = ConcurrentHashMap.newKeySet();
+        Integer[] a;
+        int size = 20;
+
+        a = new Integer[0];
+        assertSame(a, empty.toArray(a));
+
+        a = new Integer[size / 2];
+        Arrays.fill(a, 42);
+        assertSame(a, empty.toArray(a));
+        assertNull(a[0]);
+        for (int i = 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+
+        Integer[] elements = new Integer[size];
+        for (int i = 0; i < size; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        Arrays.fill(a, 42);
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
+        for (int i = 0; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+        assertSame(Integer[].class, full.toArray(a).getClass());
+
+        a = new Integer[size];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray(a))));
+    }
+
+    /**
+     * A deserialized serialized set is equal
+     */
+    public void testSerialization() throws Exception {
+        int size = 20;
+        Set x = populatedSet(size);
+        Set y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    static final int SIZE = 10000;
+    static ConcurrentHashMap<Long, Long> longMap;
+
+    static ConcurrentHashMap<Long, Long> longMap() {
+        if (longMap == null) {
+            longMap = new ConcurrentHashMap<Long, Long>(SIZE);
+            for (int i = 0; i < SIZE; ++i)
+                longMap.put(Long.valueOf(i), Long.valueOf(2 *i));
+        }
+        return longMap;
+    }
+
+    // explicit function class to avoid type inference problems
+    static class AddKeys implements BiFunction<Map.Entry<Long,Long>, Map.Entry<Long,Long>, Map.Entry<Long,Long>> {
+        public Map.Entry<Long,Long> apply(Map.Entry<Long,Long> x, Map.Entry<Long,Long> y) {
+            return new AbstractMap.SimpleEntry<Long,Long>
+             (Long.valueOf(x.getKey().longValue() + y.getKey().longValue()),
+              Long.valueOf(1L));
+        }
+    }
+
+    /**
+     * forEachKeySequentially traverses all keys
+     */
+    public void testForEachKeySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachValueSequentially traverses all values
+     */
+    public void testForEachValueSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(Long.MAX_VALUE, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1));
+    }
+
+    /**
+     * forEachSequentially traverses all mappings
+     */
+    public void testForEachSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(Long.MAX_VALUE, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachEntrySequentially traverses all entries
+     */
+    public void testForEachEntrySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachKeyInParallel traverses all keys
+     */
+    public void testForEachKeyInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(1L, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachValueInParallel traverses all values
+     */
+    public void testForEachValueInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(1L, (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), SIZE * (SIZE - 1));
+    }
+
+    /**
+     * forEachInParallel traverses all mappings
+     */
+    public void testForEachInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(1L, (Long x, Long y) -> adder.add(x.longValue() + y.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * forEachEntryInParallel traverses all entries
+     */
+    public void testForEachEntryInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> adder.add(e.getKey().longValue() + e.getValue().longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachKeySequentially traverses the given
+     * transformations of all keys
+     */
+    public void testMappedForEachKeySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachValueSequentially traverses the given
+     * transformations of all values
+     */
+    public void testMappedForEachValueSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                   (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * Mapped forEachSequentially traverses the given
+     * transformations of all mappings
+     */
+    public void testMappedForEachSequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                              (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachEntrySequentially traverses the given
+     * transformations of all entries
+     */
+    public void testMappedForEachEntrySequentially() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
+                                   (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachKeyInParallel traverses the given
+     * transformations of all keys
+     */
+    public void testMappedForEachKeyInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachKey(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                               (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachValueInParallel traverses the given
+     * transformations of all values
+     */
+    public void testMappedForEachValueInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachValue(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * Mapped forEachInParallel traverses the given
+     * transformations of all mappings
+     */
+    public void testMappedForEachInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEach(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                            (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped forEachEntryInParallel traverses the given
+     * transformations of all entries
+     */
+    public void testMappedForEachEntryInParallel() {
+        LongAdder adder = new LongAdder();
+        ConcurrentHashMap<Long, Long> m = longMap();
+        m.forEachEntry(1L, (Map.Entry<Long,Long> e) -> Long.valueOf(e.getKey().longValue() + e.getValue().longValue()),
+                                 (Long x) -> adder.add(x.longValue()));
+        assertEquals(adder.sum(), 3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysSequentially accumulates across all keys,
+     */
+    public void testReduceKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesSequentially accumulates across all values
+     */
+    public void testReduceValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceEntriesSequentially accumulates across all entries
+     */
+    public void testReduceEntriesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Map.Entry<Long,Long> r;
+        r = m.reduceEntries(Long.MAX_VALUE, new AddKeys());
+        assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysInParallel accumulates across all keys
+     */
+    public void testReduceKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceKeys(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesInParallel accumulates across all values
+     */
+    public void testReduceValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduceValues(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceEntriesInParallel accumulate across all entries
+     */
+    public void testReduceEntriesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Map.Entry<Long,Long> r;
+        r = m.reduceEntries(1L, new AddKeys());
+        assertEquals(r.getKey().longValue(), (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceKeysSequentially accumulates mapped keys
+     */
+    public void testMapReduceKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceKeys(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                     (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceValuesSequentially accumulates mapped values
+     */
+    public void testMapReduceValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceValues(Long.MAX_VALUE, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                       (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceSequentially accumulates across all transformed mappings
+     */
+    public void testMappedReduceSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduce(Long.MAX_VALUE, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                                 (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+
+        assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceKeysInParallel, accumulates mapped keys
+     */
+    public void testMapReduceKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceKeys(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                   (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * Mapped reduceValuesInParallel accumulates mapped values
+     */
+    public void testMapReduceValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r = m.reduceValues(1L, (Long x) -> Long.valueOf(4 * x.longValue()),
+                                     (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)4 * SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceInParallel accumulate across all transformed mappings
+     */
+    public void testMappedReduceInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.reduce(1L, (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()),
+                               (Long x, Long y) -> Long.valueOf(x.longValue() + y.longValue()));
+        assertEquals((long)r, (long)3 * SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToLongSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToLongSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceKeysToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToIntSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToIntSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceKeysToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToDoubleSequentially accumulates mapped keys
+     */
+    public void testReduceKeysToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceKeysToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesToLongSequentially accumulates mapped values
+     */
+    public void testReduceValuesToLongSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceValuesToLong(Long.MAX_VALUE, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToIntSequentially accumulates mapped values
+     */
+    public void testReduceValuesToIntSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceValuesToInt(Long.MAX_VALUE, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToDoubleSequentially accumulates mapped values
+     */
+    public void testReduceValuesToDoubleSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceValuesToDouble(Long.MAX_VALUE, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceKeysToLongInParallel accumulates mapped keys
+     */
+    public void testReduceKeysToLongInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceKeysToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToIntInParallel accumulates mapped keys
+     */
+    public void testReduceKeysToIntInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceKeysToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceKeysToDoubleInParallel accumulates mapped values
+     */
+    public void testReduceKeysToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceKeysToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1) / 2);
+    }
+
+    /**
+     * reduceValuesToLongInParallel accumulates mapped values
+     */
+    public void testReduceValuesToLongInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        long lr = m.reduceValuesToLong(1L, (Long x) -> x.longValue(), 0L, Long::sum);
+        assertEquals(lr, (long)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToIntInParallel accumulates mapped values
+     */
+    public void testReduceValuesToIntInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        int ir = m.reduceValuesToInt(1L, (Long x) -> x.intValue(), 0, Integer::sum);
+        assertEquals(ir, SIZE * (SIZE - 1));
+    }
+
+    /**
+     * reduceValuesToDoubleInParallel accumulates mapped values
+     */
+    public void testReduceValuesToDoubleInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        double dr = m.reduceValuesToDouble(1L, (Long x) -> x.doubleValue(), 0.0, Double::sum);
+        assertEquals(dr, (double)SIZE * (SIZE - 1));
+    }
+
+    /**
+     * searchKeysSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchKeysSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchKeys(Long.MAX_VALUE, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchValuesSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchValuesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchValues(Long.MAX_VALUE,
+            (Long x) -> (x.longValue() == (long)(SIZE/2)) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchValues(Long.MAX_VALUE,
+            (Long x) -> (x.longValue() < 0L) ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.search(Long.MAX_VALUE, (Long x, Long y) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchEntriesSequentially returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchEntriesSequentially() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchEntries(Long.MAX_VALUE, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchKeysInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchKeysInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchKeys(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchKeys(1L, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchValuesInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchValuesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchValues(1L, (Long x) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchValues(1L, (Long x) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchInParallel returns a non-null result of search function,
+     * or null if none
+     */
+    public void testSearchInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.search(1L, (Long x, Long y) -> x.longValue() == (long)(SIZE/2) ? x : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.search(1L, (Long x, Long y) -> x.longValue() < 0L ? x : null);
+        assertNull(r);
+    }
+
+    /**
+     * searchEntriesInParallel returns a non-null result of search
+     * function, or null if none
+     */
+    public void testSearchEntriesInParallel() {
+        ConcurrentHashMap<Long, Long> m = longMap();
+        Long r;
+        r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() == (long)(SIZE/2) ? e.getKey() : null);
+        assertEquals((long)r, (long)(SIZE/2));
+        r = m.searchEntries(1L, (Map.Entry<Long,Long> e) -> e.getKey().longValue() < 0L ? e.getKey() : null);
+        assertNull(r);
+    }
+
+    /**
+     * Tests performance of computeIfAbsent when the element is present.
+     * See JDK-8161372
+     * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testcomputeIfAbsent_performance -Djsr166.expensiveTests=true tck
+     */
+    public void testcomputeIfAbsent_performance() {
+        final int mapSize = 20;
+        final int iterations = expensiveTests ? (1 << 23) : mapSize * 2;
+        final int threads = expensiveTests ? 10 : 2;
+        final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
+        for (int i = 0; i < mapSize; i++)
+            map.put(i, i);
+        final ExecutorService pool = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            Runnable r = new CheckedRunnable() {
+                public void realRun() {
+                    int result = 0;
+                    for (int i = 0; i < iterations; i++)
+                        result += map.computeIfAbsent(i % mapSize, k -> k + k);
+                    if (result == -42) throw new Error();
+                }};
+            for (int i = 0; i < threads; i++)
+                pool.execute(r);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMapTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMapTest.java
new file mode 100644
index 0000000..3973eda
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentHashMapTest.java
@@ -0,0 +1,868 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentHashMapTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentHashMapTest.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentHashMap<Integer, String> map5() {
+        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>(5);
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(two, "B");
+        map.put(three, "C");
+        map.put(four, "D");
+        map.put(five, "E");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /** Re-implement Integer.compare for old java versions */
+    static int compare(int x, int y) {
+        return (x < y) ? -1 : (x > y) ? 1 : 0;
+    }
+
+    // classes for testing Comparable fallbacks
+    static class BI implements Comparable<BI> {
+        private final int value;
+        BI(int value) { this.value = value; }
+        public int compareTo(BI other) {
+            return compare(value, other.value);
+        }
+        public boolean equals(Object x) {
+            return (x instanceof BI) && ((BI)x).value == value;
+        }
+        public int hashCode() { return 42; }
+    }
+    static class CI extends BI { CI(int value) { super(value); } }
+    static class DI extends BI { DI(int value) { super(value); } }
+
+    static class BS implements Comparable<BS> {
+        private final String value;
+        BS(String value) { this.value = value; }
+        public int compareTo(BS other) {
+            return value.compareTo(other.value);
+        }
+        public boolean equals(Object x) {
+            return (x instanceof BS) && value.equals(((BS)x).value);
+        }
+        public int hashCode() { return 42; }
+    }
+
+    static class LexicographicList<E extends Comparable<E>> extends ArrayList<E>
+        implements Comparable<LexicographicList<E>> {
+        LexicographicList(Collection<E> c) { super(c); }
+        LexicographicList(E e) { super(Collections.singleton(e)); }
+        public int compareTo(LexicographicList<E> other) {
+            int common = Math.min(size(), other.size());
+            int r = 0;
+            for (int i = 0; i < common; i++) {
+                if ((r = get(i).compareTo(other.get(i))) != 0)
+                    break;
+            }
+            if (r == 0)
+                r = compare(size(), other.size());
+            return r;
+        }
+        private static final long serialVersionUID = 0;
+    }
+
+    static class CollidingObject {
+        final String value;
+        CollidingObject(final String value) { this.value = value; }
+        public int hashCode() { return this.value.hashCode() & 1; }
+        public boolean equals(final Object obj) {
+            return (obj instanceof CollidingObject) && ((CollidingObject)obj).value.equals(value);
+        }
+    }
+
+    static class ComparableCollidingObject extends CollidingObject implements Comparable<ComparableCollidingObject> {
+        ComparableCollidingObject(final String value) { super(value); }
+        public int compareTo(final ComparableCollidingObject o) {
+            return value.compareTo(o.value);
+        }
+    }
+
+    /**
+     * Inserted elements that are subclasses of the same Comparable
+     * class are found.
+     */
+    public void testComparableFamily() {
+        int size = 500;         // makes measured test run time -> 60ms
+        ConcurrentHashMap<BI, Boolean> m =
+            new ConcurrentHashMap<BI, Boolean>();
+        for (int i = 0; i < size; i++) {
+            assertTrue(m.put(new CI(i), true) == null);
+        }
+        for (int i = 0; i < size; i++) {
+            assertTrue(m.containsKey(new CI(i)));
+            assertTrue(m.containsKey(new DI(i)));
+        }
+    }
+
+    /**
+     * Elements of classes with erased generic type parameters based
+     * on Comparable can be inserted and found.
+     */
+    public void testGenericComparable() {
+        int size = 120;         // makes measured test run time -> 60ms
+        ConcurrentHashMap<Object, Boolean> m =
+            new ConcurrentHashMap<Object, Boolean>();
+        for (int i = 0; i < size; i++) {
+            BI bi = new BI(i);
+            BS bs = new BS(String.valueOf(i));
+            LexicographicList<BI> bis = new LexicographicList<BI>(bi);
+            LexicographicList<BS> bss = new LexicographicList<BS>(bs);
+            assertTrue(m.putIfAbsent(bis, true) == null);
+            assertTrue(m.containsKey(bis));
+            if (m.putIfAbsent(bss, true) == null)
+                assertTrue(m.containsKey(bss));
+            assertTrue(m.containsKey(bis));
+        }
+        for (int i = 0; i < size; i++) {
+            assertTrue(m.containsKey(Collections.singletonList(new BI(i))));
+        }
+    }
+
+    /**
+     * Elements of non-comparable classes equal to those of classes
+     * with erased generic type parameters based on Comparable can be
+     * inserted and found.
+     */
+    public void testGenericComparable2() {
+        int size = 500;         // makes measured test run time -> 60ms
+        ConcurrentHashMap<Object, Boolean> m =
+            new ConcurrentHashMap<Object, Boolean>();
+        for (int i = 0; i < size; i++) {
+            m.put(Collections.singletonList(new BI(i)), true);
+        }
+
+        for (int i = 0; i < size; i++) {
+            LexicographicList<BI> bis = new LexicographicList<BI>(new BI(i));
+            assertTrue(m.containsKey(bis));
+        }
+    }
+
+    /**
+     * Mixtures of instances of comparable and non-comparable classes
+     * can be inserted and found.
+     */
+    public void testMixedComparable() {
+        int size = 1200;        // makes measured test run time -> 35ms
+        ConcurrentHashMap<Object, Object> map =
+            new ConcurrentHashMap<Object, Object>();
+        Random rng = new Random();
+        for (int i = 0; i < size; i++) {
+            Object x;
+            switch (rng.nextInt(4)) {
+            case 0:
+                x = new Object();
+                break;
+            case 1:
+                x = new CollidingObject(Integer.toString(i));
+                break;
+            default:
+                x = new ComparableCollidingObject(Integer.toString(i));
+            }
+            assertNull(map.put(x, x));
+        }
+        int count = 0;
+        for (Object k : map.keySet()) {
+            assertEquals(map.get(k), k);
+            ++count;
+        }
+        assertEquals(count, size);
+        assertEquals(map.size(), size);
+        for (Object k : map.keySet()) {
+            assertEquals(map.put(k, k), k);
+        }
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testClear() {
+        ConcurrentHashMap map = map5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testEquals() {
+        ConcurrentHashMap map1 = map5();
+        ConcurrentHashMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * hashCode() equals sum of each key.hashCode ^ value.hashCode
+     */
+    public void testHashCode() {
+        ConcurrentHashMap<Integer,String> map = map5();
+        int sum = 0;
+        for (Map.Entry<Integer,String> e : map.entrySet())
+            sum += e.getKey().hashCode() ^ e.getValue().hashCode();
+        assertEquals(sum, map.hashCode());
+    }
+
+    /**
+     * contains returns true for contained value
+     */
+    public void testContains() {
+        ConcurrentHashMap map = map5();
+        assertTrue(map.contains("A"));
+        assertFalse(map.contains("Z"));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        ConcurrentHashMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        ConcurrentHashMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * enumeration returns an enumeration containing the correct
+     * elements
+     */
+    public void testEnumeration() {
+        ConcurrentHashMap map = map5();
+        Enumeration e = map.elements();
+        int count = 0;
+        while (e.hasMoreElements()) {
+            count++;
+            e.nextElement();
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testGet() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        ConcurrentHashMap empty = new ConcurrentHashMap();
+        assertNull(map.get("anything"));
+        assertNull(empty.get("anything"));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        ConcurrentHashMap empty = new ConcurrentHashMap();
+        ConcurrentHashMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * keys returns an enumeration containing all the keys from the map
+     */
+    public void testKeys() {
+        ConcurrentHashMap map = map5();
+        Enumeration e = map.keys();
+        int count = 0;
+        while (e.hasMoreElements()) {
+            count++;
+            e.nextElement();
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        ConcurrentHashMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     * Test keySet().removeAll on empty map
+     */
+    public void testKeySet_empty_removeAll() {
+        ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
+        Set<Integer> set = map.keySet();
+        set.removeAll(Collections.emptyList());
+        assertTrue(map.isEmpty());
+        assertTrue(set.isEmpty());
+        // following is test for JDK-8163353
+        set.removeAll(Collections.emptySet());
+        assertTrue(map.isEmpty());
+        assertTrue(set.isEmpty());
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentHashMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentHashMap map = map5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        ConcurrentHashMap map = map5();
+        Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        ConcurrentHashMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        ConcurrentHashMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        ConcurrentHashMap empty = new ConcurrentHashMap();
+        ConcurrentHashMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     * putIfAbsent works when the given key is not present
+     */
+    public void testPutIfAbsent() {
+        ConcurrentHashMap map = map5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * putIfAbsent does not add the pair if the key is already present
+     */
+    public void testPutIfAbsent2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", map.putIfAbsent(one, "Z"));
+    }
+
+    /**
+     * replace fails when the given key is not present
+     */
+    public void testReplace() {
+        ConcurrentHashMap map = map5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * replace succeeds if the key is already present
+     */
+    public void testReplace2() {
+        ConcurrentHashMap map = map5();
+        assertNotNull(map.replace(one, "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testReplaceValue() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", map.get(one));
+        assertFalse(map.replace(one, "Z", "Z"));
+        assertEquals("A", map.get(one));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testReplaceValue2() {
+        ConcurrentHashMap map = map5();
+        assertEquals("A", map.get(one));
+        assertTrue(map.replace(one, "A", "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        ConcurrentHashMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testRemove2() {
+        ConcurrentHashMap map = map5();
+        map.remove(five, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+        map.remove(four, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(four));
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testSize() {
+        ConcurrentHashMap map = map5();
+        ConcurrentHashMap empty = new ConcurrentHashMap();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        ConcurrentHashMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * Cannot create with only negative capacity
+     */
+    public void testConstructor1() {
+        try {
+            new ConcurrentHashMap(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor (initialCapacity, loadFactor) throws
+     * IllegalArgumentException if either argument is negative
+     */
+    public void testConstructor2() {
+        try {
+            new ConcurrentHashMap(-1, .75f);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+
+        try {
+            new ConcurrentHashMap(16, -1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor (initialCapacity, loadFactor, concurrencyLevel)
+     * throws IllegalArgumentException if any argument is negative
+     */
+    public void testConstructor3() {
+        try {
+            new ConcurrentHashMap(-1, .75f, 1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+
+        try {
+            new ConcurrentHashMap(16, -1, 1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+
+        try {
+            new ConcurrentHashMap(16, .75f, -1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * ConcurrentHashMap(map) throws NullPointerException if the given
+     * map is null
+     */
+    public void testConstructor4() {
+        try {
+            new ConcurrentHashMap(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * ConcurrentHashMap(map) creates a new map with the same mappings
+     * as the given map
+     */
+    public void testConstructor5() {
+        ConcurrentHashMap map1 = map5();
+        ConcurrentHashMap map2 = new ConcurrentHashMap(map5());
+        assertTrue(map2.equals(map1));
+        map2.put(one, "F");
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * get(null) throws NPE
+     */
+    public void testGet_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testContainsValue_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * contains(null) throws NPE
+     */
+    public void testContains_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.contains(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(x, null) throws NPE
+     */
+    public void testPut2_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.put("whatever", null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testPutIfAbsent1_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testReplace_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testReplaceValue_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.replace(null, one, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(x, null) throws NPE
+     */
+    public void testPutIfAbsent2_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.putIfAbsent("whatever", null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(x, null) throws NPE
+     */
+    public void testReplace2_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.replace("whatever", null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(x, null, y) throws NPE
+     */
+    public void testReplaceValue2_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.replace("whatever", null, "A");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(x, y, null) throws NPE
+     */
+    public void testReplaceValue3_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        try {
+            c.replace("whatever", one, null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        c.put("sadsdf", "asdads");
+        try {
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testRemove2_NullPointerException() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        c.put("sadsdf", "asdads");
+        try {
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(x, null) returns false
+     */
+    public void testRemove3() {
+        ConcurrentHashMap c = new ConcurrentHashMap(5);
+        c.put("sadsdf", "asdads");
+        assertFalse(c.remove("sadsdf", null));
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        Map x = map5();
+        Map y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * SetValue of an EntrySet entry sets value in the map.
+     */
+    public void testSetValueWriteThrough() {
+        // Adapted from a bug report by Eric Zoerner
+        ConcurrentHashMap map = new ConcurrentHashMap(2, 5.0f, 1);
+        assertTrue(map.isEmpty());
+        for (int i = 0; i < 20; i++)
+            map.put(new Integer(i), new Integer(i));
+        assertFalse(map.isEmpty());
+        Map.Entry entry1 = (Map.Entry)map.entrySet().iterator().next();
+        // Unless it happens to be first (in which case remainder of
+        // test is skipped), remove a possibly-colliding key from map
+        // which, under some implementations, may cause entry1 to be
+        // cloned in map
+        if (!entry1.getKey().equals(new Integer(16))) {
+            map.remove(new Integer(16));
+            entry1.setValue("XYZ");
+            assertTrue(map.containsValue("XYZ")); // fails if write-through broken
+        }
+    }
+
+    /**
+     * Tests performance of removeAll when the other collection is much smaller.
+     * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testRemoveAll_performance -Djsr166.expensiveTests=true tck
+     */
+    public void testRemoveAll_performance() {
+        final int mapSize = expensiveTests ? 1_000_000 : 100;
+        final int iterations = expensiveTests ? 500 : 2;
+        final ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>();
+        for (int i = 0; i < mapSize; i++)
+            map.put(i, i);
+        Set<Integer> keySet = map.keySet();
+        Collection<Integer> removeMe = Arrays.asList(new Integer[] { -99, -86 });
+        for (int i = 0; i < iterations; i++)
+            assertFalse(keySet.removeAll(removeMe));
+        assertEquals(mapSize, map.size());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java
new file mode 100644
index 0000000..90dbc71
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java
@@ -0,0 +1,937 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.Random;
+import java.util.concurrent.ConcurrentLinkedDeque;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentLinkedDequeTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return ConcurrentLinkedDeque.class; }
+            public Collection emptyCollection() { return new ConcurrentLinkedDeque(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(ConcurrentLinkedDequeTest.class,
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Returns a new deque of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
+        ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<>();
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; ++i)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peekFirst());
+        assertEquals((Integer) (n - 1), q.peekLast());
+        return q;
+    }
+
+    /**
+     * new deque is empty
+     */
+    public void testConstructor1() {
+        assertTrue(new ConcurrentLinkedDeque().isEmpty());
+        assertEquals(0, new ConcurrentLinkedDeque().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new ConcurrentLinkedDeque((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new ConcurrentLinkedDeque(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new ConcurrentLinkedDeque(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size() changes when elements added and removed
+     */
+    public void testSize() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.remove();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * push(null) throws NPE
+     */
+    public void testPushNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.push(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * peekFirst() returns element inserted with push
+     */
+    public void testPush() {
+        ConcurrentLinkedDeque q = populatedDeque(3);
+        q.pollLast();
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * pop() removes first element, or throws NSEE if empty
+     */
+    public void testPop() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offerFirst(null) throws NPE
+     */
+    public void testOfferFirstNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.offerFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offerLast(null) throws NPE
+     */
+    public void testOfferLastNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.offerLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offer(x) succeeds
+     */
+    public void testOffer() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertTrue(q.offer(zero));
+        assertTrue(q.offer(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * offerFirst(x) succeeds
+     */
+    public void testOfferFirst() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertTrue(q.offerFirst(zero));
+        assertTrue(q.offerFirst(one));
+        assertSame(one, q.peekFirst());
+        assertSame(zero, q.peekLast());
+    }
+
+    /**
+     * offerLast(x) succeeds
+     */
+    public void testOfferLast() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertTrue(q.offerLast(zero));
+        assertTrue(q.offerLast(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addFirst(null) throws NPE
+     */
+    public void testAddFirstNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.addFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addLast(null) throws NPE
+     */
+    public void testAddLastNull() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.addLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(x) succeeds
+     */
+    public void testAdd() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertTrue(q.add(zero));
+        assertTrue(q.add(one));
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * addFirst(x) succeeds
+     */
+    public void testAddFirst() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        q.addFirst(zero);
+        q.addFirst(one);
+        assertSame(one, q.peekFirst());
+        assertSame(zero, q.peekLast());
+    }
+
+    /**
+     * addLast(x) succeeds
+     */
+    public void testAddLast() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        q.addLast(zero);
+        q.addLast(one);
+        assertSame(zero, q.peekFirst());
+        assertSame(one, q.peekLast());
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        try {
+            q.addAll(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * pollFirst() succeeds unless empty
+     */
+    public void testPollFirst() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast() succeeds unless empty
+     */
+    public void testPollLast() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     * poll() succeeds unless empty
+     */
+    public void testPoll() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * peek() returns next element, or null if empty
+     */
+    public void testPeek() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element() returns first element, or throws NSEE if empty
+     */
+    public void testElement() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove() removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * peekFirst() returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * peekLast() returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * getFirst() returns first element, or throws NSEE if empty
+     */
+    public void testFirstElement() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * getLast() returns last element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirst() removes first element, or throws NSEE if empty
+     */
+    public void testRemoveFirst() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.removeFirst());
+        }
+        try {
+            q.removeFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * removeLast() removes last element, or throws NSEE if empty
+     */
+    public void testRemoveLast() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.removeLast());
+        }
+        try {
+            q.removeLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear() removes all elements
+     */
+    public void testClear() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        ConcurrentLinkedDeque p = new ConcurrentLinkedDeque();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if change
+     */
+    public void testRetainAll() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        ConcurrentLinkedDeque p = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ConcurrentLinkedDeque q = populatedDeque(SIZE);
+            ConcurrentLinkedDeque p = populatedDeque(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray() contains all elements in FIFO order
+     */
+    public void testToArray() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() {
+        ConcurrentLinkedDeque<Integer> q = populatedDeque(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.poll());
+    }
+
+    /**
+     * toArray(null) throws NullPointerException
+     */
+    public void testToArray_NullArg() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        try {
+            q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * Iterator iterates through all elements
+     */
+    public void testIterator() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        Deque c = new ConcurrentLinkedDeque();
+        assertIteratorExhausted(c.iterator());
+        assertIteratorExhausted(c.descendingIterator());
+    }
+
+    /**
+     * Iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+
+        assertEquals("deque should be empty again", 0, q.size());
+    }
+
+    /**
+     * iterator.remove() removes current element
+     */
+    public void testIteratorRemove() {
+        final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max - 1) + 1;
+            for (int j = 1; j <= max; ++j)
+                q.add(new Integer(j));
+            Iterator it = q.iterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split + 1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.iterator();
+            for (int j = split + 1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+    /**
+     * Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            int k = 0;
+            for (Iterator it = q.descendingIterator(); it.hasNext();) {
+                assertEquals(++k, it.next());
+            }
+
+            assertEquals(3, k);
+            q.remove();
+            q.remove();
+            q.remove();
+        }
+    }
+
+    /**
+     * descendingIterator.remove() removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final ConcurrentLinkedDeque q = new ConcurrentLinkedDeque();
+        final Random rng = new Random();
+        for (int iters = 0; iters < 100; ++iters) {
+            int max = rng.nextInt(5) + 2;
+            int split = rng.nextInt(max - 1) + 1;
+            for (int j = max; j >= 1; --j)
+                q.add(new Integer(j));
+            Iterator it = q.descendingIterator();
+            for (int j = 1; j <= split; ++j)
+                assertEquals(it.next(), new Integer(j));
+            it.remove();
+            assertEquals(it.next(), new Integer(split + 1));
+            for (int j = 1; j <= split; ++j)
+                q.remove(new Integer(j));
+            it = q.descendingIterator();
+            for (int j = split + 1; j <= max; ++j) {
+                assertEquals(it.next(), new Integer(j));
+                it.remove();
+            }
+            assertFalse(it.hasNext());
+            assertTrue(q.isEmpty());
+        }
+    }
+
+    /**
+     * toString() contains toStrings of elements
+     */
+    public void testToString() {
+        ConcurrentLinkedDeque q = populatedDeque(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized deque has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedDeque(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * contains(null) always return false.
+     * remove(null) always throws NullPointerException.
+     */
+    public void testNeverContainsNull() {
+        Deque<?>[] qs = {
+            new ConcurrentLinkedDeque<Object>(),
+            populatedDeque(2),
+        };
+
+        for (Deque<?> q : qs) {
+            assertFalse(q.contains(null));
+            try {
+                assertFalse(q.remove(null));
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            try {
+                assertFalse(q.removeFirstOccurrence(null));
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            try {
+                assertFalse(q.removeLastOccurrence(null));
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java
new file mode 100644
index 0000000..1d1e875
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentLinkedQueueTest.java
@@ -0,0 +1,574 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentLinkedQueueTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return ConcurrentLinkedQueue.class; }
+            public Collection emptyCollection() { return new ConcurrentLinkedQueue(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(ConcurrentLinkedQueueTest.class,
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private ConcurrentLinkedQueue<Integer> populatedQueue(int n) {
+        ConcurrentLinkedQueue<Integer> q = new ConcurrentLinkedQueue<>();
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; ++i)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peek());
+        return q;
+    }
+
+    /**
+     * new queue is empty
+     */
+    public void testConstructor1() {
+        assertEquals(0, new ConcurrentLinkedQueue().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new ConcurrentLinkedQueue((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new ConcurrentLinkedQueue(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new ConcurrentLinkedQueue(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.remove();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferNull() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        try {
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Offer returns true
+     */
+    public void testOffer() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        assertTrue(q.offer(zero));
+        assertTrue(q.offer(one));
+    }
+
+    /**
+     * add returns true
+     */
+    public void testAdd() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new Integer(i)));
+        }
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        try {
+            q.addAll(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        ConcurrentLinkedQueue p = new ConcurrentLinkedQueue();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if change
+     */
+    public void testRetainAll() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        ConcurrentLinkedQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ConcurrentLinkedQueue q = populatedQueue(SIZE);
+            ConcurrentLinkedQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements in FIFO order
+     */
+    public void testToArray() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() {
+        ConcurrentLinkedQueue<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.poll());
+    }
+
+    /**
+     * toArray(null) throws NullPointerException
+     */
+    public void testToArray_NullArg() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new ConcurrentLinkedQueue().iterator());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+
+        assertEquals("queue should be empty again", 0, q.size());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final ConcurrentLinkedQueue q = new ConcurrentLinkedQueue();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+        it = q.iterator();
+        assertSame(it.next(), two);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        ConcurrentLinkedQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?>[] qs = {
+            new ConcurrentLinkedQueue<Object>(),
+            populatedQueue(2),
+        };
+
+        for (Collection<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
new file mode 100644
index 0000000..7e8594d
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListMapTest.java
@@ -0,0 +1,1307 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentSkipListMapTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListMapTest.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentSkipListMap map5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testClear() {
+        ConcurrentSkipListMap map = map5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * copy constructor creates map equal to source map
+     */
+    public void testConstructFromSorted() {
+        ConcurrentSkipListMap map = map5();
+        ConcurrentSkipListMap map2 = new ConcurrentSkipListMap(map);
+        assertEquals(map, map2);
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testEquals() {
+        ConcurrentSkipListMap map1 = map5();
+        ConcurrentSkipListMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testGet() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        ConcurrentSkipListMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testFirstKey() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testLastKey() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingKeySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testKeySetOrder() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descending iterator of key set is inverse ordered
+     */
+    public void testKeySetDescendingIteratorOrder() {
+        ConcurrentSkipListMap map = map5();
+        NavigableSet s = map.navigableKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descendingKeySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingKeySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descending iterator of descendingKeySet is ordered
+     */
+    public void testDescendingKeySetDescendingIteratorOrder() {
+        ConcurrentSkipListMap map = map5();
+        NavigableSet s = map.descendingKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentSkipListMap map = map5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        ConcurrentSkipListMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * descendingEntrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     * descendingEntrySet.toArray contains all entries
+     */
+    public void testDescendingEntrySetToArray() {
+        ConcurrentSkipListMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        ConcurrentSkipListMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     * putIfAbsent works when the given key is not present
+     */
+    public void testPutIfAbsent() {
+        ConcurrentSkipListMap map = map5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * putIfAbsent does not add the pair if the key is already present
+     */
+    public void testPutIfAbsent2() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.putIfAbsent(one, "Z"));
+    }
+
+    /**
+     * replace fails when the given key is not present
+     */
+    public void testReplace() {
+        ConcurrentSkipListMap map = map5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * replace succeeds if the key is already present
+     */
+    public void testReplace2() {
+        ConcurrentSkipListMap map = map5();
+        assertNotNull(map.replace(one, "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testReplaceValue() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.get(one));
+        assertFalse(map.replace(one, "Z", "Z"));
+        assertEquals("A", map.get(one));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testReplaceValue2() {
+        ConcurrentSkipListMap map = map5();
+        assertEquals("A", map.get(one));
+        assertTrue(map.replace(one, "A", "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        ConcurrentSkipListMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testRemove2() {
+        ConcurrentSkipListMap map = map5();
+        assertTrue(map.containsKey(five));
+        assertEquals("E", map.get(five));
+        map.remove(five, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+        map.remove(four, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(four));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * lowerEntry, higherEntry, ceilingEntry, and floorEntry return
+     * immutable entries
+     */
+    public void testEntryImmutability() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.lowerEntry(three);
+        assertEquals(two, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.higherEntry(zero);
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.floorEntry(one);
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.ceilingEntry(five);
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("X");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * lowerKey returns preceding element
+     */
+    public void testLowerKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.lowerKey(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lowerKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lowerKey(one);
+        assertNull(e3);
+
+        Object e4 = q.lowerKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherKey returns next element
+     */
+    public void testHigherKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.higherKey(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higherKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higherKey(five);
+        assertNull(e3);
+
+        Object e4 = q.higherKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorKey returns preceding element
+     */
+    public void testFloorKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.floorKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floorKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floorKey(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floorKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingKey returns next element
+     */
+    public void testCeilingKey() {
+        ConcurrentSkipListMap q = map5();
+        Object e1 = q.ceilingKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceilingKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceilingKey(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceilingKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        ConcurrentSkipListMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testSize() {
+        ConcurrentSkipListMap map = map5();
+        ConcurrentSkipListMap empty = new ConcurrentSkipListMap();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        ConcurrentSkipListMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testContainsValue_NullPointerException() {
+        ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+        try {
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testPutIfAbsent1_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testReplace_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testReplaceValue_NullPointerException() {
+        ConcurrentSkipListMap c = map5();
+        try {
+            c.replace(null, one, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+        c.put("sadsdf", "asdads");
+        try {
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testRemove2_NullPointerException() {
+        ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+        c.put("sadsdf", "asdads");
+        try {
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(x, null) returns false
+     */
+    public void testRemove3() {
+        ConcurrentSkipListMap c = new ConcurrentSkipListMap();
+        c.put("sadsdf", "asdads");
+        assertFalse(c.remove("sadsdf", null));
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        NavigableMap x = map5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.subMap(two, true, four, false);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.subMap(two, true, three, false);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.headMap(four, false);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * tailMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        ConcurrentSkipListMap map = map5();
+        NavigableMap sm = map.tailMap(two, true);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(five, k);
+        k = (Integer)(r.next());
+        assertEquals(four, k);
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        NavigableMap ssm = sm.tailMap(four, true);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    Random rnd = new Random(666);
+    BitSet bs;
+
+    /**
+     * Submaps of submaps subdivide correctly
+     */
+    public void testRecursiveSubMaps() throws Exception {
+        int mapSize = expensiveTests ? 1000 : 100;
+        Class cl = ConcurrentSkipListMap.class;
+        NavigableMap<Integer, Integer> map = newMap(cl);
+        bs = new BitSet(mapSize);
+
+        populate(map, mapSize);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        mutateMap(map, 0, mapSize - 1);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        bashSubMap(map.subMap(0, true, mapSize, false),
+                   0, mapSize - 1, true);
+    }
+
+    static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
+        NavigableMap<Integer, Integer> result =
+            (NavigableMap<Integer, Integer>) cl.getConstructor().newInstance();
+        assertEquals(0, result.size());
+        assertFalse(result.keySet().iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableMap<Integer, Integer> map, int limit) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int key = rnd.nextInt(limit);
+            put(map, key);
+        }
+    }
+
+    void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min + rnd.nextInt(rangeSize);
+            assertTrue(key >= min && key <= max);
+            put(map, key);
+        }
+    }
+
+    void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (key >= min && key <= max) {
+                put(map, key);
+            } else {
+                try {
+                    map.put(key, 2 * key);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableMap<Integer, Integer> map, int key) {
+        if (map.put(key, 2 * key) == null)
+            bs.set(key);
+    }
+
+    void remove(NavigableMap<Integer, Integer> map, int key) {
+        if (map.remove(key) != null)
+            bs.clear(key);
+    }
+
+    void bashSubMap(NavigableMap<Integer, Integer> map,
+                    int min, int max, boolean ascending) {
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        mutateSubMap(map, min, max);
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headMap - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
+            else
+                bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           false);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
+            else
+                bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           true);
+        }
+
+        // tailMap - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
+            else
+                bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           false);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
+            } else {
+                bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           true);
+            }
+        }
+
+        // subMap - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+        } else {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableMap<Integer, Integer> map,
+                      final int min, final int max, final boolean ascending) {
+        class ReferenceSet {
+            int lower(int key) {
+                return ascending ? lowerAscending(key) : higherAscending(key);
+            }
+            int floor(int key) {
+                return ascending ? floorAscending(key) : ceilingAscending(key);
+            }
+            int ceiling(int key) {
+                return ascending ? ceilingAscending(key) : floorAscending(key);
+            }
+            int higher(int key) {
+                return ascending ? higherAscending(key) : lowerAscending(key);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int key) {
+                return floorAscending(key - 1);
+            }
+            int floorAscending(int key) {
+                if (key < min)
+                    return -1;
+                else if (key > max)
+                    key = max;
+
+                // BitSet should support this! Test would run much faster
+                while (key >= min) {
+                    if (bs.get(key))
+                        return key;
+                    key--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int key) {
+                if (key < min)
+                    key = min;
+                else if (key > max)
+                    return -1;
+                int result = bs.nextSetBit(key);
+                return result > max ? -1 : result;
+            }
+            int higherAscending(int key) {
+                return ceilingAscending(key + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return result > max ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return result < min ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsKey
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, map.containsKey(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(size, map.size());
+
+        // Test contents using contains keySet iterator
+        int size2 = 0;
+        int previousKey = -1;
+        for (int key : map.keySet()) {
+            assertTrue(bs.get(key));
+            size2++;
+            assertTrue(previousKey < 0 ||
+                (ascending ? key - previousKey > 0 : key - previousKey < 0));
+            previousKey = key;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int key = min - 1; key <= max + 1; key++) {
+            assertEq(map.lowerKey(key), rs.lower(key));
+            assertEq(map.floorKey(key), rs.floor(key));
+            assertEq(map.higherKey(key), rs.higher(key));
+            assertEq(map.ceilingKey(key), rs.ceiling(key));
+        }
+
+        // Test extrema
+        if (map.size() != 0) {
+            assertEq(map.firstKey(), rs.first());
+            assertEq(map.lastKey(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                map.firstKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                map.lastKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return (i == null) ? j == -1 : i == j;
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
new file mode 100644
index 0000000..d27c10f
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSetTest.java
@@ -0,0 +1,1016 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentSkipListSetTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Returns a new set of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private ConcurrentSkipListSet<Integer> populatedSet(int n) {
+        ConcurrentSkipListSet<Integer> q =
+            new ConcurrentSkipListSet<Integer>();
+        assertTrue(q.isEmpty());
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.add(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        return q;
+    }
+
+    /**
+     * Returns a new set of first 5 ints.
+     */
+    private ConcurrentSkipListSet set5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        assertEquals(5, q.size());
+        return q;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, new ConcurrentSkipListSet().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new ConcurrentSkipListSet((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new ConcurrentSkipListSet(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new ConcurrentSkipListSet(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * The comparator used in constructor is used
+     */
+    public void testConstructor7() {
+        MyReverseComparator cmp = new MyReverseComparator();
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet(cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE - 1; i >= 0; --i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.add(zero));
+        assertTrue(q.add(one));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.add(zero));
+        assertFalse(q.add(zero));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {
+            assertTrue(q.size() < 2);
+            for (int i = 0, size = q.size(); i < size; i++)
+                assertTrue(q.pollFirst().getClass() == Object.class);
+            assertNull(q.pollFirst());
+            assertTrue(q.isEmpty());
+            assertEquals(0, q.size());
+        }
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(i, q.pollFirst());
+    }
+
+    /**
+     * pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        ConcurrentSkipListSet p = new ConcurrentSkipListSet();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        ConcurrentSkipListSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            ConcurrentSkipListSet q = populatedSet(SIZE);
+            ConcurrentSkipListSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        ConcurrentSkipListSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements in sorted order
+     */
+    public void testToArray() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements in sorted order
+     */
+    public void testToArray2() {
+        ConcurrentSkipListSet<Integer> q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        assertSame(ints, q.toArray(ints));
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        NavigableSet s = new ConcurrentSkipListSet();
+        assertIteratorExhausted(s.iterator());
+        assertIteratorExhausted(s.descendingSet().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        ConcurrentSkipListSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        NavigableSet x = populatedSet(SIZE);
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        ConcurrentSkipListSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    Random rnd = new Random(666);
+
+    /**
+     * Subsets of subsets subdivide correctly
+     */
+    public void testRecursiveSubSets() throws Exception {
+        int setSize = expensiveTests ? 1000 : 100;
+        Class cl = ConcurrentSkipListSet.class;
+
+        NavigableSet<Integer> set = newSet(cl);
+        BitSet bs = new BitSet(setSize);
+
+        populate(set, setSize, bs);
+        check(set,                 0, setSize - 1, true, bs);
+        check(set.descendingSet(), 0, setSize - 1, false, bs);
+
+        mutateSet(set, 0, setSize - 1, bs);
+        check(set,                 0, setSize - 1, true, bs);
+        check(set.descendingSet(), 0, setSize - 1, false, bs);
+
+        bashSubSet(set.subSet(0, true, setSize, false),
+                   0, setSize - 1, true, bs);
+    }
+
+    /**
+     * addAll is idempotent
+     */
+    public void testAddAll_idempotent() throws Exception {
+        Set x = populatedSet(SIZE);
+        Set y = new ConcurrentSkipListSet(x);
+        y.addAll(x);
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    static NavigableSet<Integer> newSet(Class cl) throws Exception {
+        NavigableSet<Integer> result =
+            (NavigableSet<Integer>) cl.getConstructor().newInstance();
+        assertEquals(0, result.size());
+        assertFalse(result.iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableSet<Integer> set, int limit, BitSet bs) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int element = rnd.nextInt(limit);
+            put(set, element, bs);
+        }
+    }
+
+    void mutateSet(NavigableSet<Integer> set, int min, int max, BitSet bs) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min + rnd.nextInt(rangeSize);
+            assertTrue(element >= min && element <= max);
+            put(set, element, bs);
+        }
+    }
+
+    void mutateSubSet(NavigableSet<Integer> set, int min, int max,
+                      BitSet bs) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10), bs);
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (element >= min && element <= max) {
+                put(set, element, bs);
+            } else {
+                try {
+                    set.add(element);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableSet<Integer> set, int element, BitSet bs) {
+        if (set.add(element))
+            bs.set(element);
+    }
+
+    void remove(NavigableSet<Integer> set, int element, BitSet bs) {
+        if (set.remove(element))
+            bs.clear(element);
+    }
+
+    void bashSubSet(NavigableSet<Integer> set,
+                    int min, int max, boolean ascending,
+                    BitSet bs) {
+        check(set, min, max, ascending, bs);
+        check(set.descendingSet(), min, max, !ascending, bs);
+
+        mutateSubSet(set, min, max, bs);
+        check(set, min, max, ascending, bs);
+        check(set.descendingSet(), min, max, !ascending, bs);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headSet - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableSet<Integer> hm = set.headSet(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true, bs);
+            else
+                bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           false, bs);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false, bs);
+            else
+                bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           true, bs);
+        }
+
+        // tailSet - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true, bs);
+            else
+                bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           false, bs);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false, bs);
+            } else {
+                bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           true, bs);
+            }
+        }
+
+        // subSet - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true, bs);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false, bs);
+        } else {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false, bs);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true, bs);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableSet<Integer> set,
+               final int min, final int max, final boolean ascending,
+               final BitSet bs) {
+        class ReferenceSet {
+            int lower(int element) {
+                return ascending ?
+                    lowerAscending(element) : higherAscending(element);
+            }
+            int floor(int element) {
+                return ascending ?
+                    floorAscending(element) : ceilingAscending(element);
+            }
+            int ceiling(int element) {
+                return ascending ?
+                    ceilingAscending(element) : floorAscending(element);
+            }
+            int higher(int element) {
+                return ascending ?
+                    higherAscending(element) : lowerAscending(element);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int element) {
+                return floorAscending(element - 1);
+            }
+            int floorAscending(int element) {
+                if (element < min)
+                    return -1;
+                else if (element > max)
+                    element = max;
+
+                // BitSet should support this! Test would run much faster
+                while (element >= min) {
+                    if (bs.get(element))
+                        return element;
+                    element--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int element) {
+                if (element < min)
+                    element = min;
+                else if (element > max)
+                    return -1;
+                int result = bs.nextSetBit(element);
+                return result > max ? -1 : result;
+            }
+            int higherAscending(int element) {
+                return ceilingAscending(element + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return result > max ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return result < min ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsElement
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, set.contains(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(size, set.size());
+
+        // Test contents using contains elementSet iterator
+        int size2 = 0;
+        int previousElement = -1;
+        for (int element : set) {
+            assertTrue(bs.get(element));
+            size2++;
+            assertTrue(previousElement < 0 || (ascending ?
+                element - previousElement > 0 : element - previousElement < 0));
+            previousElement = element;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int element = min - 1; element <= max + 1; element++) {
+            assertEq(set.lower(element), rs.lower(element));
+            assertEq(set.floor(element), rs.floor(element));
+            assertEq(set.higher(element), rs.higher(element));
+            assertEq(set.ceiling(element), rs.ceiling(element));
+        }
+
+        // Test extrema
+        if (set.size() != 0) {
+            assertEq(set.first(), rs.first());
+            assertEq(set.last(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                set.first();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                set.last();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return (i == null) ? j == -1 : i == j;
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java
new file mode 100644
index 0000000..d48b9f9
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubMapTest.java
@@ -0,0 +1,1451 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentSkipListSubMapTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSubMapTest.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static ConcurrentNavigableMap map5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(zero, "Z");
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        map.put(seven, "F");
+        assertFalse(map.isEmpty());
+        assertEquals(7, map.size());
+        return map.subMap(one, true, seven, false);
+    }
+
+    /**
+     * Returns a new map from Integers -5 to -1 to Strings "A"-"E".
+     */
+    private static ConcurrentNavigableMap dmap5() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        map.put(m1, "A");
+        map.put(m5, "E");
+        map.put(m3, "C");
+        map.put(m2, "B");
+        map.put(m4, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map.descendingMap();
+    }
+
+    private static ConcurrentNavigableMap map0() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        return map.tailMap(one, true);
+    }
+
+    private static ConcurrentNavigableMap dmap0() {
+        ConcurrentSkipListMap map = new ConcurrentSkipListMap();
+        assertTrue(map.isEmpty());
+        return map;
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testClear() {
+        ConcurrentNavigableMap map = map5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testEquals() {
+        ConcurrentNavigableMap map1 = map5();
+        ConcurrentNavigableMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testGet() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        ConcurrentNavigableMap empty = map0();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        ConcurrentNavigableMap empty = map0();
+        ConcurrentNavigableMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testFirstKey() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testLastKey() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testKeySetOrder() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        ConcurrentNavigableMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingKeySetToArray() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * Values.toArray contains all values
+     */
+    public void testValuesToArray() {
+        ConcurrentNavigableMap map = map5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        ConcurrentNavigableMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        ConcurrentNavigableMap empty = map0();
+        ConcurrentNavigableMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     * putIfAbsent works when the given key is not present
+     */
+    public void testPutIfAbsent() {
+        ConcurrentNavigableMap map = map5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * putIfAbsent does not add the pair if the key is already present
+     */
+    public void testPutIfAbsent2() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.putIfAbsent(one, "Z"));
+    }
+
+    /**
+     * replace fails when the given key is not present
+     */
+    public void testReplace() {
+        ConcurrentNavigableMap map = map5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * replace succeeds if the key is already present
+     */
+    public void testReplace2() {
+        ConcurrentNavigableMap map = map5();
+        assertNotNull(map.replace(one, "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testReplaceValue() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.get(one));
+        assertFalse(map.replace(one, "Z", "Z"));
+        assertEquals("A", map.get(one));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testReplaceValue2() {
+        ConcurrentNavigableMap map = map5();
+        assertEquals("A", map.get(one));
+        assertTrue(map.replace(one, "A", "Z"));
+        assertEquals("Z", map.get(one));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        ConcurrentNavigableMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testRemove2() {
+        ConcurrentNavigableMap map = map5();
+        assertTrue(map.containsKey(five));
+        assertEquals("E", map.get(five));
+        map.remove(five, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+        map.remove(four, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(four));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        ConcurrentNavigableMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testSize() {
+        ConcurrentNavigableMap map = map5();
+        ConcurrentNavigableMap empty = map0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        ConcurrentNavigableMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testContainsValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map0();
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testPutIfAbsent1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testReplace_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testReplaceValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.replace(null, one, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testRemove2_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = map5();
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        NavigableMap x = map5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.subMap(two, four);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.subMap(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.headMap(four);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        ConcurrentNavigableMap map = map5();
+        SortedMap sm = map.tailMap(two);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(four);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testDescendingClear() {
+        ConcurrentNavigableMap map = dmap5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testDescendingEquals() {
+        ConcurrentNavigableMap map1 = dmap5();
+        ConcurrentNavigableMap map2 = dmap5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testDescendingContainsKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsKey(m1));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testDescendingContainsValue() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testDescendingGet() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", (String)map.get(m1));
+        ConcurrentNavigableMap empty = dmap0();
+        assertNull(empty.get(m1));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testDescendingIsEmpty() {
+        ConcurrentNavigableMap empty = dmap0();
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testDescendingFirstKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals(m1, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testDescendingLastKey() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals(m5, map.lastKey());
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testDescendingKeySet() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(m1));
+        assertTrue(s.contains(m2));
+        assertTrue(s.contains(m3));
+        assertTrue(s.contains(m4));
+        assertTrue(s.contains(m5));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, m1);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testDescendingValues() {
+        ConcurrentNavigableMap map = dmap5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testDescendingAscendingKeySetToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingDescendingKeySetToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * Values.toArray contains all values
+     */
+    public void testDescendingValuesToArray() {
+        ConcurrentNavigableMap map = dmap5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        ConcurrentNavigableMap map = dmap5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(m1) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(m2) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(m3) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(m4) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(m5) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testDescendingPutAll() {
+        ConcurrentNavigableMap empty = dmap0();
+        ConcurrentNavigableMap map = dmap5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(m1));
+        assertTrue(empty.containsKey(m2));
+        assertTrue(empty.containsKey(m3));
+        assertTrue(empty.containsKey(m4));
+        assertTrue(empty.containsKey(m5));
+    }
+
+    /**
+     * putIfAbsent works when the given key is not present
+     */
+    public void testDescendingPutIfAbsent() {
+        ConcurrentNavigableMap map = dmap5();
+        map.putIfAbsent(six, "Z");
+        assertTrue(map.containsKey(six));
+    }
+
+    /**
+     * putIfAbsent does not add the pair if the key is already present
+     */
+    public void testDescendingPutIfAbsent2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.putIfAbsent(m1, "Z"));
+    }
+
+    /**
+     * replace fails when the given key is not present
+     */
+    public void testDescendingReplace() {
+        ConcurrentNavigableMap map = dmap5();
+        assertNull(map.replace(six, "Z"));
+        assertFalse(map.containsKey(six));
+    }
+
+    /**
+     * replace succeeds if the key is already present
+     */
+    public void testDescendingReplace2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertNotNull(map.replace(m1, "Z"));
+        assertEquals("Z", map.get(m1));
+    }
+
+    /**
+     * replace value fails when the given key not mapped to expected value
+     */
+    public void testDescendingReplaceValue() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.get(m1));
+        assertFalse(map.replace(m1, "Z", "Z"));
+        assertEquals("A", map.get(m1));
+    }
+
+    /**
+     * replace value succeeds when the given key mapped to expected value
+     */
+    public void testDescendingReplaceValue2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertEquals("A", map.get(m1));
+        assertTrue(map.replace(m1, "A", "Z"));
+        assertEquals("Z", map.get(m1));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testDescendingRemove() {
+        ConcurrentNavigableMap map = dmap5();
+        map.remove(m5);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(m5));
+    }
+
+    /**
+     * remove(key,value) removes only if pair present
+     */
+    public void testDescendingRemove2() {
+        ConcurrentNavigableMap map = dmap5();
+        assertTrue(map.containsKey(m5));
+        assertEquals("E", map.get(m5));
+        map.remove(m5, "E");
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(m5));
+        map.remove(m4, "A");
+        assertEquals(4, map.size());
+        assertTrue(map.containsKey(m4));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testDescendingLowerEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.lowerEntry(m3);
+        assertEquals(m2, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(m1);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testDescendingHigherEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.higherEntry(m3);
+        assertEquals(m4, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(m5);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testDescendingFloorEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.floorEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(m1);
+        assertEquals(m1, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testDescendingCeilingEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e1 = map.ceilingEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(m5);
+        assertEquals(m5, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testDescendingPollFirstEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m2, e.getKey());
+        map.put(m1, "A");
+        e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m4);
+        e = map.pollFirstEntry();
+        assertEquals(m5, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testDescendingPollLastEntry() {
+        ConcurrentNavigableMap map = dmap5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m4, e.getKey());
+        map.put(m5, "E");
+        e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m2);
+        e = map.pollLastEntry();
+        assertEquals(m1, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testDescendingSize() {
+        ConcurrentNavigableMap map = dmap5();
+        ConcurrentNavigableMap empty = dmap0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testDescendingToString() {
+        ConcurrentNavigableMap map = dmap5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception testDescendings
+
+    /**
+     * get(null) of empty map throws NPE
+     */
+    public void testDescendingGet_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of empty map throws NPE
+     */
+    public void testDescendingContainsKey_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsValue(null) throws NPE
+     */
+    public void testDescendingContainsValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap0();
+            c.containsValue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testDescendingPut1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * putIfAbsent(null, x) throws NPE
+     */
+    public void testDescendingPutIfAbsent1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.putIfAbsent(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x) throws NPE
+     */
+    public void testDescendingReplace_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.replace(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * replace(null, x, y) throws NPE
+     */
+    public void testDescendingReplaceValue_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.replace(null, m1, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testDescendingRemove1_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null, x) throws NPE
+     */
+    public void testDescendingRemove2_NullPointerException() {
+        try {
+            ConcurrentNavigableMap c = dmap5();
+            c.remove(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testDescendingSerialization() throws Exception {
+        NavigableMap x = dmap5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testDescendingSubMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m4);
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals("C", sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testDescendingSubMapContents2() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m2, sm.lastKey());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertFalse(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(m3), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingHeadMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.headMap(m4);
+        assertTrue(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(m4, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingTailMapContents() {
+        ConcurrentNavigableMap map = dmap5();
+        SortedMap sm = map.tailMap(m2);
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertTrue(sm.containsKey(m4));
+        assertTrue(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(m2, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m3, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m4, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(m4);
+        assertEquals(m4, ssm.firstKey());
+        assertEquals(m5, ssm.lastKey());
+        assertEquals("D", ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java
new file mode 100644
index 0000000..042fc62
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ConcurrentSkipListSubSetTest.java
@@ -0,0 +1,1142 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.SortedSet;
+import java.util.concurrent.ConcurrentSkipListSet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ConcurrentSkipListSubSetTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ConcurrentSkipListSubSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Returns a new set of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private NavigableSet<Integer> populatedSet(int n) {
+        ConcurrentSkipListSet<Integer> q =
+            new ConcurrentSkipListSet<Integer>();
+        assertTrue(q.isEmpty());
+
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.add(new Integer(i)));
+        assertTrue(q.add(new Integer(-n)));
+        assertTrue(q.add(new Integer(n)));
+        NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false);
+        assertFalse(s.isEmpty());
+        assertEquals(n, s.size());
+        return s;
+    }
+
+    /**
+     * Returns a new set of first 5 ints.
+     */
+    private NavigableSet set5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        q.add(zero);
+        q.add(seven);
+        NavigableSet s = q.subSet(one, true, seven, false);
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    /**
+     * Returns a new set of first 5 negative ints.
+     */
+    private NavigableSet dset5() {
+        ConcurrentSkipListSet q = new ConcurrentSkipListSet();
+        assertTrue(q.isEmpty());
+        q.add(m1);
+        q.add(m2);
+        q.add(m3);
+        q.add(m4);
+        q.add(m5);
+        NavigableSet s = q.descendingSet();
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    private static NavigableSet set0() {
+        ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+        assertTrue(set.isEmpty());
+        return set.tailSet(m1, true);
+    }
+
+    private static NavigableSet dset0() {
+        ConcurrentSkipListSet set = new ConcurrentSkipListSet();
+        assertTrue(set.isEmpty());
+        return set;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, set0().size());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        NavigableSet q = set0();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        NavigableSet q = set0();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+        assertFalse(q.add(six));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        NavigableSet q = set0();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        NavigableSet q = set0();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        NavigableSet q = set0();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        NavigableSet q = set0();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        NavigableSet q = set0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = set0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        NavigableSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        NavigableSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        NavigableSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        NavigableSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements in sorted order
+     */
+    public void testToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements in sorted order
+     */
+    public void testToArray2() {
+        NavigableSet<Integer> q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(set0().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final NavigableSet q = set0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        NavigableSet x = populatedSet(SIZE);
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testDescendingSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testDescendingAddNull() {
+        NavigableSet q = dset0();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testDescendingAdd() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testDescendingAddDup() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+        assertFalse(q.add(m6));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testDescendingAddNonComparable() {
+        NavigableSet q = dset0();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testDescendingAddAll1() {
+        NavigableSet q = dset0();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testDescendingAddAll2() {
+        NavigableSet q = dset0();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testDescendingAddAll3() {
+        NavigableSet q = dset0();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testDescendingAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        NavigableSet q = dset0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testDescendingPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testDescendingRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2 ) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testDescendingContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testDescendingClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testDescendingContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = dset0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testDescendingRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testDescendingRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testDescendingLower() {
+        NavigableSet q = dset5();
+        Object e1 = q.lower(m3);
+        assertEquals(m2, e1);
+
+        Object e2 = q.lower(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.lower(m1);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testDescendingHigher() {
+        NavigableSet q = dset5();
+        Object e1 = q.higher(m3);
+        assertEquals(m4, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.higher(m5);
+        assertNull(e3);
+
+        Object e4 = q.higher(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testDescendingFloor() {
+        NavigableSet q = dset5();
+        Object e1 = q.floor(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.floor(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.floor(m1);
+        assertEquals(m1, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testDescendingCeiling() {
+        NavigableSet q = dset5();
+        Object e1 = q.ceiling(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.ceiling(m5);
+        assertEquals(m5, e3);
+
+        Object e4 = q.ceiling(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testDescendingToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testDescendingToArray2() {
+        NavigableSet q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        assertSame(ints, q.toArray(ints));
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testDescendingEmptyIterator() {
+        NavigableSet q = dset0();
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(0, i);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final NavigableSet q = dset0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testDescendingToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testDescendingSerialization() throws Exception {
+        NavigableSet x = dset5();
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testDescendingSubSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m4);
+        assertEquals(m2, sm.first());
+        assertEquals(m3, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.first());
+        assertEquals(m3, sm.last());
+        assertTrue(sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testDescendingSubSetContents2() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.first());
+        assertEquals(m2, sm.last());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertFalse(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(m3));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testDescendingHeadSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.headSet(m4);
+        assertTrue(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(m4, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testDescendingTailSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.tailSet(m2);
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertTrue(sm.contains(m4));
+        assertTrue(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(m4);
+        assertEquals(m4, ssm.first());
+        assertEquals(m5, ssm.last());
+        assertTrue(ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java b/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java
new file mode 100644
index 0000000..70409c3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArrayListTest.java
@@ -0,0 +1,798 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CopyOnWriteArrayListTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return CopyOnWriteArrayList.class; }
+            public List emptyCollection() { return new CopyOnWriteArrayList(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return true; }
+        }
+        class SubListImplementation extends Implementation {
+            public List emptyCollection() {
+                return super.emptyCollection().subList(0, 0);
+            }
+        }
+        return newTestSuite(
+                CopyOnWriteArrayListTest.class,
+                CollectionTest.testSuite(new Implementation()),
+                CollectionTest.testSuite(new SubListImplementation()));
+    }
+
+    static CopyOnWriteArrayList<Integer> populatedArray(int n) {
+        CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<>();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < n; i++)
+            a.add(i);
+        assertFalse(a.isEmpty());
+        assertEquals(n, a.size());
+        return a;
+    }
+
+    static CopyOnWriteArrayList<Integer> populatedArray(Integer[] elements) {
+        CopyOnWriteArrayList<Integer> a = new CopyOnWriteArrayList<>();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < elements.length; i++)
+            a.add(elements[i]);
+        assertFalse(a.isEmpty());
+        assertEquals(elements.length, a.size());
+        return a;
+    }
+
+    /**
+     * a new list is empty
+     */
+    public void testConstructor() {
+        CopyOnWriteArrayList a = new CopyOnWriteArrayList();
+        assertTrue(a.isEmpty());
+    }
+
+    /**
+     * new list contains all elements of initializing array
+     */
+    public void testConstructor2() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        CopyOnWriteArrayList a = new CopyOnWriteArrayList(ints);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], a.get(i));
+    }
+
+    /**
+     * new list contains all elements of initializing collection
+     */
+    public void testConstructor3() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        CopyOnWriteArrayList a = new CopyOnWriteArrayList(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], a.get(i));
+    }
+
+    /**
+     * addAll adds each element from the given collection, including duplicates
+     */
+    public void testAddAll() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertTrue(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+        assertTrue(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(9, full.size());
+    }
+
+    /**
+     * addAllAbsent adds each element from the given collection that did not
+     * already exist in the List
+     */
+    public void testAddAllAbsent() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        // "one" is duplicate and will not be added
+        assertEquals(2, full.addAllAbsent(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+        assertEquals(0, full.addAllAbsent(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+    }
+
+    /**
+     * addIfAbsent will not add the element if it already exists in the list
+     */
+    public void testAddIfAbsent() {
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        full.addIfAbsent(one);
+        assertEquals(SIZE, full.size());
+    }
+
+    /**
+     * addIfAbsent adds the element when it does not exist in the list
+     */
+    public void testAddIfAbsent2() {
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        full.addIfAbsent(three);
+        assertTrue(full.contains(three));
+    }
+
+    /**
+     * clear removes all elements from the list
+     */
+    public void testClear() {
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        full.clear();
+        assertEquals(0, full.size());
+    }
+
+    /**
+     * Cloned list is equal
+     */
+    public void testClone() {
+        CopyOnWriteArrayList l1 = populatedArray(SIZE);
+        CopyOnWriteArrayList l2 = (CopyOnWriteArrayList)(l1.clone());
+        assertEquals(l1, l2);
+        l1.clear();
+        assertFalse(l1.equals(l2));
+    }
+
+    /**
+     * contains is true for added elements
+     */
+    public void testContains() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertTrue(full.contains(one));
+        assertFalse(full.contains(five));
+    }
+
+    /**
+     * adding at an index places it in the indicated index
+     */
+    public void testAddIndex() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        full.add(0, m1);
+        assertEquals(4, full.size());
+        assertEquals(m1, full.get(0));
+        assertEquals(zero, full.get(1));
+
+        full.add(2, m2);
+        assertEquals(5, full.size());
+        assertEquals(m2, full.get(2));
+        assertEquals(two, full.get(4));
+    }
+
+    /**
+     * lists with same elements are equal and have same hashCode
+     */
+    public void testEquals() {
+        CopyOnWriteArrayList a = populatedArray(3);
+        CopyOnWriteArrayList b = populatedArray(3);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        a.add(m1);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertFalse(b.containsAll(a));
+        b.add(m1);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+
+        assertFalse(a.equals(null));
+    }
+
+    /**
+     * containsAll returns true for collections with subset of elements
+     */
+    public void testContainsAll() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertTrue(full.containsAll(Arrays.asList()));
+        assertTrue(full.containsAll(Arrays.asList(one)));
+        assertTrue(full.containsAll(Arrays.asList(one, two)));
+        assertFalse(full.containsAll(Arrays.asList(one, two, six)));
+        assertFalse(full.containsAll(Arrays.asList(six)));
+
+        try {
+            full.containsAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * get returns the value at the given index
+     */
+    public void testGet() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertEquals(0, full.get(0));
+    }
+
+    /**
+     * indexOf gives the index for the given object
+     */
+    public void testIndexOf() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertEquals(1, full.indexOf(one));
+        assertEquals(-1, full.indexOf("puppies"));
+    }
+
+    /**
+     * indexOf gives the index based on the given index
+     * at which to start searching
+     */
+    public void testIndexOf2() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertEquals(1, full.indexOf(one, 0));
+        assertEquals(-1, full.indexOf(one, 2));
+    }
+
+    /**
+     * isEmpty returns true when empty, else false
+     */
+    public void testIsEmpty() {
+        CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        assertTrue(empty.isEmpty());
+        assertFalse(full.isEmpty());
+    }
+
+    /**
+     * iterator() returns an iterator containing the elements of the
+     * list in insertion order
+     */
+    public void testIterator() {
+        Collection empty = new CopyOnWriteArrayList();
+        assertFalse(empty.iterator().hasNext());
+        try {
+            empty.iterator().next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedArray(elements);
+
+        Iterator it = full.iterator();
+        for (int j = 0; j < SIZE; j++) {
+            assertTrue(it.hasNext());
+            assertEquals(elements[j], it.next());
+        }
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        Collection c = new CopyOnWriteArrayList();
+        assertIteratorExhausted(c.iterator());
+    }
+
+    /**
+     * iterator.remove throws UnsupportedOperationException
+     */
+    public void testIteratorRemove() {
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        Iterator it = full.iterator();
+        it.next();
+        try {
+            it.remove();
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        assertEquals("[]", new CopyOnWriteArrayList().toString());
+        CopyOnWriteArrayList full = populatedArray(3);
+        String s = full.toString();
+        for (int i = 0; i < 3; ++i)
+            assertTrue(s.contains(String.valueOf(i)));
+        assertEquals(new ArrayList(full).toString(),
+                     full.toString());
+    }
+
+    /**
+     * lastIndexOf returns the index for the given object
+     */
+    public void testLastIndexOf1() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        full.add(one);
+        full.add(three);
+        assertEquals(3, full.lastIndexOf(one));
+        assertEquals(-1, full.lastIndexOf(six));
+    }
+
+    /**
+     * lastIndexOf returns the index from the given starting point
+     */
+    public void testLastIndexOf2() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        full.add(one);
+        full.add(three);
+        assertEquals(3, full.lastIndexOf(one, 4));
+        assertEquals(-1, full.lastIndexOf(three, 3));
+    }
+
+    /**
+     * listIterator traverses all elements
+     */
+    public void testListIterator1() {
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        ListIterator i = full.listIterator();
+        int j;
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j, i.next());
+        assertEquals(SIZE, j);
+    }
+
+    /**
+     * listIterator only returns those elements after the given index
+     */
+    public void testListIterator2() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        ListIterator i = full.listIterator(1);
+        int j;
+        for (j = 0; i.hasNext(); j++)
+            assertEquals(j + 1, i.next());
+        assertEquals(2, j);
+    }
+
+    /**
+     * remove(int) removes and returns the object at the given index
+     */
+    public void testRemove_int() {
+        int SIZE = 3;
+        for (int i = 0; i < SIZE; i++) {
+            CopyOnWriteArrayList full = populatedArray(SIZE);
+            assertEquals(i, full.remove(i));
+            assertEquals(SIZE - 1, full.size());
+            assertFalse(full.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * remove(Object) removes the object if found and returns true
+     */
+    public void testRemove_Object() {
+        int SIZE = 3;
+        for (int i = 0; i < SIZE; i++) {
+            CopyOnWriteArrayList full = populatedArray(SIZE);
+            assertFalse(full.remove(new Integer(-42)));
+            assertTrue(full.remove(new Integer(i)));
+            assertEquals(SIZE - 1, full.size());
+            assertFalse(full.contains(new Integer(i)));
+        }
+        CopyOnWriteArrayList x = new CopyOnWriteArrayList(Arrays.asList(4, 5, 6));
+        assertTrue(x.remove(new Integer(6)));
+        assertEquals(x, Arrays.asList(4, 5));
+        assertTrue(x.remove(new Integer(4)));
+        assertEquals(x, Arrays.asList(5));
+        assertTrue(x.remove(new Integer(5)));
+        assertEquals(x, Arrays.asList());
+        assertFalse(x.remove(new Integer(5)));
+    }
+
+    /**
+     * removeAll removes all elements from the given collection
+     */
+    public void testRemoveAll() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertTrue(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+        assertFalse(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+    }
+
+    /**
+     * set changes the element at the given index
+     */
+    public void testSet() {
+        CopyOnWriteArrayList full = populatedArray(3);
+        assertEquals(2, full.set(2, four));
+        assertEquals(4, full.get(2));
+    }
+
+    /**
+     * size returns the number of elements
+     */
+    public void testSize() {
+        CopyOnWriteArrayList empty = new CopyOnWriteArrayList();
+        CopyOnWriteArrayList full = populatedArray(SIZE);
+        assertEquals(SIZE, full.size());
+        assertEquals(0, empty.size());
+    }
+
+    /**
+     * toArray() returns an Object array containing all elements from
+     * the list in insertion order
+     */
+    public void testToArray() {
+        Object[] a = new CopyOnWriteArrayList().toArray();
+        assertTrue(Arrays.equals(new Object[0], a));
+        assertSame(Object[].class, a.getClass());
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedArray(elements);
+
+        assertTrue(Arrays.equals(elements, full.toArray()));
+        assertSame(Object[].class, full.toArray().getClass());
+    }
+
+    /**
+     * toArray(Integer array) returns an Integer array containing all
+     * elements from the list in insertion order
+     */
+    public void testToArray2() {
+        Collection empty = new CopyOnWriteArrayList();
+        Integer[] a;
+
+        a = new Integer[0];
+        assertSame(a, empty.toArray(a));
+
+        a = new Integer[SIZE / 2];
+        Arrays.fill(a, 42);
+        assertSame(a, empty.toArray(a));
+        assertNull(a[0]);
+        for (int i = 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedArray(elements);
+
+        Arrays.fill(a, 42);
+        assertTrue(Arrays.equals(elements, full.toArray(a)));
+        for (int i = 0; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+        assertSame(Integer[].class, full.toArray(a).getClass());
+
+        a = new Integer[SIZE];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.equals(elements, a));
+
+        a = new Integer[2 * SIZE];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
+        assertNull(a[SIZE]);
+        for (int i = SIZE + 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+    }
+
+    /**
+     * sublists contains elements at indexes offset from their base
+     */
+    public void testSubList() {
+        CopyOnWriteArrayList a = populatedArray(10);
+        assertTrue(a.subList(1,1).isEmpty());
+        for (int j = 0; j < 9; ++j) {
+            for (int i = j ; i < 10; ++i) {
+                List b = a.subList(j,i);
+                for (int k = j; k < i; ++k) {
+                    assertEquals(new Integer(k), b.get(k-j));
+                }
+            }
+        }
+
+        List s = a.subList(2, 5);
+        assertEquals(3, s.size());
+        s.set(2, m1);
+        assertEquals(a.get(4), m1);
+        s.clear();
+        assertEquals(7, a.size());
+    }
+
+    // Exception tests
+
+    /**
+     * toArray throws an ArrayStoreException when the given array
+     * can not store the objects inside the list
+     */
+    public void testToArray_ArrayStoreException() {
+        CopyOnWriteArrayList c = new CopyOnWriteArrayList();
+        c.add("zfasdfsdf");
+        c.add("asdadasd");
+        try {
+            c.toArray(new Long[5]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * get throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testGet1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.get(-1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * get throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testGet2_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.get(list.size());
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * set throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testSet1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.set(-1, "qwerty");
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * set throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testSet2() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.set(list.size(), "qwerty");
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * add throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testAdd1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.add(-1, "qwerty");
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * add throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testAdd2_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.add(list.size() + 1, "qwerty");
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * remove throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testRemove1_IndexOutOfBounds() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.remove(-1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * remove throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testRemove2_IndexOutOfBounds() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.remove(list.size());
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * addAll throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testAddAll1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.addAll(-1, new LinkedList());
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * addAll throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testAddAll2_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.addAll(list.size() + 1, new LinkedList());
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * listIterator throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testListIterator1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.listIterator(-1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * listIterator throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testListIterator2_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.listIterator(list.size() + 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * subList throws an IndexOutOfBoundsException on a negative index
+     */
+    public void testSubList1_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.subList(-1, list.size());
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * subList throws an IndexOutOfBoundsException on a too high index
+     */
+    public void testSubList2_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.subList(0, list.size() + 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * subList throws IndexOutOfBoundsException when the second index
+     * is lower then the first
+     */
+    public void testSubList3_IndexOutOfBoundsException() {
+        CopyOnWriteArrayList c = populatedArray(5);
+        List[] lists = { c, c.subList(1, c.size() - 1) };
+        for (List list : lists) {
+            try {
+                list.subList(list.size() - 1, 1);
+                shouldThrow();
+            } catch (IndexOutOfBoundsException success) {}
+        }
+    }
+
+    /**
+     * a deserialized serialized list is equal
+     */
+    public void testSerialization() throws Exception {
+        List x = populatedArray(SIZE);
+        List y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(0), y.remove(0));
+        }
+        assertTrue(y.isEmpty());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java b/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java
new file mode 100644
index 0000000..d7fea36
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CopyOnWriteArraySetTest.java
@@ -0,0 +1,432 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArraySet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CopyOnWriteArraySetTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(CopyOnWriteArraySetTest.class);
+    }
+
+    static CopyOnWriteArraySet<Integer> populatedSet(int n) {
+        CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<>();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < n; i++)
+            a.add(i);
+        assertEquals(n == 0, a.isEmpty());
+        assertEquals(n, a.size());
+        return a;
+    }
+
+    static CopyOnWriteArraySet populatedSet(Integer[] elements) {
+        CopyOnWriteArraySet<Integer> a = new CopyOnWriteArraySet<>();
+        assertTrue(a.isEmpty());
+        for (int i = 0; i < elements.length; i++)
+            a.add(elements[i]);
+        assertFalse(a.isEmpty());
+        assertEquals(elements.length, a.size());
+        return a;
+    }
+
+    /**
+     * Default-constructed set is empty
+     */
+    public void testConstructor() {
+        CopyOnWriteArraySet a = new CopyOnWriteArraySet();
+        assertTrue(a.isEmpty());
+    }
+
+    /**
+     * Collection-constructed set holds all of its elements
+     */
+    public void testConstructor3() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        CopyOnWriteArraySet a = new CopyOnWriteArraySet(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertTrue(a.contains(ints[i]));
+    }
+
+    /**
+     * addAll adds each non-duplicate element from the given collection
+     */
+    public void testAddAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, five)));
+        assertEquals(6, full.size());
+    }
+
+    /**
+     * addAll adds each non-duplicate element from the given collection
+     */
+    public void testAddAll2() {
+        Set full = populatedSet(3);
+        // "one" is duplicate and will not be added
+        assertTrue(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+        assertFalse(full.addAll(Arrays.asList(three, four, one)));
+        assertEquals(5, full.size());
+    }
+
+    /**
+     * add will not add the element if it already exists in the set
+     */
+    public void testAdd2() {
+        Set full = populatedSet(3);
+        full.add(one);
+        assertEquals(3, full.size());
+    }
+
+    /**
+     * add adds the element when it does not exist in the set
+     */
+    public void testAdd3() {
+        Set full = populatedSet(3);
+        full.add(three);
+        assertTrue(full.contains(three));
+    }
+
+    /**
+     * clear removes all elements from the set
+     */
+    public void testClear() {
+        Collection full = populatedSet(3);
+        full.clear();
+        assertEquals(0, full.size());
+        assertTrue(full.isEmpty());
+    }
+
+    /**
+     * contains returns true for added elements
+     */
+    public void testContains() {
+        Collection full = populatedSet(3);
+        assertTrue(full.contains(one));
+        assertFalse(full.contains(five));
+    }
+
+    /**
+     * Sets with equal elements are equal
+     */
+    public void testEquals() {
+        CopyOnWriteArraySet a = populatedSet(3);
+        CopyOnWriteArraySet b = populatedSet(3);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        assertEquals(a.size(), b.size());
+
+        a.add(m1);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertFalse(b.containsAll(a));
+        b.add(m1);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+
+        Object x = a.iterator().next();
+        a.remove(x);
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        a.add(x);
+        assertTrue(a.equals(b));
+        assertTrue(b.equals(a));
+        assertTrue(a.containsAll(b));
+        assertTrue(b.containsAll(a));
+        assertEquals(a.hashCode(), b.hashCode());
+        assertEquals(a.size(), b.size());
+
+        CopyOnWriteArraySet empty1 = new CopyOnWriteArraySet(Arrays.asList());
+        CopyOnWriteArraySet empty2 = new CopyOnWriteArraySet(Arrays.asList());
+        assertTrue(empty1.equals(empty1));
+        assertTrue(empty1.equals(empty2));
+
+        assertFalse(empty1.equals(a));
+        assertFalse(a.equals(empty1));
+
+        assertFalse(a.equals(null));
+    }
+
+    /**
+     * containsAll returns true for collections with subset of elements
+     */
+    public void testContainsAll() {
+        Collection full = populatedSet(3);
+        assertTrue(full.containsAll(full));
+        assertTrue(full.containsAll(Arrays.asList()));
+        assertTrue(full.containsAll(Arrays.asList(one)));
+        assertTrue(full.containsAll(Arrays.asList(one, two)));
+        assertFalse(full.containsAll(Arrays.asList(one, two, six)));
+        assertFalse(full.containsAll(Arrays.asList(six)));
+
+        CopyOnWriteArraySet empty1 = new CopyOnWriteArraySet(Arrays.asList());
+        CopyOnWriteArraySet empty2 = new CopyOnWriteArraySet(Arrays.asList());
+        assertTrue(empty1.containsAll(empty2));
+        assertTrue(empty1.containsAll(empty1));
+        assertFalse(empty1.containsAll(full));
+        assertTrue(full.containsAll(empty1));
+
+        try {
+            full.containsAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * isEmpty is true when empty, else false
+     */
+    public void testIsEmpty() {
+        assertTrue(populatedSet(0).isEmpty());
+        assertFalse(populatedSet(3).isEmpty());
+    }
+
+    /**
+     * iterator() returns an iterator containing the elements of the
+     * set in insertion order
+     */
+    public void testIterator() {
+        Collection empty = new CopyOnWriteArraySet();
+        assertFalse(empty.iterator().hasNext());
+        try {
+            empty.iterator().next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        Iterator it = full.iterator();
+        for (int j = 0; j < SIZE; j++) {
+            assertTrue(it.hasNext());
+            assertEquals(elements[j], it.next());
+        }
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new CopyOnWriteArraySet().iterator());
+    }
+
+    /**
+     * iterator remove is unsupported
+     */
+    public void testIteratorRemove() {
+        Collection full = populatedSet(3);
+        Iterator it = full.iterator();
+        it.next();
+        try {
+            it.remove();
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * toString holds toString of elements
+     */
+    public void testToString() {
+        assertEquals("[]", new CopyOnWriteArraySet().toString());
+        Collection full = populatedSet(3);
+        String s = full.toString();
+        for (int i = 0; i < 3; ++i)
+            assertTrue(s.contains(String.valueOf(i)));
+        assertEquals(new ArrayList(full).toString(),
+                     full.toString());
+    }
+
+    /**
+     * removeAll removes all elements from the given collection
+     */
+    public void testRemoveAll() {
+        Set full = populatedSet(3);
+        assertTrue(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+        assertFalse(full.removeAll(Arrays.asList(one, two)));
+        assertEquals(1, full.size());
+    }
+
+    /**
+     * remove removes an element
+     */
+    public void testRemove() {
+        Collection full = populatedSet(3);
+        full.remove(one);
+        assertFalse(full.contains(one));
+        assertEquals(2, full.size());
+    }
+
+    /**
+     * size returns the number of elements
+     */
+    public void testSize() {
+        Collection empty = new CopyOnWriteArraySet();
+        Collection full = populatedSet(3);
+        assertEquals(3, full.size());
+        assertEquals(0, empty.size());
+    }
+
+    /**
+     * toArray() returns an Object array containing all elements from
+     * the set in insertion order
+     */
+    public void testToArray() {
+        Object[] a = new CopyOnWriteArraySet().toArray();
+        assertTrue(Arrays.equals(new Object[0], a));
+        assertSame(Object[].class, a.getClass());
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        assertTrue(Arrays.equals(elements, full.toArray()));
+        assertSame(Object[].class, full.toArray().getClass());
+    }
+
+    /**
+     * toArray(Integer array) returns an Integer array containing all
+     * elements from the set in insertion order
+     */
+    public void testToArray2() {
+        Collection empty = new CopyOnWriteArraySet();
+        Integer[] a;
+
+        a = new Integer[0];
+        assertSame(a, empty.toArray(a));
+
+        a = new Integer[SIZE / 2];
+        Arrays.fill(a, 42);
+        assertSame(a, empty.toArray(a));
+        assertNull(a[0]);
+        for (int i = 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+
+        Integer[] elements = new Integer[SIZE];
+        for (int i = 0; i < SIZE; i++)
+            elements[i] = i;
+        shuffle(elements);
+        Collection<Integer> full = populatedSet(elements);
+
+        Arrays.fill(a, 42);
+        assertTrue(Arrays.equals(elements, full.toArray(a)));
+        for (int i = 0; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+        assertSame(Integer[].class, full.toArray(a).getClass());
+
+        a = new Integer[SIZE];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.equals(elements, a));
+
+        a = new Integer[2 * SIZE];
+        Arrays.fill(a, 42);
+        assertSame(a, full.toArray(a));
+        assertTrue(Arrays.equals(elements, Arrays.copyOf(a, SIZE)));
+        assertNull(a[SIZE]);
+        for (int i = SIZE + 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+    }
+
+    /**
+     * toArray throws an ArrayStoreException when the given array can
+     * not store the objects inside the set
+     */
+    public void testToArray_ArrayStoreException() {
+        CopyOnWriteArraySet c = new CopyOnWriteArraySet();
+        c.add("zfasdfsdf");
+        c.add("asdadasd");
+        try {
+            c.toArray(new Long[5]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * A deserialized serialized set is equal
+     */
+    public void testSerialization() throws Exception {
+        Set x = populatedSet(SIZE);
+        Set y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * addAll is idempotent
+     */
+    public void testAddAll_idempotent() throws Exception {
+        Set x = populatedSet(SIZE);
+        Set y = new CopyOnWriteArraySet(x);
+        y.addAll(x);
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CountDownLatchTest.java b/ojluni/src/test/java/util/concurrent/tck/CountDownLatchTest.java
new file mode 100644
index 0000000..e9ab578
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CountDownLatchTest.java
@@ -0,0 +1,224 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CountDownLatchTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(CountDownLatchTest.class);
+    }
+
+    /**
+     * negative constructor argument throws IAE
+     */
+    public void testConstructor() {
+        try {
+            new CountDownLatch(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getCount returns initial count and decreases after countDown
+     */
+    public void testGetCount() {
+        final CountDownLatch l = new CountDownLatch(2);
+        assertEquals(2, l.getCount());
+        l.countDown();
+        assertEquals(1, l.getCount());
+    }
+
+    /**
+     * countDown decrements count when positive and has no effect when zero
+     */
+    public void testCountDown() {
+        final CountDownLatch l = new CountDownLatch(1);
+        assertEquals(1, l.getCount());
+        l.countDown();
+        assertEquals(0, l.getCount());
+        l.countDown();
+        assertEquals(0, l.getCount());
+    }
+
+    /**
+     * await returns after countDown to zero, but not before
+     */
+    public void testAwait() {
+        final CountDownLatch l = new CountDownLatch(2);
+        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertEquals(2, l.getCount());
+                pleaseCountDown.countDown();
+                l.await();
+                assertEquals(0, l.getCount());
+            }});
+
+        await(pleaseCountDown);
+        assertEquals(2, l.getCount());
+        l.countDown();
+        assertEquals(1, l.getCount());
+        assertThreadStaysAlive(t);
+        l.countDown();
+        assertEquals(0, l.getCount());
+        awaitTermination(t);
+    }
+
+    /**
+     * timed await returns after countDown to zero
+     */
+    public void testTimedAwait() {
+        final CountDownLatch l = new CountDownLatch(2);
+        final CountDownLatch pleaseCountDown = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertEquals(2, l.getCount());
+                pleaseCountDown.countDown();
+                assertTrue(l.await(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(0, l.getCount());
+            }});
+
+        await(pleaseCountDown);
+        assertEquals(2, l.getCount());
+        l.countDown();
+        assertEquals(1, l.getCount());
+        assertThreadStaysAlive(t);
+        l.countDown();
+        assertEquals(0, l.getCount());
+        awaitTermination(t);
+    }
+
+    /**
+     * await throws IE if interrupted before counted down
+     */
+    public void testAwait_Interruptible() {
+        final CountDownLatch l = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.currentThread().interrupt();
+                try {
+                    l.await();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    l.await();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertEquals(1, l.getCount());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed await throws IE if interrupted before counted down
+     */
+    public void testTimedAwait_Interruptible() {
+        final CountDownLatch l = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.currentThread().interrupt();
+                try {
+                    l.await(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    l.await(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertEquals(1, l.getCount());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed await times out if not counted down before timeout
+     */
+    public void testAwaitTimeout() throws InterruptedException {
+        final CountDownLatch l = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertEquals(1, l.getCount());
+                assertFalse(l.await(timeoutMillis(), MILLISECONDS));
+                assertEquals(1, l.getCount());
+            }});
+
+        awaitTermination(t);
+        assertEquals(1, l.getCount());
+    }
+
+    /**
+     * toString indicates current count
+     */
+    public void testToString() {
+        CountDownLatch s = new CountDownLatch(2);
+        assertTrue(s.toString().contains("Count = 2"));
+        s.countDown();
+        assertTrue(s.toString().contains("Count = 1"));
+        s.countDown();
+        assertTrue(s.toString().contains("Count = 0"));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CountedCompleter8Test.java b/ojluni/src/test/java/util/concurrent/tck/CountedCompleter8Test.java
new file mode 100644
index 0000000..663c2b5
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CountedCompleter8Test.java
@@ -0,0 +1,169 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CountedCompleter8Test extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(CountedCompleter8Test.class);
+    }
+
+    /** CountedCompleter class javadoc code sample, version 1. */
+    public static <E> void forEach1(E[] array, Consumer<E> action) {
+        class Task extends CountedCompleter<Void> {
+            final int lo, hi;
+            Task(Task parent, int lo, int hi) {
+                super(parent); this.lo = lo; this.hi = hi;
+            }
+
+            public void compute() {
+                if (hi - lo >= 2) {
+                    int mid = (lo + hi) >>> 1;
+                    // must set pending count before fork
+                    setPendingCount(2);
+                    new Task(this, mid, hi).fork(); // right child
+                    new Task(this, lo, mid).fork(); // left child
+                }
+                else if (hi > lo)
+                    action.accept(array[lo]);
+                tryComplete();
+            }
+        }
+        new Task(null, 0, array.length).invoke();
+    }
+
+    /** CountedCompleter class javadoc code sample, version 2. */
+    public static <E> void forEach2(E[] array, Consumer<E> action) {
+        class Task extends CountedCompleter<Void> {
+            final int lo, hi;
+            Task(Task parent, int lo, int hi) {
+                super(parent); this.lo = lo; this.hi = hi;
+            }
+
+            public void compute() {
+                if (hi - lo >= 2) {
+                    int mid = (lo + hi) >>> 1;
+                    setPendingCount(1); // looks off by one, but correct!
+                    new Task(this, mid, hi).fork(); // right child
+                    new Task(this, lo, mid).compute(); // direct invoke
+                } else {
+                    if (hi > lo)
+                        action.accept(array[lo]);
+                    tryComplete();
+                }
+            }
+        }
+        new Task(null, 0, array.length).invoke();
+    }
+
+    /** CountedCompleter class javadoc code sample, version 3. */
+    public static <E> void forEach3(E[] array, Consumer<E> action) {
+        class Task extends CountedCompleter<Void> {
+            final int lo, hi;
+            Task(Task parent, int lo, int hi) {
+                super(parent); this.lo = lo; this.hi = hi;
+            }
+
+            public void compute() {
+                int n = hi - lo;
+                for (; n >= 2; n /= 2) {
+                    addToPendingCount(1);
+                    new Task(this, lo + n/2, lo + n).fork();
+                }
+                if (n > 0)
+                    action.accept(array[lo]);
+                propagateCompletion();
+            }
+        }
+        new Task(null, 0, array.length).invoke();
+    }
+
+    /** CountedCompleter class javadoc code sample, version 4. */
+    public static <E> void forEach4(E[] array, Consumer<E> action) {
+        class Task extends CountedCompleter<Void> {
+            final int lo, hi;
+            Task(Task parent, int lo, int hi) {
+                super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
+                this.lo = lo; this.hi = hi;
+            }
+
+            public void compute() {
+                for (int n = hi - lo; n >= 2; n /= 2)
+                    new Task(this, lo + n/2, lo + n).fork();
+                action.accept(array[lo]);
+                propagateCompletion();
+            }
+        }
+        if (array.length > 0)
+            new Task(null, 0, array.length).invoke();
+    }
+
+    void testRecursiveDecomposition(
+        BiConsumer<Integer[], Consumer<Integer>> action) {
+        int n = ThreadLocalRandom.current().nextInt(8);
+        Integer[] a = new Integer[n];
+        for (int i = 0; i < n; i++) a[i] = i + 1;
+        AtomicInteger ai = new AtomicInteger(0);
+        action.accept(a, ai::addAndGet);
+        assertEquals(n * (n + 1) / 2, ai.get());
+    }
+
+    /**
+     * Variants of divide-by-two recursive decomposition into leaf tasks,
+     * as described in the CountedCompleter class javadoc code samples
+     */
+    public void testRecursiveDecomposition() {
+        testRecursiveDecomposition(CountedCompleter8Test::forEach1);
+        testRecursiveDecomposition(CountedCompleter8Test::forEach2);
+        testRecursiveDecomposition(CountedCompleter8Test::forEach3);
+        testRecursiveDecomposition(CountedCompleter8Test::forEach4);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CountedCompleterTest.java b/ojluni/src/test/java/util/concurrent/tck/CountedCompleterTest.java
new file mode 100644
index 0000000..241ca03
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CountedCompleterTest.java
@@ -0,0 +1,1874 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CountedCompleterTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(CountedCompleterTest.class);
+    }
+
+    // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+    static final int mainPoolSize =
+        Math.max(2, Runtime.getRuntime().availableProcessors());
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool(mainPoolSize);
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            assertFalse(a.isDone());
+            assertFalse(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+
+            assertNull(pool.invoke(a));
+
+            assertTrue(a.isDone());
+            assertTrue(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+        }
+    }
+
+    void checkNotDone(CountedCompleter a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedNormally(CountedCompleter<?> a) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            assertNull(a.join());
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertNull(a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertNull(a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(CountedCompleter a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+        assertTrue(a.cancel(false));
+        assertTrue(a.cancel(true));
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(CountedCompleter a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(t.getClass(), expected.getClass());
+        }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.invoke();
+            shouldThrow();
+        } catch (Throwable success) {
+            assertSame(t, success);
+        }
+    }
+
+    public static final class FJException extends RuntimeException {
+        FJException() { super(); }
+    }
+
+    abstract class CheckedCC extends CountedCompleter<Object> {
+        final AtomicInteger computeN = new AtomicInteger(0);
+        final AtomicInteger onCompletionN = new AtomicInteger(0);
+        final AtomicInteger onExceptionalCompletionN = new AtomicInteger(0);
+        final AtomicInteger setRawResultN = new AtomicInteger(0);
+        final AtomicReference<Object> rawResult = new AtomicReference<>(null);
+        int computeN() { return computeN.get(); }
+        int onCompletionN() { return onCompletionN.get(); }
+        int onExceptionalCompletionN() { return onExceptionalCompletionN.get(); }
+        int setRawResultN() { return setRawResultN.get(); }
+
+        CheckedCC() { super(); }
+        CheckedCC(CountedCompleter p) { super(p); }
+        CheckedCC(CountedCompleter p, int n) { super(p, n); }
+        abstract void realCompute();
+        public final void compute() {
+            computeN.incrementAndGet();
+            realCompute();
+        }
+        public void onCompletion(CountedCompleter caller) {
+            onCompletionN.incrementAndGet();
+            super.onCompletion(caller);
+        }
+        public boolean onExceptionalCompletion(Throwable ex,
+                                               CountedCompleter caller) {
+            onExceptionalCompletionN.incrementAndGet();
+            assertNotNull(ex);
+            assertTrue(isCompletedAbnormally());
+            assertTrue(super.onExceptionalCompletion(ex, caller));
+            return true;
+        }
+        protected void setRawResult(Object t) {
+            setRawResultN.incrementAndGet();
+            rawResult.set(t);
+            super.setRawResult(t);
+        }
+        void checkIncomplete() {
+            assertEquals(0, computeN());
+            assertEquals(0, onCompletionN());
+            assertEquals(0, onExceptionalCompletionN());
+            assertEquals(0, setRawResultN());
+            checkNotDone(this);
+        }
+        void checkCompletes(Object rawResult) {
+            checkIncomplete();
+            int pendingCount = getPendingCount();
+            complete(rawResult);
+            assertEquals(pendingCount, getPendingCount());
+            assertEquals(0, computeN());
+            assertEquals(1, onCompletionN());
+            assertEquals(0, onExceptionalCompletionN());
+            assertEquals(1, setRawResultN());
+            assertSame(rawResult, this.rawResult.get());
+            checkCompletedNormally(this);
+        }
+        void checkCompletesExceptionally(Throwable ex) {
+            checkIncomplete();
+            completeExceptionally(ex);
+            checkCompletedExceptionally(ex);
+        }
+        void checkCompletedExceptionally(Throwable ex) {
+            assertEquals(0, computeN());
+            assertEquals(0, onCompletionN());
+            assertEquals(1, onExceptionalCompletionN());
+            assertEquals(0, setRawResultN());
+            assertNull(this.rawResult.get());
+            checkCompletedAbnormally(this, ex);
+        }
+    }
+
+    final class NoopCC extends CheckedCC {
+        NoopCC() { super(); }
+        NoopCC(CountedCompleter p) { super(p); }
+        NoopCC(CountedCompleter p, int initialPendingCount) {
+            super(p, initialPendingCount);
+        }
+        protected void realCompute() {}
+    }
+
+    /**
+     * A newly constructed CountedCompleter is not completed;
+     * complete() causes completion. pendingCount is ignored.
+     */
+    public void testComplete() {
+        for (Object x : new Object[] { Boolean.TRUE, null }) {
+            for (int pendingCount : new int[] { 0, 42 }) {
+                testComplete(new NoopCC(), x, pendingCount);
+                testComplete(new NoopCC(new NoopCC()), x, pendingCount);
+            }
+        }
+    }
+    void testComplete(NoopCC cc, Object x, int pendingCount) {
+        cc.setPendingCount(pendingCount);
+        cc.checkCompletes(x);
+        assertEquals(pendingCount, cc.getPendingCount());
+    }
+
+    /**
+     * completeExceptionally completes exceptionally
+     */
+    public void testCompleteExceptionally() {
+        new NoopCC()
+            .checkCompletesExceptionally(new FJException());
+        new NoopCC(new NoopCC())
+            .checkCompletesExceptionally(new FJException());
+    }
+
+    /**
+     * completeExceptionally(null) surprisingly has the same effect as
+     * completeExceptionally(new RuntimeException())
+     */
+    public void testCompleteExceptionally_null() {
+        NoopCC a = new NoopCC();
+        a.completeExceptionally(null);
+        try {
+            a.invoke();
+            shouldThrow();
+        } catch (RuntimeException success) {
+            assertSame(success.getClass(), RuntimeException.class);
+            assertNull(success.getCause());
+            a.checkCompletedExceptionally(success);
+        }
+    }
+
+    /**
+     * setPendingCount sets the reported pending count
+     */
+    public void testSetPendingCount() {
+        NoopCC a = new NoopCC();
+        assertEquals(0, a.getPendingCount());
+        int[] vals = {
+             -1, 0, 1,
+             Integer.MIN_VALUE,
+             Integer.MAX_VALUE,
+        };
+        for (int val : vals) {
+            a.setPendingCount(val);
+            assertEquals(val, a.getPendingCount());
+        }
+    }
+
+    /**
+     * addToPendingCount adds to the reported pending count
+     */
+    public void testAddToPendingCount() {
+        NoopCC a = new NoopCC();
+        assertEquals(0, a.getPendingCount());
+        a.addToPendingCount(1);
+        assertEquals(1, a.getPendingCount());
+        a.addToPendingCount(27);
+        assertEquals(28, a.getPendingCount());
+        a.addToPendingCount(-28);
+        assertEquals(0, a.getPendingCount());
+    }
+
+    /**
+     * decrementPendingCountUnlessZero decrements reported pending
+     * count unless zero
+     */
+    public void testDecrementPendingCountUnlessZero() {
+        NoopCC a = new NoopCC(null, 2);
+        assertEquals(2, a.getPendingCount());
+        assertEquals(2, a.decrementPendingCountUnlessZero());
+        assertEquals(1, a.getPendingCount());
+        assertEquals(1, a.decrementPendingCountUnlessZero());
+        assertEquals(0, a.getPendingCount());
+        assertEquals(0, a.decrementPendingCountUnlessZero());
+        assertEquals(0, a.getPendingCount());
+        a.setPendingCount(-1);
+        assertEquals(-1, a.decrementPendingCountUnlessZero());
+        assertEquals(-2, a.getPendingCount());
+    }
+
+    /**
+     * compareAndSetPendingCount compares and sets the reported
+     * pending count
+     */
+    public void testCompareAndSetPendingCount() {
+        NoopCC a = new NoopCC();
+        assertEquals(0, a.getPendingCount());
+        assertTrue(a.compareAndSetPendingCount(0, 1));
+        assertEquals(1, a.getPendingCount());
+        assertTrue(a.compareAndSetPendingCount(1, 2));
+        assertEquals(2, a.getPendingCount());
+        assertFalse(a.compareAndSetPendingCount(1, 3));
+        assertEquals(2, a.getPendingCount());
+    }
+
+    /**
+     * getCompleter returns parent or null if at root
+     */
+    public void testGetCompleter() {
+        NoopCC a = new NoopCC();
+        assertNull(a.getCompleter());
+        CountedCompleter b = new NoopCC(a);
+        assertSame(a, b.getCompleter());
+        CountedCompleter c = new NoopCC(b);
+        assertSame(b, c.getCompleter());
+    }
+
+    /**
+     * getRoot returns self if no parent, else parent's root
+     */
+    public void testGetRoot() {
+        NoopCC a = new NoopCC();
+        NoopCC b = new NoopCC(a);
+        NoopCC c = new NoopCC(b);
+        assertSame(a, a.getRoot());
+        assertSame(a, b.getRoot());
+        assertSame(a, c.getRoot());
+    }
+
+    /**
+     * tryComplete decrements pending count unless zero, in which case
+     * causes completion
+     */
+    public void testTryComplete() {
+        NoopCC a = new NoopCC();
+        assertEquals(0, a.getPendingCount());
+        int n = 3;
+        a.setPendingCount(n);
+        for (; n > 0; n--) {
+            assertEquals(n, a.getPendingCount());
+            a.tryComplete();
+            a.checkIncomplete();
+            assertEquals(n - 1, a.getPendingCount());
+        }
+        a.tryComplete();
+        assertEquals(0, a.computeN());
+        assertEquals(1, a.onCompletionN());
+        assertEquals(0, a.onExceptionalCompletionN());
+        assertEquals(0, a.setRawResultN());
+        checkCompletedNormally(a);
+    }
+
+    /**
+     * propagateCompletion decrements pending count unless zero, in
+     * which case causes completion, without invoking onCompletion
+     */
+    public void testPropagateCompletion() {
+        NoopCC a = new NoopCC();
+        assertEquals(0, a.getPendingCount());
+        int n = 3;
+        a.setPendingCount(n);
+        for (; n > 0; n--) {
+            assertEquals(n, a.getPendingCount());
+            a.propagateCompletion();
+            a.checkIncomplete();
+            assertEquals(n - 1, a.getPendingCount());
+        }
+        a.propagateCompletion();
+        assertEquals(0, a.computeN());
+        assertEquals(0, a.onCompletionN());
+        assertEquals(0, a.onExceptionalCompletionN());
+        assertEquals(0, a.setRawResultN());
+        checkCompletedNormally(a);
+    }
+
+    /**
+     * firstComplete returns this if pending count is zero else null
+     */
+    public void testFirstComplete() {
+        NoopCC a = new NoopCC();
+        a.setPendingCount(1);
+        assertNull(a.firstComplete());
+        a.checkIncomplete();
+        assertSame(a, a.firstComplete());
+        a.checkIncomplete();
+    }
+
+    /**
+     * firstComplete.nextComplete returns parent if pending count is
+     * zero else null
+     */
+    public void testNextComplete() {
+        NoopCC a = new NoopCC();
+        NoopCC b = new NoopCC(a);
+        a.setPendingCount(1);
+        b.setPendingCount(1);
+        assertNull(b.firstComplete());
+        assertSame(b, b.firstComplete());
+        assertNull(b.nextComplete());
+        a.checkIncomplete();
+        b.checkIncomplete();
+        assertSame(a, b.nextComplete());
+        assertSame(a, b.nextComplete());
+        a.checkIncomplete();
+        b.checkIncomplete();
+        assertNull(a.nextComplete());
+        b.checkIncomplete();
+        checkCompletedNormally(a);
+    }
+
+    /**
+     * quietlyCompleteRoot completes root task and only root task
+     */
+    public void testQuietlyCompleteRoot() {
+        NoopCC a = new NoopCC();
+        NoopCC b = new NoopCC(a);
+        NoopCC c = new NoopCC(b);
+        a.setPendingCount(1);
+        b.setPendingCount(1);
+        c.setPendingCount(1);
+        c.quietlyCompleteRoot();
+        assertTrue(a.isDone());
+        assertFalse(b.isDone());
+        assertFalse(c.isDone());
+    }
+
+    // Invocation tests use some interdependent task classes
+    // to better test propagation etc
+
+    /**
+     * Version of Fibonacci with different classes for left vs right forks
+     */
+    abstract class CCF extends CheckedCC {
+        int number;
+        int rnumber;
+
+        public CCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        protected final void realCompute() {
+            CCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RCCF(f, n - 2).fork();
+                f = new LCCF(f, --n);
+            }
+            f.complete(null);
+        }
+    }
+
+    final class LCCF extends CCF {
+        public LCCF(int n) { this(null, n); }
+        public LCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            super.onCompletion(caller);
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    final class RCCF extends CCF {
+        public RCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            super.onCompletion(caller);
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.rnumber = n;
+            else
+                number = n;
+        }
+    }
+
+    // Version of CCF with forced failure in left completions
+    abstract class FailingCCF extends CheckedCC {
+        int number;
+        int rnumber;
+
+        public FailingCCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        protected final void realCompute() {
+            FailingCCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RFCCF(f, n - 2).fork();
+                f = new LFCCF(f, --n);
+            }
+            f.complete(null);
+        }
+    }
+
+    final class LFCCF extends FailingCCF {
+        public LFCCF(int n) { this(null, n); }
+        public LFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            super.onCompletion(caller);
+            FailingCCF p = (FailingCCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    final class RFCCF extends FailingCCF {
+        public RFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            super.onCompletion(caller);
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvoke() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPE() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                assertEquals(0, getQueuedTaskCount());
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() throws Exception {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        final ForkJoinPool mainPool = mainPool();
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertSame(mainPool, getPool());
+            }};
+        testInvokeOnPool(mainPool, a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertTrue(inForkJoinPool());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResult() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally2() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF n = new LCCF(8);
+                CCF f = new LCCF(n, 8);
+                FJException ex = new FJException();
+                f.completeExceptionally(ex);
+                f.checkCompletedExceptionally(ex);
+                n.checkCompletedExceptionally(ex);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                FailingCCF g = new LFCCF(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF g = new LFCCF(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                FailingCCF g = new LFCCF(9);
+                CCF h = new LCCF(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF h = new LCCF(7);
+                assertSame(h, h.fork());
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                assertNull(f.join());
+                checkCompletedNormally(f);
+                helpQuiesce();
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task without
+     * executing it
+     */
+    public void testPollNextLocalTask() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                assertEquals(34, g.number);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertNull(f.join());
+                helpQuiesce();
+                checkCompletedNormally(f);
+                assertEquals(34, g.number);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF g = new LCCF(9);
+                assertSame(g, g.fork());
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    // versions for singleton pools
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvokeSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvokeSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGetSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGetSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPESingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesceSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(0, getQueuedTaskCount());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvokeSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvokeSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGetSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGetSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvokeSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGetSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGetSingleton() throws Exception {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoinSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionallySingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF n = new LCCF(8);
+                CCF f = new LCCF(n, 8);
+                FJException ex = new FJException();
+                f.completeExceptionally(ex);
+                f.checkCompletedExceptionally(ex);
+                n.checkCompletedExceptionally(ex);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollectionSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPESingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                FailingCCF g = new LFCCF(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF g = new LFCCF(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3Singleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(8);
+                FailingCCF g = new LFCCF(9);
+                CCF h = new LCCF(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollectionSingleton() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(8);
+                CCF g = new LCCF(9);
+                CCF h = new LCCF(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/CyclicBarrierTest.java b/ojluni/src/test/java/util/concurrent/tck/CyclicBarrierTest.java
new file mode 100644
index 0000000..08258c6
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/CyclicBarrierTest.java
@@ -0,0 +1,490 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.BrokenBarrierException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class CyclicBarrierTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(CyclicBarrierTest.class);
+    }
+
+    /**
+     * Spin-waits till the number of waiters == numberOfWaiters.
+     */
+    void awaitNumberWaiting(CyclicBarrier barrier, int numberOfWaiters) {
+        long startTime = System.nanoTime();
+        while (barrier.getNumberWaiting() != numberOfWaiters) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                fail("timed out");
+            Thread.yield();
+        }
+    }
+
+    /**
+     * Creating with negative parties throws IAE
+     */
+    public void testConstructor1() {
+        try {
+            new CyclicBarrier(-1, (Runnable)null);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Creating with negative parties and no action throws IAE
+     */
+    public void testConstructor2() {
+        try {
+            new CyclicBarrier(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getParties returns the number of parties given in constructor
+     */
+    public void testGetParties() {
+        CyclicBarrier b = new CyclicBarrier(2);
+        assertEquals(2, b.getParties());
+        assertEquals(0, b.getNumberWaiting());
+    }
+
+    /**
+     * A 1-party barrier triggers after single await
+     */
+    public void testSingleParty() throws Exception {
+        CyclicBarrier b = new CyclicBarrier(1);
+        assertEquals(1, b.getParties());
+        assertEquals(0, b.getNumberWaiting());
+        b.await();
+        b.await();
+        assertEquals(0, b.getNumberWaiting());
+    }
+
+    /**
+     * The supplied barrier action is run at barrier
+     */
+    public void testBarrierAction() throws Exception {
+        final AtomicInteger count = new AtomicInteger(0);
+        final Runnable incCount = new Runnable() { public void run() {
+            count.getAndIncrement(); }};
+        CyclicBarrier b = new CyclicBarrier(1, incCount);
+        assertEquals(1, b.getParties());
+        assertEquals(0, b.getNumberWaiting());
+        b.await();
+        b.await();
+        assertEquals(0, b.getNumberWaiting());
+        assertEquals(2, count.get());
+    }
+
+    /**
+     * A 2-party/thread barrier triggers after both threads invoke await
+     */
+    public void testTwoParties() throws Exception {
+        final CyclicBarrier b = new CyclicBarrier(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                b.await();
+                b.await();
+                b.await();
+                b.await();
+            }});
+
+        b.await();
+        b.await();
+        b.await();
+        b.await();
+        awaitTermination(t);
+    }
+
+    /**
+     * An interruption in one party causes others waiting in await to
+     * throw BrokenBarrierException
+     */
+    public void testAwait1_Interrupted_BrokenBarrier() {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+        Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws Exception {
+                pleaseInterrupt.countDown();
+                c.await();
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                pleaseInterrupt.countDown();
+                c.await();
+            }};
+
+        t1.start();
+        t2.start();
+        await(pleaseInterrupt);
+        t1.interrupt();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * An interruption in one party causes others waiting in timed await to
+     * throw BrokenBarrierException
+     */
+    public void testAwait2_Interrupted_BrokenBarrier() throws Exception {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+        Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+            public void realRun() throws Exception {
+                pleaseInterrupt.countDown();
+                c.await(LONG_DELAY_MS, MILLISECONDS);
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                pleaseInterrupt.countDown();
+                c.await(LONG_DELAY_MS, MILLISECONDS);
+            }};
+
+        t1.start();
+        t2.start();
+        await(pleaseInterrupt);
+        t1.interrupt();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A timeout in timed await throws TimeoutException
+     */
+    public void testAwait3_TimeoutException() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                long startTime = System.nanoTime();
+                try {
+                    c.await(timeoutMillis(), MILLISECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {}
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * A timeout in one party causes others waiting in timed await to
+     * throw BrokenBarrierException
+     */
+    public void testAwait4_Timeout_BrokenBarrier() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                try {
+                    c.await(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (BrokenBarrierException success) {}
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                awaitNumberWaiting(c, 1);
+                long startTime = System.nanoTime();
+                try {
+                    c.await(timeoutMillis(), MILLISECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {}
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A timeout in one party causes others waiting in await to
+     * throw BrokenBarrierException
+     */
+    public void testAwait5_Timeout_BrokenBarrier() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                try {
+                    c.await();
+                    shouldThrow();
+                } catch (BrokenBarrierException success) {}
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                awaitNumberWaiting(c, 1);
+                long startTime = System.nanoTime();
+                try {
+                    c.await(timeoutMillis(), MILLISECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {}
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A reset of an active barrier causes waiting threads to throw
+     * BrokenBarrierException
+     */
+    public void testReset_BrokenBarrier() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        final CountDownLatch pleaseReset = new CountDownLatch(2);
+        Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                pleaseReset.countDown();
+                c.await();
+            }};
+        Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+            public void realRun() throws Exception {
+                pleaseReset.countDown();
+                c.await();
+            }};
+
+        t1.start();
+        t2.start();
+        await(pleaseReset);
+
+        awaitNumberWaiting(c, 2);
+        c.reset();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A reset before threads enter barrier does not throw
+     * BrokenBarrierException
+     */
+    public void testReset_NoBrokenBarrier() throws Exception {
+        final CyclicBarrier c = new CyclicBarrier(3);
+        c.reset();
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                c.await();
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                c.await();
+            }});
+
+        c.await();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * All threads block while a barrier is broken.
+     */
+    public void testReset_Leakage() throws InterruptedException {
+        final CyclicBarrier c = new CyclicBarrier(2);
+        final AtomicBoolean done = new AtomicBoolean();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                while (!done.get()) {
+                    try {
+                        while (c.isBroken())
+                            c.reset();
+
+                        c.await();
+                        shouldThrow();
+                    }
+                    catch (BrokenBarrierException ok) {}
+                    catch (InterruptedException ok) {}
+                }}});
+
+        for (int i = 0; i < 4; i++) {
+            delay(timeoutMillis());
+            t.interrupt();
+        }
+        done.set(true);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * Reset of a non-broken barrier does not break barrier
+     */
+    public void testResetWithoutBreakage() throws Exception {
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 3; i++) {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            Thread t1 = newStartedThread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }});
+
+            Thread t2 = newStartedThread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }});
+
+            start.await();
+            barrier.await();
+            awaitTermination(t1);
+            awaitTermination(t2);
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            if (i == 1) barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+
+    /**
+     * Reset of a barrier after interruption reinitializes it.
+     */
+    public void testResetAfterInterrupt() throws Exception {
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 2; i++) {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            Thread t1 = new ThreadShouldThrow(InterruptedException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            t1.start();
+            t2.start();
+            start.await();
+            t1.interrupt();
+            awaitTermination(t1);
+            awaitTermination(t2);
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+
+    /**
+     * Reset of a barrier after timeout reinitializes it.
+     */
+    public void testResetAfterTimeout() throws Exception {
+        final CyclicBarrier barrier = new CyclicBarrier(3);
+        for (int i = 0; i < 2; i++) {
+            assertEquals(0, barrier.getNumberWaiting());
+            Thread t1 = newStartedThread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    try {
+                        barrier.await();
+                        shouldThrow();
+                    } catch (BrokenBarrierException success) {}
+                }});
+            Thread t2 = newStartedThread(new CheckedRunnable() {
+                public void realRun() throws Exception {
+                    awaitNumberWaiting(barrier, 1);
+                    long startTime = System.nanoTime();
+                    try {
+                        barrier.await(timeoutMillis(), MILLISECONDS);
+                        shouldThrow();
+                    } catch (TimeoutException success) {}
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }});
+
+            awaitTermination(t1);
+            awaitTermination(t2);
+            assertEquals(0, barrier.getNumberWaiting());
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+
+    /**
+     * Reset of a barrier after a failed command reinitializes it.
+     */
+    public void testResetAfterCommandException() throws Exception {
+        final CyclicBarrier barrier =
+            new CyclicBarrier(3, new Runnable() {
+                    public void run() {
+                        throw new NullPointerException(); }});
+        for (int i = 0; i < 2; i++) {
+            final CyclicBarrier start = new CyclicBarrier(3);
+            Thread t1 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            Thread t2 = new ThreadShouldThrow(BrokenBarrierException.class) {
+                public void realRun() throws Exception {
+                    start.await();
+                    barrier.await();
+                }};
+
+            t1.start();
+            t2.start();
+            start.await();
+            awaitNumberWaiting(barrier, 2);
+            try {
+                barrier.await();
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            awaitTermination(t1);
+            awaitTermination(t2);
+            assertTrue(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+            barrier.reset();
+            assertFalse(barrier.isBroken());
+            assertEquals(0, barrier.getNumberWaiting());
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/DelayQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/DelayQueueTest.java
new file mode 100644
index 0000000..dfaf2d0
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/DelayQueueTest.java
@@ -0,0 +1,816 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.DelayQueue;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Test;
+
+public class DelayQueueTest extends JSR166TestCase {
+
+    public static class Generic extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new DelayQueue();
+        }
+        protected PDelay makeElement(int i) {
+            return new PDelay(i);
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return DelayQueue.class; }
+            public Collection emptyCollection() { return new DelayQueue(); }
+            public Object makeElement(int i) { return new PDelay(i); }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(DelayQueueTest.class,
+                            new Generic().testSuite(),
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * A fake Delayed implementation for testing.
+     * Most tests use PDelays, where delays are all elapsed
+     * (so, no blocking solely for delays) but are still ordered
+     */
+    static class PDelay implements Delayed {
+        final int pseudodelay;
+        PDelay(int pseudodelay) { this.pseudodelay = pseudodelay; }
+        public int compareTo(Delayed y) {
+            return Integer.compare(this.pseudodelay, ((PDelay)y).pseudodelay);
+        }
+        public boolean equals(Object other) {
+            return (other instanceof PDelay) &&
+                this.pseudodelay == ((PDelay)other).pseudodelay;
+        }
+        // suppress [overrides] javac warning
+        public int hashCode() { return pseudodelay; }
+        public long getDelay(TimeUnit ignore) {
+            return Integer.MIN_VALUE + pseudodelay;
+        }
+        public String toString() {
+            return String.valueOf(pseudodelay);
+        }
+    }
+
+    /**
+     * Delayed implementation that actually delays
+     */
+    static class NanoDelay implements Delayed {
+        final long trigger;
+        NanoDelay(long i) {
+            trigger = System.nanoTime() + i;
+        }
+
+        public int compareTo(Delayed y) {
+            return Long.compare(trigger, ((NanoDelay)y).trigger);
+        }
+
+        public boolean equals(Object other) {
+            return (other instanceof NanoDelay) &&
+                this.trigger == ((NanoDelay)other).trigger;
+        }
+
+        // suppress [overrides] javac warning
+        public int hashCode() { return (int) trigger; }
+
+        public long getDelay(TimeUnit unit) {
+            long n = trigger - System.nanoTime();
+            return unit.convert(n, TimeUnit.NANOSECONDS);
+        }
+
+        public long getTriggerTime() {
+            return trigger;
+        }
+
+        public String toString() {
+            return String.valueOf(trigger);
+        }
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * PDelays 0 ... n - 1.
+     */
+    private DelayQueue<PDelay> populatedQueue(int n) {
+        DelayQueue<PDelay> q = new DelayQueue<>();
+        assertTrue(q.isEmpty());
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.offer(new PDelay(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.offer(new PDelay(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        assertEquals(n, q.size());
+        assertEquals(new PDelay(0), q.peek());
+        return q;
+    }
+
+    /**
+     * A new queue has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(Integer.MAX_VALUE, new DelayQueue().remainingCapacity());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new DelayQueue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new DelayQueue(Arrays.asList(new PDelay[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        PDelay[] a = new PDelay[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            a[i] = new PDelay(i);
+        try {
+            new DelayQueue(Arrays.asList(a));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        PDelay[] ints = new PDelay[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new PDelay(i);
+        DelayQueue q = new DelayQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        DelayQueue q = new DelayQueue();
+        assertTrue(q.isEmpty());
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        q.add(new PDelay(1));
+        assertFalse(q.isEmpty());
+        q.add(new PDelay(2));
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * remainingCapacity() always returns Integer.MAX_VALUE
+     */
+    public void testRemainingCapacity() {
+        BlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(SIZE - i, q.size());
+            assertTrue(q.remove() instanceof PDelay);
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(i, q.size());
+            assertTrue(q.add(new PDelay(i)));
+        }
+    }
+
+    /**
+     * offer non-null succeeds
+     */
+    public void testOffer() {
+        DelayQueue q = new DelayQueue();
+        assertTrue(q.offer(new PDelay(0)));
+        assertTrue(q.offer(new PDelay(1)));
+    }
+
+    /**
+     * add succeeds
+     */
+    public void testAdd() {
+        DelayQueue q = new DelayQueue();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new PDelay(i)));
+        }
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        DelayQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        DelayQueue q = new DelayQueue();
+        PDelay[] a = new PDelay[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            a[i] = new PDelay(i);
+        try {
+            q.addAll(Arrays.asList(a));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        PDelay[] empty = new PDelay[0];
+        PDelay[] ints = new PDelay[SIZE];
+        for (int i = SIZE - 1; i >= 0; --i)
+            ints[i] = new PDelay(i);
+        DelayQueue q = new DelayQueue();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() {
+        DelayQueue q = new DelayQueue();
+        for (int i = 0; i < SIZE; ++i) {
+            PDelay x = new PDelay(i);
+            q.put(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(SIZE, q.size());
+    }
+
+    /**
+     * put doesn't block waiting for take
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final DelayQueue q = new DelayQueue();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+            }});
+
+        awaitTermination(t);
+        assertEquals(4, q.size());
+    }
+
+    /**
+     * timed offer does not time out
+     */
+    public void testTimedOffer() throws InterruptedException {
+        final DelayQueue q = new DelayQueue();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new PDelay(0));
+                q.put(new PDelay(0));
+                assertTrue(q.offer(new PDelay(0), SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(q.offer(new PDelay(0), LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in priority order
+     */
+    public void testTake() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.take());
+        }
+    }
+
+    /**
+     * Take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final DelayQueue q = populatedQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(new PDelay(i), ((PDelay)q.take()));
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(new PDelay(i), q.poll(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final DelayQueue q = populatedQueue(SIZE);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(new PDelay(i),
+                                 ((PDelay)q.poll(LONG_DELAY_MS, MILLISECONDS)));
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.peek());
+            assertEquals(new PDelay(i), q.poll());
+            if (q.isEmpty())
+                assertNull(q.peek());
+            else
+                assertFalse(new PDelay(i).equals(q.peek()));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.element());
+            q.poll();
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(new PDelay(i), q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        DelayQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new PDelay(i)));
+            q.poll();
+            assertFalse(q.contains(new PDelay(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        DelayQueue q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        PDelay x = new PDelay(1);
+        q.add(x);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(x));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        DelayQueue q = populatedQueue(SIZE);
+        DelayQueue p = new DelayQueue();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new PDelay(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        DelayQueue q = populatedQueue(SIZE);
+        DelayQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            DelayQueue q = populatedQueue(SIZE);
+            DelayQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                PDelay x = (PDelay)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() throws InterruptedException {
+        DelayQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.take());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() {
+        DelayQueue<PDelay> q = populatedQueue(SIZE);
+        PDelay[] ints = new PDelay[SIZE];
+        PDelay[] array = q.toArray(ints);
+        assertSame(ints, array);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.remove());
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        DelayQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        DelayQueue q = populatedQueue(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new DelayQueue().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final DelayQueue q = new DelayQueue();
+        q.add(new PDelay(2));
+        q.add(new PDelay(1));
+        q.add(new PDelay(3));
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+        it = q.iterator();
+        assertEquals(new PDelay(2), it.next());
+        assertEquals(new PDelay(3), it.next());
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        DelayQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (Object e : q)
+            assertTrue(s.contains(e.toString()));
+    }
+
+    /**
+     * timed poll transfers elements across Executor tasks
+     */
+    public void testPollInExecutor() {
+        final DelayQueue q = new DelayQueue();
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertNotNull(q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(new PDelay(1));
+                }});
+        }
+    }
+
+    /**
+     * Delayed actions do not occur until their delay elapses
+     */
+    public void testDelay() throws InterruptedException {
+        DelayQueue<NanoDelay> q = new DelayQueue<>();
+        for (int i = 0; i < SIZE; ++i)
+            q.add(new NanoDelay(1000000L * (SIZE - i)));
+
+        long last = 0;
+        for (int i = 0; i < SIZE; ++i) {
+            NanoDelay e = q.take();
+            long tt = e.getTriggerTime();
+            assertTrue(System.nanoTime() - tt >= 0);
+            if (i != 0)
+                assertTrue(tt >= last);
+            last = tt;
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * peek of a non-empty queue returns non-null even if not expired
+     */
+    public void testPeekDelayed() {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(Long.MAX_VALUE));
+        assertNotNull(q.peek());
+    }
+
+    /**
+     * poll of a non-empty queue returns null if no expired elements.
+     */
+    public void testPollDelayed() {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(Long.MAX_VALUE));
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll of a non-empty queue returns null if no expired elements.
+     */
+    public void testTimedPollDelayed() throws InterruptedException {
+        DelayQueue q = new DelayQueue();
+        q.add(new NanoDelay(LONG_DELAY_MS * 1000000L));
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+    }
+
+    /**
+     * drainTo(c) empties queue into another collection c
+     */
+    public void testDrainTo() {
+        DelayQueue q = new DelayQueue();
+        PDelay[] elems = new PDelay[SIZE];
+        for (int i = 0; i < SIZE; ++i) {
+            elems[i] = new PDelay(i);
+            q.add(elems[i]);
+        }
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(elems[i], l.get(i));
+        q.add(elems[0]);
+        q.add(elems[1]);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(elems[0]));
+        assertTrue(q.contains(elems[1]));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i)
+            assertEquals(elems[i], l.get(i));
+    }
+
+    /**
+     * drainTo empties queue
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final DelayQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new PDelay(SIZE + 1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        for (int i = 0; i < SIZE + 2; ++i) {
+            DelayQueue q = populatedQueue(SIZE);
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(SIZE - k, q.size());
+            assertEquals(k, l.size());
+        }
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?> q = populatedQueue(SIZE);
+        assertFalse(q.contains(null));
+        assertFalse(q.remove(null));
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/DoubleAccumulatorTest.java b/ojluni/src/test/java/util/concurrent/tck/DoubleAccumulatorTest.java
new file mode 100644
index 0000000..ef42b44
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/DoubleAccumulatorTest.java
@@ -0,0 +1,184 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.DoubleAccumulator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class DoubleAccumulatorTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(DoubleAccumulatorTest.class);
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * accumulate accumulates given value to current, and get returns current value
+     */
+    public void testAccumulateAndGet() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        ai.accumulate(-4.0);
+        assertEquals(2.0, ai.get());
+        ai.accumulate(4.0);
+        assertEquals(4.0, ai.get());
+    }
+
+    /**
+     * reset() causes subsequent get() to return zero
+     */
+    public void testReset() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        ai.reset();
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * getThenReset() returns current value; subsequent get() returns zero
+     */
+    public void testGetThenReset() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        ai.accumulate(2.0);
+        assertEquals(2.0, ai.get());
+        assertEquals(2.0, ai.getThenReset());
+        assertEquals(0.0, ai.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals("0.0", ai.toString());
+        ai.accumulate(1.0);
+        assertEquals(Double.toString(1.0), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0, ai.intValue());
+        ai.accumulate(1.0);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0, ai.longValue());
+        ai.accumulate(1.0);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0f, ai.floatValue());
+        ai.accumulate(1.0);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
+        assertEquals(0.0, ai.doubleValue());
+        ai.accumulate(1.0);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * accumulates by multiple threads produce correct result
+     */
+    public void testAccumulateAndGetMT() {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0);
+        Phaser phaser = new Phaser(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AccTask(a, phaser, incs));
+        phaser.arriveAndAwaitAdvance();
+        phaser.arriveAndAwaitAdvance();
+        double expected = incs - 1;
+        double result = a.get();
+        assertEquals(expected, result);
+        pool.shutdown();
+    }
+
+    static final class AccTask implements Runnable {
+        final DoubleAccumulator acc;
+        final Phaser phaser;
+        final int incs;
+        volatile double result;
+        AccTask(DoubleAccumulator acc, Phaser phaser, int incs) {
+            this.acc = acc;
+            this.phaser = phaser;
+            this.incs = incs;
+        }
+
+        public void run() {
+            phaser.arriveAndAwaitAdvance();
+            DoubleAccumulator a = acc;
+            for (int i = 0; i < incs; ++i)
+                a.accumulate(i);
+            result = a.get();
+            phaser.arrive();
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/DoubleAdderTest.java b/ojluni/src/test/java/util/concurrent/tck/DoubleAdderTest.java
new file mode 100644
index 0000000..dd89b56
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/DoubleAdderTest.java
@@ -0,0 +1,198 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.DoubleAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class DoubleAdderTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(DoubleAdderTest.class);
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * add adds given value to current, and sum returns current value
+     */
+    public void testAddAndSum() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        ai.add(-4.0);
+        assertEquals(-2.0, ai.sum());
+    }
+
+    /**
+     * reset() causes subsequent sum() to return zero
+     */
+    public void testReset() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        ai.reset();
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * sumThenReset() returns sum; subsequent sum() returns zero
+     */
+    public void testSumThenReset() {
+        DoubleAdder ai = new DoubleAdder();
+        ai.add(2.0);
+        assertEquals(2.0, ai.sum());
+        assertEquals(2.0, ai.sumThenReset());
+        assertEquals(0.0, ai.sum());
+    }
+
+    /**
+     * a deserialized serialized adder holds same value
+     */
+    public void testSerialization() throws Exception {
+        DoubleAdder x = new DoubleAdder();
+        DoubleAdder y = serialClone(x);
+        assertNotSame(x, y);
+        x.add(-22.0);
+        DoubleAdder z = serialClone(x);
+        assertEquals(-22.0, x.sum());
+        assertEquals(0.0, y.sum());
+        assertEquals(-22.0, z.sum());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(Double.toString(0.0), ai.toString());
+        ai.add(1.0);
+        assertEquals(Double.toString(1.0), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0, ai.intValue());
+        ai.add(1.0);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0, ai.longValue());
+        ai.add(1.0);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0f, ai.floatValue());
+        ai.add(1.0);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        DoubleAdder ai = new DoubleAdder();
+        assertEquals(0.0, ai.doubleValue());
+        ai.add(1.0);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * adds by multiple threads produce correct sum
+     */
+    public void testAddAndSumMT() throws Throwable {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        DoubleAdder a = new DoubleAdder();
+        CyclicBarrier barrier = new CyclicBarrier(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AdderTask(a, barrier, incs));
+        barrier.await();
+        barrier.await();
+        double total = (long)nthreads * incs;
+        double sum = a.sum();
+        assertEquals(sum, total);
+        pool.shutdown();
+    }
+
+    static final class AdderTask implements Runnable {
+        final DoubleAdder adder;
+        final CyclicBarrier barrier;
+        final int incs;
+        volatile double result;
+        AdderTask(DoubleAdder adder, CyclicBarrier barrier, int incs) {
+            this.adder = adder;
+            this.barrier = barrier;
+            this.incs = incs;
+        }
+
+        public void run() {
+            try {
+                barrier.await();
+                DoubleAdder a = adder;
+                for (int i = 0; i < incs; ++i)
+                    a.add(1.0);
+                result = a.sum();
+                barrier.await();
+            } catch (Throwable t) { throw new Error(t); }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/EntryTest.java b/ojluni/src/test/java/util/concurrent/tck/EntryTest.java
new file mode 100644
index 0000000..c98541d
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/EntryTest.java
@@ -0,0 +1,158 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.AbstractMap;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class EntryTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(EntryTest.class);
+    }
+
+    static final String k1 = "1";
+    static final String v1 = "a";
+    static final String k2 = "2";
+    static final String v2 = "b";
+
+    /**
+     * A new SimpleEntry(k, v) holds k, v.
+     */
+    public void testConstructor1() {
+        Map.Entry e = new AbstractMap.SimpleEntry(k1, v1);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+    }
+
+    /**
+     * A new SimpleImmutableEntry(k, v) holds k, v.
+     */
+    public void testConstructor2() {
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+    }
+
+    /**
+     * A new SimpleEntry(entry(k, v)) holds k, v.
+     */
+    public void testConstructor3() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+    }
+
+    /**
+     * A new SimpleImmutableEntry(entry(k, v)) holds k, v.
+     */
+    public void testConstructor4() {
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+    }
+
+    /**
+     * Entries with same key-value pairs are equal and have same
+     * hashcodes
+     */
+    public void testEquals() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(e2, e);
+        assertEquals(e2.hashCode(), e.hashCode());
+        assertEquals(s2, s);
+        assertEquals(s2.hashCode(), s.hashCode());
+        assertEquals(e2, s2);
+        assertEquals(e2.hashCode(), s2.hashCode());
+        assertEquals(e, s);
+        assertEquals(e.hashCode(), s.hashCode());
+    }
+
+    /**
+     * Entries with different key-value pairs are not equal
+     */
+    public void testNotEquals() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(k2, v1);
+        assertFalse(e2.equals(e));
+        e = new AbstractMap.SimpleEntry(k1, v2);
+        assertFalse(e2.equals(e));
+        e = new AbstractMap.SimpleEntry(k2, v2);
+        assertFalse(e2.equals(e));
+
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(k2, v1);
+        assertFalse(s2.equals(s));
+        s = new AbstractMap.SimpleImmutableEntry(k1, v2);
+        assertFalse(s2.equals(s));
+        s = new AbstractMap.SimpleImmutableEntry(k2, v2);
+        assertFalse(s2.equals(s));
+    }
+
+    /**
+     * getValue returns last setValue for SimpleEntry
+     */
+    public void testSetValue1() {
+        Map.Entry e2 = new AbstractMap.SimpleEntry(k1, v1);
+        Map.Entry e = new AbstractMap.SimpleEntry(e2);
+        assertEquals(k1, e.getKey());
+        assertEquals(v1, e.getValue());
+        e.setValue(k2);
+        assertEquals(k2, e.getValue());
+        assertFalse(e2.equals(e));
+    }
+
+    /**
+     * setValue for SimpleImmutableEntry throws UnsupportedOperationException
+     */
+    public void testSetValue2() {
+        Map.Entry s2 = new AbstractMap.SimpleImmutableEntry(k1, v1);
+        Map.Entry s = new AbstractMap.SimpleImmutableEntry(s2);
+        assertEquals(k1, s.getKey());
+        assertEquals(v1, s.getValue());
+        try {
+            s.setValue(k2);
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ExchangerTest.java b/ojluni/src/test/java/util/concurrent/tck/ExchangerTest.java
new file mode 100644
index 0000000..95acafb
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ExchangerTest.java
@@ -0,0 +1,181 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Exchanger;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ExchangerTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ExchangerTest.class);
+    }
+
+    /**
+     * exchange exchanges objects across two threads
+     */
+    public void testExchange() {
+        final Exchanger e = new Exchanger();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(one, e.exchange(two));
+                assertSame(two, e.exchange(one));
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(two, e.exchange(one));
+                assertSame(one, e.exchange(two));
+            }});
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * timed exchange exchanges objects across two threads
+     */
+    public void testTimedExchange() {
+        final Exchanger e = new Exchanger();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
+                assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                assertSame(two, e.exchange(one, LONG_DELAY_MS, MILLISECONDS));
+                assertSame(one, e.exchange(two, LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * interrupt during wait for exchange throws IE
+     */
+    public void testExchange_InterruptedException() {
+        final Exchanger e = new Exchanger();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadStarted.countDown();
+                e.exchange(one);
+            }});
+
+        await(threadStarted);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * interrupt during wait for timed exchange throws IE
+     */
+    public void testTimedExchange_InterruptedException() {
+        final Exchanger e = new Exchanger();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws Exception {
+                threadStarted.countDown();
+                e.exchange(null, LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        await(threadStarted);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timeout during wait for timed exchange throws TimeoutException
+     */
+    public void testExchange_TimeoutException() {
+        final Exchanger e = new Exchanger();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                long startTime = System.nanoTime();
+                try {
+                    e.exchange(null, timeoutMillis(), MILLISECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {}
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * If one exchanging thread is interrupted, another succeeds.
+     */
+    public void testReplacementAfterExchange() {
+        final Exchanger e = new Exchanger();
+        final CountDownLatch exchanged = new CountDownLatch(2);
+        final CountDownLatch interrupted = new CountDownLatch(1);
+        Thread t1 = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(two, e.exchange(one));
+                exchanged.countDown();
+                e.exchange(two);
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertSame(one, e.exchange(two));
+                exchanged.countDown();
+                interrupted.await();
+                assertSame(three, e.exchange(one));
+            }});
+        Thread t3 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                interrupted.await();
+                assertSame(one, e.exchange(three));
+            }});
+
+        await(exchanged);
+        t1.interrupt();
+        awaitTermination(t1);
+        interrupted.countDown();
+        awaitTermination(t2);
+        awaitTermination(t3);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java b/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java
new file mode 100644
index 0000000..1af24cf
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionService9Test.java
@@ -0,0 +1,141 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.Future;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ExecutorCompletionService9Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ExecutorCompletionService9Test.class);
+    }
+
+    void solveAll(Executor e,
+                  Collection<Callable<Integer>> solvers)
+        throws InterruptedException, ExecutionException {
+        CompletionService<Integer> cs
+            = new ExecutorCompletionService<>(e);
+        solvers.forEach(cs::submit);
+        for (int i = solvers.size(); i > 0; i--) {
+            Integer r = cs.take().get();
+            if (r != null)
+                use(r);
+        }
+    }
+
+    void solveAny(Executor e,
+                  Collection<Callable<Integer>> solvers)
+        throws InterruptedException {
+        CompletionService<Integer> cs
+            = new ExecutorCompletionService<>(e);
+        int n = solvers.size();
+        List<Future<Integer>> futures = new ArrayList<>(n);
+        Integer result = null;
+        try {
+            solvers.forEach(solver -> futures.add(cs.submit(solver)));
+            for (int i = n; i > 0; i--) {
+                try {
+                    Integer r = cs.take().get();
+                    if (r != null) {
+                        result = r;
+                        break;
+                    }
+                } catch (ExecutionException ignore) {}
+            }
+        } finally {
+            futures.forEach(future -> future.cancel(true));
+        }
+
+        if (result != null)
+            use(result);
+    }
+
+    ArrayList<Integer> results;
+
+    void use(Integer x) {
+        if (results == null) results = new ArrayList<Integer>();
+        results.add(x);
+    }
+
+    /**
+     * The first "solvers" sample code in the class javadoc works.
+     */
+    public void testSolveAll()
+        throws InterruptedException, ExecutionException {
+        results = null;
+        Set<Callable<Integer>> solvers = Set.of(
+            () -> null,
+            () -> 1,
+            () -> 2,
+            () -> 3,
+            () -> null);
+        solveAll(cachedThreadPool, solvers);
+        results.sort(Comparator.naturalOrder());
+        assertEquals(List.of(1, 2, 3), results);
+    }
+
+    /**
+     * The second "solvers" sample code in the class javadoc works.
+     */
+    public void testSolveAny()
+        throws InterruptedException {
+        results = null;
+        Set<Callable<Integer>> solvers = Set.of(
+            () -> { throw new ArithmeticException(); },
+            () -> null,
+            () -> 1,
+            () -> 2);
+        solveAny(cachedThreadPool, solvers);
+        assertEquals(1, results.size());
+        Integer elt = results.get(0);
+        assertTrue(elt.equals(1) || elt.equals(2));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java b/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java
new file mode 100644
index 0000000..877031e
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ExecutorCompletionServiceTest.java
@@ -0,0 +1,278 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletionService;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorCompletionService;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ExecutorCompletionServiceTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ExecutorCompletionServiceTest.class);
+    }
+
+    /**
+     * new ExecutorCompletionService(null) throws NullPointerException
+     */
+    public void testConstructorNPE() {
+        try {
+            new ExecutorCompletionService(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * new ExecutorCompletionService(e, null) throws NullPointerException
+     */
+    public void testConstructorNPE2() {
+        try {
+            new ExecutorCompletionService(cachedThreadPool, null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * ecs.submit(null) throws NullPointerException
+     */
+    public void testSubmitNullCallable() {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        try {
+            cs.submit((Callable) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * ecs.submit(null, val) throws NullPointerException
+     */
+    public void testSubmitNullRunnable() {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        try {
+            cs.submit((Runnable) null, Boolean.TRUE);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A taken submitted task is completed
+     */
+    public void testTake()
+        throws InterruptedException, ExecutionException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        cs.submit(new StringTask());
+        Future f = cs.take();
+        assertTrue(f.isDone());
+        assertSame(TEST_STRING, f.get());
+    }
+
+    /**
+     * Take returns the same future object returned by submit
+     */
+    public void testTake2() throws InterruptedException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        Future f1 = cs.submit(new StringTask());
+        Future f2 = cs.take();
+        assertSame(f1, f2);
+    }
+
+    /**
+     * poll returns non-null when the returned task is completed
+     */
+    public void testPoll1()
+        throws InterruptedException, ExecutionException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        assertNull(cs.poll());
+        cs.submit(new StringTask());
+
+        long startTime = System.nanoTime();
+        Future f;
+        while ((f = cs.poll()) == null) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                fail("timed out");
+            Thread.yield();
+        }
+        assertTrue(f.isDone());
+        assertSame(TEST_STRING, f.get());
+    }
+
+    /**
+     * timed poll returns non-null when the returned task is completed
+     */
+    public void testPoll2()
+        throws InterruptedException, ExecutionException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        assertNull(cs.poll());
+        cs.submit(new StringTask());
+
+        long startTime = System.nanoTime();
+        Future f;
+        while ((f = cs.poll(SHORT_DELAY_MS, MILLISECONDS)) == null) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                fail("timed out");
+            Thread.yield();
+        }
+        assertTrue(f.isDone());
+        assertSame(TEST_STRING, f.get());
+    }
+
+    /**
+     * poll returns null before the returned task is completed
+     */
+    public void testPollReturnsNull()
+        throws InterruptedException, ExecutionException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        final CountDownLatch proceed = new CountDownLatch(1);
+        cs.submit(new Callable() { public String call() throws Exception {
+            proceed.await();
+            return TEST_STRING;
+        }});
+        assertNull(cs.poll());
+        assertNull(cs.poll(0L, MILLISECONDS));
+        assertNull(cs.poll(Long.MIN_VALUE, MILLISECONDS));
+        long startTime = System.nanoTime();
+        assertNull(cs.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        proceed.countDown();
+        assertSame(TEST_STRING, cs.take().get());
+    }
+
+    /**
+     * successful and failed tasks are both returned
+     */
+    public void testTaskAssortment()
+        throws InterruptedException, ExecutionException {
+        CompletionService cs = new ExecutorCompletionService(cachedThreadPool);
+        ArithmeticException ex = new ArithmeticException();
+        for (int i = 0; i < 2; i++) {
+            cs.submit(new StringTask());
+            cs.submit(callableThrowing(ex));
+            cs.submit(runnableThrowing(ex), null);
+        }
+        int normalCompletions = 0;
+        int exceptionalCompletions = 0;
+        for (int i = 0; i < 3 * 2; i++) {
+            try {
+                if (cs.take().get() == TEST_STRING)
+                    normalCompletions++;
+            }
+            catch (ExecutionException expected) {
+                assertTrue(expected.getCause() instanceof ArithmeticException);
+                exceptionalCompletions++;
+            }
+        }
+        assertEquals(2 * 1, normalCompletions);
+        assertEquals(2 * 2, exceptionalCompletions);
+        assertNull(cs.poll());
+    }
+
+    /**
+     * Submitting to underlying AES that overrides newTaskFor(Callable)
+     * returns and eventually runs Future returned by newTaskFor.
+     */
+    public void testNewTaskForCallable() throws InterruptedException {
+        final AtomicBoolean done = new AtomicBoolean(false);
+        class MyCallableFuture<V> extends FutureTask<V> {
+            MyCallableFuture(Callable<V> c) { super(c); }
+            @Override protected void done() { done.set(true); }
+        }
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   30L, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1)) {
+                protected <T> RunnableFuture<T> newTaskFor(Callable<T> c) {
+                    return new MyCallableFuture<T>(c);
+                }};
+        CompletionService<String> cs = new ExecutorCompletionService<>(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            assertNull(cs.poll());
+            Callable<String> c = new StringTask();
+            Future f1 = cs.submit(c);
+            assertTrue("submit must return MyCallableFuture",
+                       f1 instanceof MyCallableFuture);
+            Future f2 = cs.take();
+            assertSame("submit and take must return same objects", f1, f2);
+            assertTrue("completed task must have set done", done.get());
+        }
+    }
+
+    /**
+     * Submitting to underlying AES that overrides newTaskFor(Runnable,T)
+     * returns and eventually runs Future returned by newTaskFor.
+     */
+    public void testNewTaskForRunnable() throws InterruptedException {
+        final AtomicBoolean done = new AtomicBoolean(false);
+        class MyRunnableFuture<V> extends FutureTask<V> {
+            MyRunnableFuture(Runnable t, V r) { super(t, r); }
+            @Override protected void done() { done.set(true); }
+        }
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   30L, TimeUnit.SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1)) {
+                protected <T> RunnableFuture<T> newTaskFor(Runnable t, T r) {
+                    return new MyRunnableFuture<T>(t, r);
+                }};
+        CompletionService<String> cs = new ExecutorCompletionService<>(e);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            assertNull(cs.poll());
+            Runnable r = new NoOpRunnable();
+            Future f1 = cs.submit(r, null);
+            assertTrue("submit must return MyRunnableFuture",
+                       f1 instanceof MyRunnableFuture);
+            Future f2 = cs.take();
+            assertSame("submit and take must return same objects", f1, f2);
+            assertTrue("completed task must have set done", done.get());
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ExecutorsTest.java b/ojluni/src/test/java/util/concurrent/tck/ExecutorsTest.java
new file mode 100644
index 0000000..fd4b7e4
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ExecutorsTest.java
@@ -0,0 +1,625 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadPoolExecutor;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ExecutorsTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ExecutorsTest.class);
+    }
+
+    /**
+     * A newCachedThreadPool can execute runnables
+     */
+    public void testNewCachedThreadPool1() {
+        final ExecutorService e = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A newCachedThreadPool with given ThreadFactory can execute runnables
+     */
+    public void testNewCachedThreadPool2() {
+        final ExecutorService e = Executors.newCachedThreadPool(new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A newCachedThreadPool with null ThreadFactory throws NPE
+     */
+    public void testNewCachedThreadPool3() {
+        try {
+            ExecutorService e = Executors.newCachedThreadPool(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A new SingleThreadExecutor can execute runnables
+     */
+    public void testNewSingleThreadExecutor1() {
+        final ExecutorService e = Executors.newSingleThreadExecutor();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A new SingleThreadExecutor with given ThreadFactory can execute runnables
+     */
+    public void testNewSingleThreadExecutor2() {
+        final ExecutorService e = Executors.newSingleThreadExecutor(new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A new SingleThreadExecutor with null ThreadFactory throws NPE
+     */
+    public void testNewSingleThreadExecutor3() {
+        try {
+            ExecutorService e = Executors.newSingleThreadExecutor(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A new SingleThreadExecutor cannot be casted to concrete implementation
+     */
+    public void testCastNewSingleThreadExecutor() {
+        final ExecutorService e = Executors.newSingleThreadExecutor();
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                ThreadPoolExecutor tpe = (ThreadPoolExecutor)e;
+                shouldThrow();
+            } catch (ClassCastException success) {}
+        }
+    }
+
+    /**
+     * A new newFixedThreadPool can execute runnables
+     */
+    public void testNewFixedThreadPool1() {
+        final ExecutorService e = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A new newFixedThreadPool with given ThreadFactory can execute runnables
+     */
+    public void testNewFixedThreadPool2() {
+        final ExecutorService e = Executors.newFixedThreadPool(2, new SimpleThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * A new newFixedThreadPool with null ThreadFactory throws NPE
+     */
+    public void testNewFixedThreadPool3() {
+        try {
+            ExecutorService e = Executors.newFixedThreadPool(2, null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A new newFixedThreadPool with 0 threads throws IAE
+     */
+    public void testNewFixedThreadPool4() {
+        try {
+            ExecutorService e = Executors.newFixedThreadPool(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * An unconfigurable newFixedThreadPool can execute runnables
+     */
+    public void testUnconfigurableExecutorService() {
+        final ExecutorService e = Executors.unconfigurableExecutorService(Executors.newFixedThreadPool(2));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+            e.execute(new NoOpRunnable());
+        }
+    }
+
+    /**
+     * unconfigurableExecutorService(null) throws NPE
+     */
+    public void testUnconfigurableExecutorServiceNPE() {
+        try {
+            ExecutorService e = Executors.unconfigurableExecutorService(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * unconfigurableScheduledExecutorService(null) throws NPE
+     */
+    public void testUnconfigurableScheduledExecutorServiceNPE() {
+        try {
+            ExecutorService e = Executors.unconfigurableScheduledExecutorService(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * a newSingleThreadScheduledExecutor successfully runs delayed task
+     */
+    public void testNewSingleThreadScheduledExecutor() throws Exception {
+        final ScheduledExecutorService p = Executors.newSingleThreadScheduledExecutor();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch proceed = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    await(proceed);
+                }};
+            long startTime = System.nanoTime();
+            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+                                  timeoutMillis(), MILLISECONDS);
+            assertFalse(f.isDone());
+            proceed.countDown();
+            assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+            assertSame(Boolean.TRUE, f.get());
+            assertTrue(f.isDone());
+            assertFalse(f.isCancelled());
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * a newScheduledThreadPool successfully runs delayed task
+     */
+    public void testNewScheduledThreadPool() throws Exception {
+        final ScheduledExecutorService p = Executors.newScheduledThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch proceed = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    await(proceed);
+                }};
+            long startTime = System.nanoTime();
+            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+                                  timeoutMillis(), MILLISECONDS);
+            assertFalse(f.isDone());
+            proceed.countDown();
+            assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+            assertSame(Boolean.TRUE, f.get());
+            assertTrue(f.isDone());
+            assertFalse(f.isCancelled());
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * an unconfigurable newScheduledThreadPool successfully runs delayed task
+     */
+    public void testUnconfigurableScheduledExecutorService() throws Exception {
+        final ScheduledExecutorService p =
+            Executors.unconfigurableScheduledExecutorService
+            (Executors.newScheduledThreadPool(2));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch proceed = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    await(proceed);
+                }};
+            long startTime = System.nanoTime();
+            Future f = p.schedule(Executors.callable(task, Boolean.TRUE),
+                                  timeoutMillis(), MILLISECONDS);
+            assertFalse(f.isDone());
+            proceed.countDown();
+            assertSame(Boolean.TRUE, f.get(LONG_DELAY_MS, MILLISECONDS));
+            assertSame(Boolean.TRUE, f.get());
+            assertTrue(f.isDone());
+            assertFalse(f.isCancelled());
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * Future.get on submitted tasks will time out if they compute too long.
+     */
+    public void testTimedCallable() throws Exception {
+        final ExecutorService[] executors = {
+            Executors.newSingleThreadExecutor(),
+            Executors.newCachedThreadPool(),
+            Executors.newFixedThreadPool(2),
+            Executors.newScheduledThreadPool(2),
+        };
+
+        final Runnable sleeper = new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                delay(LONG_DELAY_MS);
+            }};
+
+        List<Thread> threads = new ArrayList<>();
+        for (final ExecutorService executor : executors) {
+            threads.add(newStartedThread(new CheckedRunnable() {
+                public void realRun() {
+                    Future future = executor.submit(sleeper);
+                    assertFutureTimesOut(future);
+                }}));
+        }
+        for (Thread thread : threads)
+            awaitTermination(thread);
+        for (ExecutorService executor : executors)
+            joinPool(executor);
+    }
+
+    /**
+     * ThreadPoolExecutor using defaultThreadFactory has
+     * specified group, priority, daemon status, and name
+     */
+    public void testDefaultThreadFactory() throws Exception {
+        final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
+        final CountDownLatch done = new CountDownLatch(1);
+        Runnable r = new CheckedRunnable() {
+            public void realRun() {
+                try {
+                    Thread current = Thread.currentThread();
+                    assertTrue(!current.isDaemon());
+                    assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+                    ThreadGroup g = current.getThreadGroup();
+                    SecurityManager s = System.getSecurityManager();
+                    if (s != null)
+                        assertTrue(g == s.getThreadGroup());
+                    else
+                        assertTrue(g == egroup);
+                    String name = current.getName();
+                    assertTrue(name.endsWith("thread-1"));
+                } catch (SecurityException ok) {
+                    // Also pass if not allowed to change setting
+                }
+                done.countDown();
+            }};
+        ExecutorService e = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            e.execute(r);
+            await(done);
+        }
+    }
+
+    /**
+     * ThreadPoolExecutor using privilegedThreadFactory has
+     * specified group, priority, daemon status, name,
+     * access control context and context class loader
+     */
+    public void testPrivilegedThreadFactory() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                final ThreadGroup egroup = Thread.currentThread().getThreadGroup();
+                final ClassLoader thisccl = Thread.currentThread().getContextClassLoader();
+                final AccessControlContext thisacc = AccessController.getContext();
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() {
+                        Thread current = Thread.currentThread();
+                        assertTrue(!current.isDaemon());
+                        assertTrue(current.getPriority() <= Thread.NORM_PRIORITY);
+                        ThreadGroup g = current.getThreadGroup();
+                        SecurityManager s = System.getSecurityManager();
+                        if (s != null)
+                            assertTrue(g == s.getThreadGroup());
+                        else
+                            assertTrue(g == egroup);
+                        String name = current.getName();
+                        assertTrue(name.endsWith("thread-1"));
+                        assertSame(thisccl, current.getContextClassLoader());
+                        // Android-removed: Android doesn't support real AccessControlContext.
+                        // assertEquals(thisacc, AccessController.getCossntext());
+                        done.countDown();
+                    }};
+                ExecutorService e = Executors.newSingleThreadExecutor(Executors.privilegedThreadFactory());
+                try (PoolCleaner cleaner = cleaner(e)) {
+                    e.execute(r);
+                    await(done);
+                }
+            }};
+
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"),
+                           new RuntimePermission("modifyThread"));
+    }
+
+    boolean haveCCLPermissions() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+                sm.checkPermission(new RuntimePermission("getClassLoader"));
+            } catch (AccessControlException e) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    void checkCCL() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
+            sm.checkPermission(new RuntimePermission("getClassLoader"));
+        }
+    }
+
+    class CheckCCL implements Callable<Object> {
+        public Object call() {
+            checkCCL();
+            return null;
+        }
+    }
+
+    /**
+     * Without class loader permissions, creating
+     * privilegedCallableUsingCurrentClassLoader throws ACE
+     */
+    public void testCreatePrivilegedCallableUsingCCLWithNoPrivs() {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                if (System.getSecurityManager() == null)
+                    return;
+                try {
+                    Executors.privilegedCallableUsingCurrentClassLoader(new NoOpCallable());
+                    shouldThrow();
+                } catch (AccessControlException success) {}
+            }};
+
+        runWithoutPermissions(r);
+    }
+
+    /**
+     * With class loader permissions, calling
+     * privilegedCallableUsingCurrentClassLoader does not throw ACE
+     */
+    public void testPrivilegedCallableUsingCCLWithPrivs() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Executors.privilegedCallableUsingCurrentClassLoader
+                    (new NoOpCallable())
+                    .call();
+            }};
+
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"));
+    }
+
+    /**
+     * Without permissions, calling privilegedCallable throws ACE
+     */
+    public void testPrivilegedCallableWithNoPrivs() throws Exception {
+        // Avoid classloader-related SecurityExceptions in swingui.TestRunner
+        Executors.privilegedCallable(new CheckCCL());
+
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                if (System.getSecurityManager() == null)
+                    return;
+                Callable task = Executors.privilegedCallable(new CheckCCL());
+                try {
+                    task.call();
+                    shouldThrow();
+                } catch (AccessControlException success) {}
+            }};
+
+        runWithoutPermissions(r);
+
+        // It seems rather difficult to test that the
+        // AccessControlContext of the privilegedCallable is used
+        // instead of its caller.  Below is a failed attempt to do
+        // that, which does not work because the AccessController
+        // cannot capture the internal state of the current Policy.
+        // It would be much more work to differentiate based on,
+        // e.g. CodeSource.
+
+//         final AccessControlContext[] noprivAcc = new AccessControlContext[1];
+//         final Callable[] task = new Callable[1];
+
+//         runWithPermissions
+//             (new CheckedRunnable() {
+//                 public void realRun() {
+//                     if (System.getSecurityManager() == null)
+//                         return;
+//                     noprivAcc[0] = AccessController.getContext();
+//                     task[0] = Executors.privilegedCallable(new CheckCCL());
+//                     try {
+//                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+//                                                           public Void run() {
+//                                                               checkCCL();
+//                                                               return null;
+//                                                           }}, noprivAcc[0]);
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+//                 }});
+
+//         runWithPermissions
+//             (new CheckedRunnable() {
+//                 public void realRun() throws Exception {
+//                     if (System.getSecurityManager() == null)
+//                         return;
+//                     // Verify that we have an underprivileged ACC
+//                     try {
+//                         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+//                                                           public Void run() {
+//                                                               checkCCL();
+//                                                               return null;
+//                                                           }}, noprivAcc[0]);
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+
+//                     try {
+//                         task[0].call();
+//                         shouldThrow();
+//                     } catch (AccessControlException success) {}
+//                 }},
+//              new RuntimePermission("getClassLoader"),
+//              new RuntimePermission("setContextClassLoader"));
+    }
+
+    /**
+     * With permissions, calling privilegedCallable succeeds
+     */
+    public void testPrivilegedCallableWithPrivs() throws Exception {
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Executors.privilegedCallable(new CheckCCL()).call();
+            }};
+
+        runWithPermissions(r,
+                           new RuntimePermission("getClassLoader"),
+                           new RuntimePermission("setContextClassLoader"));
+    }
+
+    /**
+     * callable(Runnable) returns null when called
+     */
+    public void testCallable1() throws Exception {
+        Callable c = Executors.callable(new NoOpRunnable());
+        assertNull(c.call());
+    }
+
+    /**
+     * callable(Runnable, result) returns result when called
+     */
+    public void testCallable2() throws Exception {
+        Callable c = Executors.callable(new NoOpRunnable(), one);
+        assertSame(one, c.call());
+    }
+
+    /**
+     * callable(PrivilegedAction) returns its result when called
+     */
+    public void testCallable3() throws Exception {
+        Callable c = Executors.callable(new PrivilegedAction() {
+                public Object run() { return one; }});
+        assertSame(one, c.call());
+    }
+
+    /**
+     * callable(PrivilegedExceptionAction) returns its result when called
+     */
+    public void testCallable4() throws Exception {
+        Callable c = Executors.callable(new PrivilegedExceptionAction() {
+                public Object run() { return one; }});
+        assertSame(one, c.call());
+    }
+
+    /**
+     * callable(null Runnable) throws NPE
+     */
+    public void testCallableNPE1() {
+        try {
+            Callable c = Executors.callable((Runnable) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * callable(null, result) throws NPE
+     */
+    public void testCallableNPE2() {
+        try {
+            Callable c = Executors.callable((Runnable) null, one);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * callable(null PrivilegedAction) throws NPE
+     */
+    public void testCallableNPE3() {
+        try {
+            Callable c = Executors.callable((PrivilegedAction) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * callable(null PrivilegedExceptionAction) throws NPE
+     */
+    public void testCallableNPE4() {
+        try {
+            Callable c = Executors.callable((PrivilegedExceptionAction) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ForkJoinPool8Test.java b/ojluni/src/test/java/util/concurrent/tck/ForkJoinPool8Test.java
new file mode 100644
index 0000000..a39fc71
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ForkJoinPool8Test.java
@@ -0,0 +1,1610 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountedCompleter;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinPool8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ForkJoinPool8Test.class);
+    }
+
+    /**
+     * Common pool exists and has expected parallelism.
+     */
+    public void testCommonPoolParallelism() {
+        assertEquals(ForkJoinPool.getCommonPoolParallelism(),
+                     ForkJoinPool.commonPool().getParallelism());
+    }
+
+    /**
+     * Common pool cannot be shut down
+     */
+    public void testCommonPoolShutDown() {
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+        ForkJoinPool.commonPool().shutdown();
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+        ForkJoinPool.commonPool().shutdownNow();
+        assertFalse(ForkJoinPool.commonPool().isShutdown());
+        assertFalse(ForkJoinPool.commonPool().isTerminating());
+        assertFalse(ForkJoinPool.commonPool().isTerminated());
+    }
+
+    /*
+     * All of the following test methods are adaptations of those for
+     * RecursiveAction and CountedCompleter, but with all actions
+     * executed in the common pool, generally implicitly via
+     * checkInvoke.
+     */
+
+    private void checkInvoke(ForkJoinTask a) {
+        checkNotDone(a);
+        assertNull(a.invoke());
+        checkCompletedNormally(a);
+    }
+
+    void checkNotDone(ForkJoinTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        if (! ForkJoinTask.inForkJoinPool()) {
+            Thread.currentThread().interrupt();
+            try {
+                a.get();
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+            Thread.currentThread().interrupt();
+            try {
+                a.get(5L, SECONDS);
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+        }
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedNormally(ForkJoinTask a) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+        assertNull(a.join());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertNull(a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertNull(a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(ForkJoinTask a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(expected.getClass(), t.getClass());
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        public FJException() { super(); }
+        public FJException(Throwable cause) { super(cause); }
+    }
+
+    // A simple recursive action for testing
+    final class FibAction extends CheckedRecursiveAction {
+        final int number;
+        int result;
+        FibAction(int n) { number = n; }
+        protected void realCompute() {
+            int n = number;
+            if (n <= 1)
+                result = n;
+            else {
+                FibAction f1 = new FibAction(n - 1);
+                FibAction f2 = new FibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    // A recursive action failing in base case
+    static final class FailingFibAction extends RecursiveAction {
+        final int number;
+        int result;
+        FailingFibAction(int n) { number = n; }
+        public void compute() {
+            int n = number;
+            if (n <= 1)
+                throw new FJException();
+            else {
+                FailingFibAction f1 = new FailingFibAction(n - 1);
+                FailingFibAction f2 = new FailingFibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks. getRawResult of a RecursiveAction returns null;
+     */
+    public void testInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
+     */
+    public void testJoinIgnoresInterrupts() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                final Thread currentThread = Thread.currentThread();
+
+                // test join()
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                assertNull(f.join());
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    Thread.interrupted();
+                    checkCancelled(f);
+                }
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    Thread.interrupted();
+                    checkCompletedAbnormally(f, success);
+                }
+
+                // test quietlyJoin()
+                f = new FibAction(8);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCancelled(f);
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+        a.reinitialize();
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(5L, SECONDS));
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * A reinitialized normally completed task may be re-invoked
+     */
+    public void testReinitialize() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    assertNull(f.invoke());
+                    assertEquals(21, f.result);
+                    checkCompletedNormally(f);
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * A reinitialized abnormally completed task may be re-invoked
+     */
+    public void testReinitializeAbnormal() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    try {
+                        f.invoke();
+                        shouldThrow();
+                    } catch (FJException success) {
+                        checkCompletedAbnormally(f, success);
+                    }
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task suppresses execution invoking complete
+     */
+    public void testComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.complete(null);
+                assertNull(f.invoke());
+                assertEquals(0, f.result);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                invokeAll(f, g);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                invokeAll(f, g, h);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                FibAction h = new FibAction(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    // CountedCompleter versions
+
+    abstract static class CCF extends CountedCompleter {
+        int number;
+        int rnumber;
+
+        public CCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        public final void compute() {
+            CountedCompleter p;
+            CCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RCCF(f, n - 2).fork();
+                f = new LCCF(f, --n);
+            }
+            f.number = n;
+            f.onCompletion(f);
+            if ((p = f.getCompleter()) != null)
+                p.tryComplete();
+            else
+                f.quietlyComplete();
+        }
+    }
+
+    static final class LCCF extends CCF {
+        public LCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    static final class RCCF extends CCF {
+        public RCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            CCF p = (CCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.rnumber = n;
+            else
+                number = n;
+        }
+    }
+
+    // Version of CCF with forced failure in left completions
+    abstract static class FailingCCF extends CountedCompleter {
+        int number;
+        int rnumber;
+
+        public FailingCCF(CountedCompleter parent, int n) {
+            super(parent, 1);
+            this.number = n;
+        }
+
+        public final void compute() {
+            CountedCompleter p;
+            FailingCCF f = this;
+            int n = number;
+            while (n >= 2) {
+                new RFCCF(f, n - 2).fork();
+                f = new LFCCF(f, --n);
+            }
+            f.number = n;
+            f.onCompletion(f);
+            if ((p = f.getCompleter()) != null)
+                p.tryComplete();
+            else
+                f.quietlyComplete();
+        }
+    }
+
+    static final class LFCCF extends FailingCCF {
+        public LFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            FailingCCF p = (FailingCCF)getCompleter();
+            int n = number + rnumber;
+            if (p != null)
+                p.number = n;
+            else
+                number = n;
+        }
+    }
+    static final class RFCCF extends FailingCCF {
+        public RFCCF(CountedCompleter parent, int n) {
+            super(parent, n);
+        }
+        public final void onCompletion(CountedCompleter caller) {
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPECC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvokeCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGetCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGetCC() throws Exception {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoinCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResultCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollectionCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPECC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                FailingCCF g = new LFCCF(null, 9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF g = new LFCCF(null, 9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3CC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                CCF f = new LCCF(null, 8);
+                FailingCCF g = new LFCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollectionCC() {
+        ForkJoinTask a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingCCF f = new LFCCF(null, 8);
+                CCF g = new LCCF(null, 9);
+                CCF h = new LCCF(null, 7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        checkInvoke(a);
+    }
+
+    /**
+     * awaitQuiescence by a worker is equivalent in effect to
+     * ForkJoinTask.helpQuiesce()
+     */
+    public void testAwaitQuiescence1() throws Exception {
+        final ForkJoinPool p = new ForkJoinPool();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            assertTrue(p.isQuiescent());
+            ForkJoinTask a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    FibAction f = new FibAction(8);
+                    assertSame(f, f.fork());
+                    assertSame(p, ForkJoinTask.getPool());
+                    boolean quiescent = p.awaitQuiescence(LONG_DELAY_MS, MILLISECONDS);
+                    assertTrue(quiescent);
+                    assertFalse(p.isQuiescent());
+                    while (!f.isDone()) {
+                        assertFalse(p.getAsyncMode());
+                        assertFalse(p.isShutdown());
+                        assertFalse(p.isTerminating());
+                        assertFalse(p.isTerminated());
+                        Thread.yield();
+                    }
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    assertFalse(p.isQuiescent());
+                    assertEquals(0, ForkJoinTask.getQueuedTaskCount());
+                    assertEquals(21, f.result);
+                }};
+            p.execute(a);
+            while (!a.isDone() || !p.isQuiescent()) {
+                assertFalse(p.getAsyncMode());
+                assertFalse(p.isShutdown());
+                assertFalse(p.isTerminating());
+                assertFalse(p.isTerminated());
+                Thread.yield();
+            }
+            assertEquals(0, p.getQueuedTaskCount());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * awaitQuiescence returns when pool isQuiescent() or the indicated
+     * timeout elapsed
+     */
+    public void testAwaitQuiescence2() throws Exception {
+        /**
+         * """It is possible to disable or limit the use of threads in the
+         * common pool by setting the parallelism property to zero. However
+         * doing so may cause unjoined tasks to never be executed."""
+         */
+        if ("0".equals(System.getProperty(
+             "java.util.concurrent.ForkJoinPool.common.parallelism")))
+            return;
+        final ForkJoinPool p = new ForkJoinPool();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertTrue(p.isQuiescent());
+            final long startTime = System.nanoTime();
+            ForkJoinTask a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    FibAction f = new FibAction(8);
+                    assertSame(f, f.fork());
+                    while (!f.isDone()
+                           && millisElapsedSince(startTime) < LONG_DELAY_MS) {
+                        assertFalse(p.getAsyncMode());
+                        assertFalse(p.isShutdown());
+                        assertFalse(p.isTerminating());
+                        assertFalse(p.isTerminated());
+                        Thread.yield();
+                    }
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    assertEquals(0, ForkJoinTask.getQueuedTaskCount());
+                    assertEquals(21, f.result);
+                }};
+            p.execute(a);
+            assertTrue(p.awaitQuiescence(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isQuiescent());
+            assertTrue(a.isDone());
+            assertEquals(0, p.getQueuedTaskCount());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ForkJoinPoolTest.java b/ojluni/src/test/java/util/concurrent/tck/ForkJoinPoolTest.java
new file mode 100644
index 0000000..d8ad1dd
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ForkJoinPoolTest.java
@@ -0,0 +1,986 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.Future;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.ReentrantLock;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinPoolTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ForkJoinPoolTest.class);
+    }
+
+    /*
+     * Testing coverage notes:
+     *
+     * 1. shutdown and related methods are tested via super.joinPool.
+     *
+     * 2. newTaskFor and adapters are tested in submit/invoke tests
+     *
+     * 3. We cannot portably test monitoring methods such as
+     * getStealCount() since they rely ultimately on random task
+     * stealing that may cause tasks not to be stolen/propagated
+     * across threads, especially on uniprocessors.
+     *
+     * 4. There are no independently testable ForkJoinWorkerThread
+     * methods, but they are covered here and in task tests.
+     */
+
+    // Some classes to test extension and factory methods
+
+    static class MyError extends Error {}
+
+    // to test handlers
+    static class FailingFJWSubclass extends ForkJoinWorkerThread {
+        public FailingFJWSubclass(ForkJoinPool p) { super(p) ; }
+        protected void onStart() { super.onStart(); throw new MyError(); }
+    }
+
+    static class FailingThreadFactory
+            implements ForkJoinPool.ForkJoinWorkerThreadFactory {
+        final AtomicInteger calls = new AtomicInteger(0);
+        public ForkJoinWorkerThread newThread(ForkJoinPool p) {
+            if (calls.incrementAndGet() > 1) return null;
+            return new FailingFJWSubclass(p);
+        }
+    }
+
+    static class SubFJP extends ForkJoinPool { // to expose protected
+        SubFJP() { super(1); }
+        public int drainTasksTo(Collection<? super ForkJoinTask<?>> c) {
+            return super.drainTasksTo(c);
+        }
+        public ForkJoinTask<?> pollSubmission() {
+            return super.pollSubmission();
+        }
+    }
+
+    static class ManagedLocker implements ForkJoinPool.ManagedBlocker {
+        final ReentrantLock lock;
+        boolean hasLock = false;
+        ManagedLocker(ReentrantLock lock) { this.lock = lock; }
+        public boolean block() {
+            if (!hasLock)
+                lock.lock();
+            return true;
+        }
+        public boolean isReleasable() {
+            return hasLock || (hasLock = lock.tryLock());
+        }
+    }
+
+    // A simple recursive task for testing
+    static final class FibTask extends RecursiveTask<Integer> {
+        final int number;
+        FibTask(int n) { number = n; }
+        protected Integer compute() {
+            int n = number;
+            if (n <= 1)
+                return n;
+            FibTask f1 = new FibTask(n - 1);
+            f1.fork();
+            return (new FibTask(n - 2)).compute() + f1.join();
+        }
+    }
+
+    // A failing task for testing
+    static final class FailingTask extends ForkJoinTask<Void> {
+        public final Void getRawResult() { return null; }
+        protected final void setRawResult(Void mustBeNull) { }
+        protected final boolean exec() { throw new Error(); }
+        FailingTask() {}
+    }
+
+    // Fib needlessly using locking to test ManagedBlockers
+    static final class LockingFibTask extends RecursiveTask<Integer> {
+        final int number;
+        final ManagedLocker locker;
+        final ReentrantLock lock;
+        LockingFibTask(int n, ManagedLocker locker, ReentrantLock lock) {
+            number = n;
+            this.locker = locker;
+            this.lock = lock;
+        }
+        protected Integer compute() {
+            int n;
+            LockingFibTask f1 = null;
+            LockingFibTask f2 = null;
+            locker.block();
+            n = number;
+            if (n > 1) {
+                f1 = new LockingFibTask(n - 1, locker, lock);
+                f2 = new LockingFibTask(n - 2, locker, lock);
+            }
+            lock.unlock();
+            if (n <= 1)
+                return n;
+            else {
+                f1.fork();
+                return f2.compute() + f1.join();
+            }
+        }
+    }
+
+    /**
+     * Successfully constructed pool reports default factory,
+     * parallelism and async mode policies, no active threads or
+     * tasks, and quiescent running state.
+     */
+    public void testDefaultInitialState() {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                       p.getFactory());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getActiveThreadCount());
+            assertEquals(0, p.getStealCount());
+            assertEquals(0, p.getQueuedTaskCount());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+        }
+    }
+
+    /**
+     * Constructor throws if size argument is less than zero
+     */
+    public void testConstructor1() {
+        try {
+            new ForkJoinPool(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if factory argument is null
+     */
+    public void testConstructor2() {
+        try {
+            new ForkJoinPool(1, null, null, false);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getParallelism returns size set in constructor
+     */
+    public void testGetParallelism() {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getParallelism());
+        }
+    }
+
+    /**
+     * getPoolSize returns number of started workers.
+     */
+    public void testGetPoolSize() {
+        final CountDownLatch taskStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        final ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getActiveThreadCount());
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    taskStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    assertEquals(1, p.getActiveThreadCount());
+                    done.await();
+                }};
+            Future<?> future = p.submit(task);
+            await(taskStarted);
+            assertEquals(1, p.getPoolSize());
+            assertEquals(1, p.getActiveThreadCount());
+            done.countDown();
+        }
+        assertEquals(0, p.getPoolSize());
+        assertEquals(0, p.getActiveThreadCount());
+    }
+
+    /**
+     * awaitTermination on a non-shutdown pool times out
+     */
+    public void testAwaitTermination_timesOut() throws InterruptedException {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isTerminated());
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+            assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+            assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+            assertFalse(p.awaitTermination(0L, NANOSECONDS));
+            assertFalse(p.awaitTermination(0L, MILLISECONDS));
+            long timeoutNanos = 999999L;
+            long startTime = System.nanoTime();
+            assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+            assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+            assertFalse(p.isTerminated());
+            startTime = System.nanoTime();
+            long timeoutMillis = timeoutMillis();
+            assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            assertFalse(p.isTerminated());
+            p.shutdown();
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
+    }
+
+    /**
+     * setUncaughtExceptionHandler changes handler for uncaught exceptions.
+     *
+     * Additionally tests: Overriding ForkJoinWorkerThread.onStart
+     * performs its defined action
+     */
+    public void testSetUncaughtExceptionHandler() throws InterruptedException {
+        final CountDownLatch uehInvoked = new CountDownLatch(1);
+        final Thread.UncaughtExceptionHandler ueh =
+            new Thread.UncaughtExceptionHandler() {
+                public void uncaughtException(Thread t, Throwable e) {
+                    threadAssertTrue(e instanceof MyError);
+                    threadAssertTrue(t instanceof FailingFJWSubclass);
+                    uehInvoked.countDown();
+                }};
+        ForkJoinPool p = new ForkJoinPool(1, new FailingThreadFactory(),
+                                          ueh, false);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(ueh, p.getUncaughtExceptionHandler());
+            try {
+                p.execute(new FibTask(8));
+                await(uehInvoked);
+            } finally {
+                p.shutdownNow(); // failure might have prevented processing task
+            }
+        }
+    }
+
+    /**
+     * After invoking a single task, isQuiescent eventually becomes
+     * true, at which time queues are empty, threads are not active,
+     * the task has completed successfully, and construction
+     * parameters continue to hold
+     */
+    public void testIsQuiescent() throws Exception {
+        ForkJoinPool p = new ForkJoinPool(2);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertTrue(p.isQuiescent());
+            long startTime = System.nanoTime();
+            FibTask f = new FibTask(20);
+            p.invoke(f);
+            assertSame(ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                       p.getFactory());
+            while (! p.isQuiescent()) {
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    throw new AssertionFailedError("timed out");
+                assertFalse(p.getAsyncMode());
+                assertFalse(p.isShutdown());
+                assertFalse(p.isTerminating());
+                assertFalse(p.isTerminated());
+                Thread.yield();
+            }
+
+            assertTrue(p.isQuiescent());
+            assertFalse(p.getAsyncMode());
+            assertEquals(0, p.getQueuedTaskCount());
+            assertEquals(0, p.getQueuedSubmissionCount());
+            assertFalse(p.hasQueuedSubmissions());
+            while (p.getActiveThreadCount() != 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertFalse(p.isShutdown());
+            assertFalse(p.isTerminating());
+            assertFalse(p.isTerminated());
+            assertTrue(f.isDone());
+            assertEquals(6765, (int) f.get());
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * Completed submit(ForkJoinTask) returns result
+     */
+    public void testSubmitForkJoinTask() throws Throwable {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ForkJoinTask<Integer> f = p.submit(new FibTask(8));
+            assertEquals(21, (int) f.get());
+        }
+    }
+
+    /**
+     * A task submitted after shutdown is rejected
+     */
+    public void testSubmitAfterShutdown() {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            p.shutdown();
+            assertTrue(p.isShutdown());
+            try {
+                ForkJoinTask<Integer> f = p.submit(new FibTask(8));
+                shouldThrow();
+            } catch (RejectedExecutionException success) {}
+        }
+    }
+
+    /**
+     * Pool maintains parallelism when using ManagedBlocker
+     */
+    public void testBlockingForkJoinTask() throws Throwable {
+        ForkJoinPool p = new ForkJoinPool(4);
+        try {
+            ReentrantLock lock = new ReentrantLock();
+            ManagedLocker locker = new ManagedLocker(lock);
+            ForkJoinTask<Integer> f = new LockingFibTask(20, locker, lock);
+            p.execute(f);
+            assertEquals(6765, (int) f.get());
+        } finally {
+            p.shutdownNow(); // don't wait out shutdown
+        }
+    }
+
+    /**
+     * pollSubmission returns unexecuted submitted task, if present
+     */
+    public void testPollSubmission() {
+        final CountDownLatch done = new CountDownLatch(1);
+        SubFJP p = new SubFJP();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ForkJoinTask a = p.submit(awaiter(done));
+            ForkJoinTask b = p.submit(awaiter(done));
+            ForkJoinTask c = p.submit(awaiter(done));
+            ForkJoinTask r = p.pollSubmission();
+            assertTrue(r == a || r == b || r == c);
+            assertFalse(r.isDone());
+            done.countDown();
+        }
+    }
+
+    /**
+     * drainTasksTo transfers unexecuted submitted tasks, if present
+     */
+    public void testDrainTasksTo() {
+        final CountDownLatch done = new CountDownLatch(1);
+        SubFJP p = new SubFJP();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ForkJoinTask a = p.submit(awaiter(done));
+            ForkJoinTask b = p.submit(awaiter(done));
+            ForkJoinTask c = p.submit(awaiter(done));
+            ArrayList<ForkJoinTask> al = new ArrayList();
+            p.drainTasksTo(al);
+            assertTrue(al.size() > 0);
+            for (ForkJoinTask r : al) {
+                assertTrue(r == a || r == b || r == c);
+                assertFalse(r.isDone());
+            }
+            done.countDown();
+        }
+    }
+
+    // FJ Versions of AbstractExecutorService tests
+
+    /**
+     * execute(runnable) runs it to completion
+     */
+    public void testExecuteRunnable() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            final AtomicBoolean done = new AtomicBoolean(false);
+            Future<?> future = e.submit(new CheckedRunnable() {
+                public void realRun() {
+                    done.set(true);
+                }});
+            assertNull(future.get());
+            assertNull(future.get(0, MILLISECONDS));
+            assertTrue(done.get());
+            assertTrue(future.isDone());
+            assertFalse(future.isCancelled());
+        }
+    }
+
+    /**
+     * Completed submit(callable) returns result
+     */
+    public void testSubmitCallable() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new StringTask());
+            assertSame(TEST_STRING, future.get());
+            assertTrue(future.isDone());
+            assertFalse(future.isCancelled());
+        }
+    }
+
+    /**
+     * Completed submit(runnable) returns successfully
+     */
+    public void testSubmitRunnable() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<?> future = e.submit(new NoOpRunnable());
+            assertNull(future.get());
+            assertTrue(future.isDone());
+            assertFalse(future.isCancelled());
+        }
+    }
+
+    /**
+     * Completed submit(runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            assertSame(TEST_STRING, future.get());
+            assertTrue(future.isDone());
+            assertFalse(future.isCancelled());
+        }
+    }
+
+    /**
+     * A submitted privileged action runs to completion
+     */
+    public void testSubmitPrivilegedAction() throws Exception {
+        final Callable callable = Executors.callable(new PrivilegedAction() {
+                public Object run() { return TEST_STRING; }});
+        Runnable r = new CheckedRunnable() {
+        public void realRun() throws Exception {
+            ExecutorService e = new ForkJoinPool(1);
+            try (PoolCleaner cleaner = cleaner(e)) {
+                Future future = e.submit(callable);
+                assertSame(TEST_STRING, future.get());
+            }
+        }};
+
+        runWithPermissions(r, new RuntimePermission("modifyThread"));
+    }
+
+    /**
+     * A submitted privileged exception action runs to completion
+     */
+    public void testSubmitPrivilegedExceptionAction() throws Exception {
+        final Callable callable =
+            Executors.callable(new PrivilegedExceptionAction() {
+                public Object run() { return TEST_STRING; }});
+        Runnable r = new CheckedRunnable() {
+        public void realRun() throws Exception {
+            ExecutorService e = new ForkJoinPool(1);
+            try (PoolCleaner cleaner = cleaner(e)) {
+                Future future = e.submit(callable);
+                assertSame(TEST_STRING, future.get());
+            }
+        }};
+
+        runWithPermissions(r, new RuntimePermission("modifyThread"));
+    }
+
+    /**
+     * A submitted failed privileged exception action reports exception
+     */
+    public void testSubmitFailedPrivilegedExceptionAction() throws Exception {
+        final Callable callable =
+            Executors.callable(new PrivilegedExceptionAction() {
+                public Object run() { throw new IndexOutOfBoundsException(); }});
+        Runnable r = new CheckedRunnable() {
+        public void realRun() throws Exception {
+            ExecutorService e = new ForkJoinPool(1);
+            try (PoolCleaner cleaner = cleaner(e)) {
+                Future future = e.submit(callable);
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    assertTrue(success.getCause() instanceof IndexOutOfBoundsException);
+                }
+            }
+        }};
+
+        runWithPermissions(r, new RuntimePermission("modifyThread"));
+    }
+
+    /**
+     * execute(null runnable) throws NullPointerException
+     */
+    public void testExecuteNullRunnable() {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                Future<?> future = e.submit((Runnable) null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * submit(null callable) throws NullPointerException
+     */
+    public void testSubmitNullCallable() {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                Future<String> future = e.submit((Callable) null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * submit(callable).get() throws InterruptedException if interrupted
+     */
+    public void testInterruptedSubmit() throws InterruptedException {
+        final CountDownLatch submitted    = new CountDownLatch(1);
+        final CountDownLatch quittingTime = new CountDownLatch(1);
+        final Callable<Void> awaiter = new CheckedCallable<Void>() {
+            public Void realCall() throws InterruptedException {
+                assertTrue(quittingTime.await(2*LONG_DELAY_MS, MILLISECONDS));
+                return null;
+            }};
+        final ExecutorService p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p, quittingTime)) {
+            Thread t = new Thread(new CheckedInterruptedRunnable() {
+                public void realRun() throws Exception {
+                    Future<Void> future = p.submit(awaiter);
+                    submitted.countDown();
+                    future.get();
+                }});
+            t.start();
+            await(submitted);
+            t.interrupt();
+            awaitTermination(t);
+        }
+    }
+
+    /**
+     * get of submit(callable) throws ExecutionException if callable
+     * throws exception
+     */
+    public void testSubmitEE() throws Throwable {
+        ForkJoinPool p = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.submit(new Callable() {
+                        public Object call() { throw new ArithmeticException(); }})
+                    .get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof ArithmeticException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NullPointerException
+     */
+    public void testInvokeAny1() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IllegalArgumentException
+     */
+    public void testInvokeAny2() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NullPointerException if c has a single null element
+     */
+    public void testInvokeAny3() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NullPointerException if c has null elements
+     */
+    public void testInvokeAny4() throws Throwable {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task in c completes
+     */
+    public void testInvokeAny5() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task in c if at least one completes
+     */
+    public void testInvokeAny6() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NullPointerException
+     */
+    public void testInvokeAll1() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws InterruptedException {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r
+                = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NullPointerException if c has null elements
+     */
+    public void testInvokeAll3() throws InterruptedException {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of returned element of invokeAll(c) throws
+     * ExecutionException on failed task
+     */
+    public void testInvokeAll4() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks in c
+     */
+    public void testInvokeAll5() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NullPointerException
+     */
+    public void testTimedInvokeAny1() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(null time unit) throws NullPointerException
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IllegalArgumentException
+     */
+    public void testTimedInvokeAny2() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NullPointerException if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Throwable {
+        CountDownLatch latch = new CountDownLatch(1);
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task in c
+     */
+    public void testTimedInvokeAny5() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NullPointerException
+     */
+    public void testTimedInvokeAll1() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(null time unit) throws NullPointerException
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws InterruptedException {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r
+                = e.invokeAll(new ArrayList<Callable<String>>(),
+                              MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NullPointerException if c has null elements
+     */
+    public void testTimedInvokeAll3() throws InterruptedException {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of returned element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Throwable {
+        ExecutorService e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures
+                = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks in c
+     */
+    public void testTimedInvokeAll5() throws Throwable {
+        ForkJoinPool e = new ForkJoinPool(1);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures
+                = e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ForkJoinTask8Test.java b/ojluni/src/test/java/util/concurrent/tck/ForkJoinTask8Test.java
new file mode 100644
index 0000000..bf9d17c
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ForkJoinTask8Test.java
@@ -0,0 +1,1228 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinTask8Test extends JSR166TestCase {
+
+    /*
+     * Testing notes: This differs from ForkJoinTaskTest mainly by
+     * defining a version of BinaryAsyncAction that uses JDK8 task
+     * tags for control state, thereby testing getForkJoinTaskTag,
+     * setForkJoinTaskTag, and compareAndSetForkJoinTaskTag across
+     * various contexts. Most of the test methods using it are
+     * otherwise identical, but omitting retest of those dealing with
+     * cancellation, which is not represented in this tag scheme.
+     */
+
+    static final short INITIAL_STATE = -1;
+    static final short COMPLETE_STATE = 0;
+    static final short EXCEPTION_STATE = 1;
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ForkJoinTask8Test.class);
+    }
+
+    // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+    static final int mainPoolSize =
+        Math.max(2, Runtime.getRuntime().availableProcessors());
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool(mainPoolSize);
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    // Compute fib naively and efficiently
+    final int[] fib;
+    {
+        int[] fib = new int[10];
+        fib[0] = 0;
+        fib[1] = 1;
+        for (int i = 2; i < fib.length; i++)
+            fib[i] = fib[i - 1] + fib[i - 2];
+        this.fib = fib;
+    }
+
+    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            assertFalse(a.isDone());
+            assertFalse(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+
+            assertNull(pool.invoke(a));
+
+            assertTrue(a.isDone());
+            assertTrue(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+        }
+    }
+
+    void checkNotDone(ForkJoinTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == INITIAL_STATE);
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a) {
+        checkCompletedNormally(a, null);
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertSame(expected, a.getRawResult());
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() == COMPLETE_STATE);
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            assertSame(expected, a.join());
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertSame(expected, a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertSame(expected, a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        if (a instanceof BinaryAsyncAction)
+            assertTrue(((BinaryAsyncAction)a).getForkJoinTaskTag() != INITIAL_STATE);
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(t.getClass(), expected.getClass());
+        }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        FJException() { super(); }
+    }
+
+    abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
+
+        private volatile BinaryAsyncAction parent;
+
+        private volatile BinaryAsyncAction sibling;
+
+        protected BinaryAsyncAction() {
+            setForkJoinTaskTag(INITIAL_STATE);
+        }
+
+        public final Void getRawResult() { return null; }
+        protected final void setRawResult(Void mustBeNull) { }
+
+        public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            x.parent = y.parent = this;
+            x.sibling = y;
+            y.sibling = x;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            if (this.getForkJoinTaskTag() != COMPLETE_STATE ||
+                x.getForkJoinTaskTag() != COMPLETE_STATE ||
+                y.getForkJoinTaskTag() != COMPLETE_STATE) {
+                completeThisExceptionally(new FJException());
+            }
+        }
+
+        protected boolean onException() {
+            return true;
+        }
+
+        public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            linkSubtasks(x, y);
+            y.fork();
+            x.fork();
+        }
+
+        private void completeThis() {
+            setForkJoinTaskTag(COMPLETE_STATE);
+            super.complete(null);
+        }
+
+        private void completeThisExceptionally(Throwable ex) {
+            setForkJoinTaskTag(EXCEPTION_STATE);
+            super.completeExceptionally(ex);
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            if (super.cancel(mayInterruptIfRunning)) {
+                completeExceptionally(new FJException());
+                return true;
+            }
+            return false;
+        }
+
+        public final void complete() {
+            BinaryAsyncAction a = this;
+            for (;;) {
+                BinaryAsyncAction s = a.sibling;
+                BinaryAsyncAction p = a.parent;
+                a.sibling = null;
+                a.parent = null;
+                a.completeThis();
+                if (p == null ||
+                    p.compareAndSetForkJoinTaskTag(INITIAL_STATE, COMPLETE_STATE))
+                    break;
+                try {
+                    p.onComplete(a, s);
+                } catch (Throwable rex) {
+                    p.completeExceptionally(rex);
+                    return;
+                }
+                a = p;
+            }
+        }
+
+        public final void completeExceptionally(Throwable ex) {
+            for (BinaryAsyncAction a = this;;) {
+                a.completeThisExceptionally(ex);
+                BinaryAsyncAction s = a.sibling;
+                if (s != null && !s.isDone())
+                    s.completeExceptionally(ex);
+                if ((a = a.parent) == null)
+                    break;
+            }
+        }
+
+        public final BinaryAsyncAction getParent() {
+            return parent;
+        }
+
+        public BinaryAsyncAction getSibling() {
+            return sibling;
+        }
+
+        public void reinitialize() {
+            parent = sibling = null;
+            super.reinitialize();
+        }
+
+    }
+
+    final class AsyncFib extends BinaryAsyncAction {
+        int number;
+        int expectedResult;
+        public AsyncFib(int number) {
+            this.number = number;
+            this.expectedResult = fib[number];
+        }
+
+        public final boolean exec() {
+            try {
+                AsyncFib f = this;
+                int n = f.number;
+                while (n > 1) {
+                    AsyncFib p = f;
+                    AsyncFib r = new AsyncFib(n - 2);
+                    f = new AsyncFib(--n);
+                    p.linkSubtasks(r, f);
+                    r.fork();
+                }
+                f.complete();
+            }
+            catch (Throwable ex) {
+                compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
+            }
+            if (getForkJoinTaskTag() == EXCEPTION_STATE)
+                throw new FJException();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            number = ((AsyncFib)x).number + ((AsyncFib)y).number;
+            super.onComplete(x, y);
+        }
+
+        public void checkCompletedNormally() {
+            assertEquals(expectedResult, number);
+            ForkJoinTask8Test.this.checkCompletedNormally(this);
+        }
+    }
+
+    static final class FailingAsyncFib extends BinaryAsyncAction {
+        int number;
+        public FailingAsyncFib(int n) {
+            this.number = n;
+        }
+
+        public final boolean exec() {
+            try {
+                FailingAsyncFib f = this;
+                int n = f.number;
+                while (n > 1) {
+                    FailingAsyncFib p = f;
+                    FailingAsyncFib r = new FailingAsyncFib(n - 2);
+                    f = new FailingAsyncFib(--n);
+                    p.linkSubtasks(r, f);
+                    r.fork();
+                }
+                f.complete();
+            }
+            catch (Throwable ex) {
+                compareAndSetForkJoinTaskTag(INITIAL_STATE, EXCEPTION_STATE);
+            }
+            if (getForkJoinTaskTag() == EXCEPTION_STATE)
+                throw new FJException();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvoke() {
+        testInvoke(mainPool());
+    }
+    public void testInvoke_Singleton() {
+        testInvoke(singletonPool());
+    }
+    public void testInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertNull(f.invoke());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        testQuietlyInvoke(mainPool());
+    }
+    public void testQuietlyInvoke_Singleton() {
+        testQuietlyInvoke(singletonPool());
+    }
+    public void testQuietlyInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.quietlyInvoke();
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        testForkJoin(mainPool());
+    }
+    public void testForkJoin_Singleton() {
+        testForkJoin(singletonPool());
+    }
+    public void testForkJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        testForkGet(mainPool());
+    }
+    public void testForkGet_Singleton() {
+        testForkGet(singletonPool());
+    }
+    public void testForkGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        testForkTimedGet(mainPool());
+    }
+    public void testForkTimedGet_Singleton() {
+        testForkTimedGet(singletonPool());
+    }
+    public void testForkTimedGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get with null time unit throws NullPointerException
+     */
+    public void testForkTimedGetNullTimeUnit() {
+        testForkTimedGetNullTimeUnit(mainPool());
+    }
+    public void testForkTimedGetNullTimeUnit_Singleton() {
+        testForkTimedGet(singletonPool());
+    }
+    public void testForkTimedGetNullTimeUnit(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        testForkQuietlyJoin(mainPool());
+    }
+    public void testForkQuietlyJoin_Singleton() {
+        testForkQuietlyJoin(singletonPool());
+    }
+    public void testForkQuietlyJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        testForkHelpQuiesce(mainPool());
+    }
+    public void testForkHelpQuiesce_Singleton() {
+        testForkHelpQuiesce(singletonPool());
+    }
+    public void testForkHelpQuiesce(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(0, getQueuedTaskCount());
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        testAbnormalInvoke(mainPool());
+    }
+    public void testAbnormalInvoke_Singleton() {
+        testAbnormalInvoke(singletonPool());
+    }
+    public void testAbnormalInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        testAbnormalQuietlyInvoke(mainPool());
+    }
+    public void testAbnormalQuietlyInvoke_Singleton() {
+        testAbnormalQuietlyInvoke(singletonPool());
+    }
+    public void testAbnormalQuietlyInvoke(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        testAbnormalForkJoin(mainPool());
+    }
+    public void testAbnormalForkJoin_Singleton() {
+        testAbnormalForkJoin(singletonPool());
+    }
+    public void testAbnormalForkJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        testAbnormalForkGet(mainPool());
+    }
+    public void testAbnormalForkGet_Singleton() {
+        testAbnormalForkJoin(singletonPool());
+    }
+    public void testAbnormalForkGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        testAbnormalForkTimedGet(mainPool());
+    }
+    public void testAbnormalForkTimedGet_Singleton() {
+        testAbnormalForkTimedGet(singletonPool());
+    }
+    public void testAbnormalForkTimedGet(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        testAbnormalForkQuietlyJoin(mainPool());
+    }
+    public void testAbnormalForkQuietlyJoin_Singleton() {
+        testAbnormalForkQuietlyJoin(singletonPool());
+    }
+    public void testAbnormalForkQuietlyJoin(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        testGetPool(mainPool());
+    }
+    public void testGetPool_Singleton() {
+        testGetPool(singletonPool());
+    }
+    public void testGetPool(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertSame(pool, getPool());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        testInForkJoinPool(mainPool());
+    }
+    public void testInForkJoinPool_Singleton() {
+        testInForkJoinPool(singletonPool());
+    }
+    public void testInForkJoinPool(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertTrue(inForkJoinPool());
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResult() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        testCompleteExceptionally(mainPool());
+    }
+    public void testCompleteExceptionally_Singleton() {
+        testCompleteExceptionally(singletonPool());
+    }
+    public void testCompleteExceptionally(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        testInvokeAll1(mainPool());
+    }
+    public void testInvokeAll1_Singleton() {
+        testInvokeAll1(singletonPool());
+    }
+    public void testInvokeAll1(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                invokeAll(f);
+                f.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        testInvokeAll2(mainPool());
+    }
+    public void testInvokeAll2_Singleton() {
+        testInvokeAll2(singletonPool());
+    }
+    public void testInvokeAll2(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                };
+                invokeAll(tasks[0], tasks[1]);
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        testInvokeAll3(mainPool());
+    }
+    public void testInvokeAll3_Singleton() {
+        testInvokeAll3(singletonPool());
+    }
+    public void testInvokeAll3(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                    new AsyncFib(7),
+                };
+                invokeAll(tasks[0], tasks[1], tasks[2]);
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        testInvokeAllCollection(mainPool());
+    }
+    public void testInvokeAllCollection_Singleton() {
+        testInvokeAllCollection(singletonPool());
+    }
+    public void testInvokeAllCollection(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib[] tasks = {
+                    new AsyncFib(8),
+                    new AsyncFib(9),
+                    new AsyncFib(7),
+                };
+                invokeAll(Arrays.asList(tasks));
+                for (AsyncFib task : tasks) assertTrue(task.isDone());
+                for (AsyncFib task : tasks) task.checkCompletedNormally();
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NullPointerException
+     */
+    public void testInvokeAllNullTask() {
+        testInvokeAllNullTask(mainPool());
+    }
+    public void testInvokeAllNullTask_Singleton() {
+        testInvokeAllNullTask(singletonPool());
+    }
+    public void testInvokeAllNullTask(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib nul = null;
+                Runnable[] throwingActions = {
+                    () -> invokeAll(nul),
+                    () -> invokeAll(nul, nul),
+                    () -> invokeAll(new AsyncFib(8), new AsyncFib(9), nul),
+                    () -> invokeAll(new AsyncFib(8), nul, new AsyncFib(9)),
+                    () -> invokeAll(nul, new AsyncFib(8), new AsyncFib(9)),
+                };
+                assertThrows(NullPointerException.class, throwingActions);
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        testAbnormalInvokeAll1(mainPool());
+    }
+    public void testAbnormalInvokeAll1_Singleton() {
+        testAbnormalInvokeAll1(singletonPool());
+    }
+    public void testAbnormalInvokeAll1(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        testAbnormalInvokeAll2(mainPool());
+    }
+    public void testAbnormalInvokeAll2_Singleton() {
+        testAbnormalInvokeAll2(singletonPool());
+    }
+    public void testAbnormalInvokeAll2(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks[0], tasks[1]);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        testAbnormalInvokeAll3(mainPool());
+    }
+    public void testAbnormalInvokeAll3_Singleton() {
+        testAbnormalInvokeAll3(singletonPool());
+    }
+    public void testAbnormalInvokeAll3(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks[0], tasks[1], tasks[2]);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        testAbnormalInvokeAllCollection(mainPool());
+    }
+    public void testAbnormalInvokeAllCollection_Singleton() {
+        testAbnormalInvokeAllCollection(singletonPool());
+    }
+    public void testAbnormalInvokeAllCollection(ForkJoinPool pool) {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(Arrays.asList(tasks));
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(pool, a);
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib h = new AsyncFib(7);
+                assertSame(h, h.fork());
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                f.checkCompletedNormally();
+                g.checkCompletedNormally();
+                h.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                assertNull(f.join());
+                f.checkCompletedNormally();
+                helpQuiesce();
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task without
+     * executing it
+     */
+    public void testPollNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertNull(f.join());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                g.checkCompletedNormally();
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                f.checkCompletedNormally();
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * ForkJoinTask.quietlyComplete returns when task completes
+     * normally without setting a value. The most recent value
+     * established by setRawResult(V) (or null by default) is returned
+     * from invoke.
+     */
+    public void testQuietlyComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    AsyncFib f = new AsyncFib(8);
+                    f.quietlyComplete();
+                    assertEquals(8, f.number);
+                    assertTrue(f.isDone());
+                    assertFalse(f.isCancelled());
+                    assertTrue(f.isCompletedNormally());
+                    assertFalse(f.isCompletedAbnormally());
+                    assertNull(f.getException());
+                }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    // jdk9
+
+    /**
+     * pollSubmission returns unexecuted submitted task, if present
+     */
+    public void testPollSubmission() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ForkJoinTask a = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinTask b = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinTask c = ForkJoinTask.adapt(awaiter(done));
+        final ForkJoinPool p = singletonPool();
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Thread external = new Thread(new CheckedRunnable() {
+                public void realRun() {
+                    p.execute(a);
+                    p.execute(b);
+                    p.execute(c);
+                }});
+            RecursiveAction s = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    external.start();
+                    try {
+                        external.join();
+                    } catch (Exception ex) {
+                        threadUnexpectedException(ex);
+                    }
+                    assertTrue(p.hasQueuedSubmissions());
+                    assertTrue(Thread.currentThread() instanceof ForkJoinWorkerThread);
+                    ForkJoinTask r = ForkJoinTask.pollSubmission();
+                    assertTrue(r == a || r == b || r == c);
+                    assertFalse(r.isDone());
+                }};
+            p.invoke(s);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ForkJoinTaskTest.java b/ojluni/src/test/java/util/concurrent/tck/ForkJoinTaskTest.java
new file mode 100644
index 0000000..2255fda
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ForkJoinTaskTest.java
@@ -0,0 +1,1682 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ForkJoinTaskTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ForkJoinTaskTest.class);
+    }
+
+    // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
+    static final int mainPoolSize =
+        Math.max(2, Runtime.getRuntime().availableProcessors());
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool(mainPoolSize);
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            assertFalse(a.isDone());
+            assertFalse(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+
+            assertNull(pool.invoke(a));
+
+            assertTrue(a.isDone());
+            assertTrue(a.isCompletedNormally());
+            assertFalse(a.isCompletedAbnormally());
+            assertFalse(a.isCancelled());
+            assertNull(a.getException());
+            assertNull(a.getRawResult());
+        }
+    }
+
+    void checkNotDone(ForkJoinTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a) {
+        checkCompletedNormally(a, null);
+    }
+
+    <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertSame(expected, a.getRawResult());
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            assertSame(expected, a.join());
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        {
+            Thread.currentThread().interrupt();
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+            Thread.interrupted();
+        }
+
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertSame(expected, a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertSame(expected, a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(ForkJoinTask a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+        assertTrue(a.cancel(false));
+        assertTrue(a.cancel(true));
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(ForkJoinTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            Thread.currentThread().interrupt();
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(t.getClass(), expected.getClass());
+        }
+        Thread.interrupted();
+
+        {
+            long startTime = System.nanoTime();
+            a.quietlyJoin();        // should be no-op
+            assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    /*
+     * Testing coverage notes:
+     *
+     * To test extension methods and overrides, most tests use
+     * BinaryAsyncAction extension class that processes joins
+     * differently than supplied Recursive forms.
+     */
+
+    public static final class FJException extends RuntimeException {
+        FJException() { super(); }
+    }
+
+    abstract static class BinaryAsyncAction extends ForkJoinTask<Void> {
+        private volatile int controlState;
+
+        static final AtomicIntegerFieldUpdater<BinaryAsyncAction> controlStateUpdater =
+            AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class,
+                                                 "controlState");
+
+        private volatile BinaryAsyncAction parent;
+
+        private volatile BinaryAsyncAction sibling;
+
+        protected BinaryAsyncAction() {
+        }
+
+        public final Void getRawResult() { return null; }
+        protected final void setRawResult(Void mustBeNull) { }
+
+        public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            x.parent = y.parent = this;
+            x.sibling = y;
+            y.sibling = x;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+        }
+
+        protected boolean onException() {
+            return true;
+        }
+
+        public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
+            linkSubtasks(x, y);
+            y.fork();
+            x.fork();
+        }
+
+        private void completeThis() {
+            super.complete(null);
+        }
+
+        private void completeThisExceptionally(Throwable ex) {
+            super.completeExceptionally(ex);
+        }
+
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            if (super.cancel(mayInterruptIfRunning)) {
+                completeExceptionally(new FJException());
+                return true;
+            }
+            return false;
+        }
+
+        public final void complete() {
+            BinaryAsyncAction a = this;
+            for (;;) {
+                BinaryAsyncAction s = a.sibling;
+                BinaryAsyncAction p = a.parent;
+                a.sibling = null;
+                a.parent = null;
+                a.completeThis();
+                if (p == null || p.compareAndSetControlState(0, 1))
+                    break;
+                try {
+                    p.onComplete(a, s);
+                } catch (Throwable rex) {
+                    p.completeExceptionally(rex);
+                    return;
+                }
+                a = p;
+            }
+        }
+
+        public final void completeExceptionally(Throwable ex) {
+            for (BinaryAsyncAction a = this;;) {
+                a.completeThisExceptionally(ex);
+                BinaryAsyncAction s = a.sibling;
+                if (s != null && !s.isDone())
+                    s.completeExceptionally(ex);
+                if ((a = a.parent) == null)
+                    break;
+            }
+        }
+
+        public final BinaryAsyncAction getParent() {
+            return parent;
+        }
+
+        public BinaryAsyncAction getSibling() {
+            return sibling;
+        }
+
+        public void reinitialize() {
+            parent = sibling = null;
+            super.reinitialize();
+        }
+
+        protected final int getControlState() {
+            return controlState;
+        }
+
+        protected final boolean compareAndSetControlState(int expect,
+                                                          int update) {
+            return controlStateUpdater.compareAndSet(this, expect, update);
+        }
+
+        protected final void setControlState(int value) {
+            controlState = value;
+        }
+
+        protected final void incrementControlState() {
+            controlStateUpdater.incrementAndGet(this);
+        }
+
+        protected final void decrementControlState() {
+            controlStateUpdater.decrementAndGet(this);
+        }
+
+    }
+
+    static final class AsyncFib extends BinaryAsyncAction {
+        int number;
+        public AsyncFib(int n) {
+            this.number = n;
+        }
+
+        public final boolean exec() {
+            AsyncFib f = this;
+            int n = f.number;
+            while (n > 1) {
+                AsyncFib p = f;
+                AsyncFib r = new AsyncFib(n - 2);
+                f = new AsyncFib(--n);
+                p.linkSubtasks(r, f);
+                r.fork();
+            }
+            f.complete();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            number = ((AsyncFib)x).number + ((AsyncFib)y).number;
+        }
+    }
+
+    static final class FailingAsyncFib extends BinaryAsyncAction {
+        int number;
+        public FailingAsyncFib(int n) {
+            this.number = n;
+        }
+
+        public final boolean exec() {
+            FailingAsyncFib f = this;
+            int n = f.number;
+            while (n > 1) {
+                FailingAsyncFib p = f;
+                FailingAsyncFib r = new FailingAsyncFib(n - 2);
+                f = new FailingAsyncFib(--n);
+                p.linkSubtasks(r, f);
+                r.fork();
+            }
+            f.complete();
+            return false;
+        }
+
+        protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
+            completeExceptionally(new FJException());
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                assertEquals(0, getQueuedTaskCount());
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() throws Exception {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        final ForkJoinPool mainPool = mainPool();
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertSame(mainPool, getPool());
+            }};
+        testInvokeOnPool(mainPool, a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertTrue(inForkJoinPool());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResult() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * completeExceptionally(null) surprisingly has the same effect as
+     * completeExceptionally(new RuntimeException())
+     */
+    public void testCompleteExceptionally_null() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(null);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (RuntimeException success) {
+                    assertSame(success.getClass(), RuntimeException.class);
+                    assertNull(success.getCause());
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(Arrays.asList(tasks));
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib h = new AsyncFib(7);
+                assertSame(h, h.fork());
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                assertNull(f.join());
+                checkCompletedNormally(f);
+                helpQuiesce();
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task without
+     * executing it
+     */
+    public void testPollNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                assertEquals(34, g.number);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertNull(f.join());
+                helpQuiesce();
+                checkCompletedNormally(f);
+                assertEquals(34, g.number);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib g = new AsyncFib(9);
+                assertSame(g, g.fork());
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    // versions for singleton pools
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks; getRawResult returns null.
+     */
+    public void testInvokeSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvokeSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGetSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGetSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPESingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesceSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                assertEquals(0, getQueuedTaskCount());
+                assertEquals(21, f.number);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvokeSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvokeSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGetSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGetSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvokeSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGetSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGetSingleton() throws Exception {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoinSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionallySingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                invokeAll(f, g);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.number);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                invokeAll(f, g, h);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollectionSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertEquals(21, f.number);
+                assertEquals(34, g.number);
+                assertEquals(13, h.number);
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPESingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                ForkJoinTask[] tasks = { f, g };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3Singleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                AsyncFib f = new AsyncFib(8);
+                FailingAsyncFib g = new FailingAsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(tasks);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollectionSingleton() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingAsyncFib f = new FailingAsyncFib(8);
+                AsyncFib g = new AsyncFib(9);
+                AsyncFib h = new AsyncFib(7);
+                ForkJoinTask[] tasks = { f, g, h };
+                shuffle(tasks);
+                try {
+                    invokeAll(Arrays.asList(tasks));
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * ForkJoinTask.quietlyComplete returns when task completes
+     * normally without setting a value. The most recent value
+     * established by setRawResult(V) (or null by default) is returned
+     * from invoke.
+     */
+    public void testQuietlyComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+                protected void realCompute() {
+                    AsyncFib f = new AsyncFib(8);
+                    f.quietlyComplete();
+                    assertEquals(8, f.number);
+                    checkCompletedNormally(f);
+                }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/FutureTaskTest.java b/ojluni/src/test/java/util/concurrent/tck/FutureTaskTest.java
new file mode 100644
index 0000000..40f0a84
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/FutureTaskTest.java
@@ -0,0 +1,867 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class FutureTaskTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(FutureTaskTest.class);
+    }
+
+    void checkIsDone(Future<?> f) {
+        assertTrue(f.isDone());
+        assertFalse(f.cancel(false));
+        assertFalse(f.cancel(true));
+        if (f instanceof PublicFutureTask) {
+            PublicFutureTask pf = (PublicFutureTask) f;
+            assertEquals(1, pf.doneCount());
+            assertFalse(pf.runAndReset());
+            assertEquals(1, pf.doneCount());
+            Object r = null; Object exInfo = null;
+            try {
+                r = f.get();
+            } catch (CancellationException t) {
+                exInfo = CancellationException.class;
+            } catch (ExecutionException t) {
+                exInfo = t.getCause();
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+
+            // Check that run and runAndReset have no effect.
+            int savedRunCount = pf.runCount();
+            pf.run();
+            pf.runAndReset();
+            assertEquals(savedRunCount, pf.runCount());
+            try {
+                assertSame(r, f.get());
+            } catch (CancellationException t) {
+                assertSame(exInfo, CancellationException.class);
+            } catch (ExecutionException t) {
+                assertSame(exInfo, t.getCause());
+            } catch (Throwable t) {
+                threadUnexpectedException(t);
+            }
+            assertTrue(f.isDone());
+        }
+    }
+
+    void checkNotDone(Future<?> f) {
+        assertFalse(f.isDone());
+        assertFalse(f.isCancelled());
+        if (f instanceof PublicFutureTask) {
+            PublicFutureTask pf = (PublicFutureTask) f;
+            assertEquals(0, pf.doneCount());
+            assertEquals(0, pf.setCount());
+            assertEquals(0, pf.setExceptionCount());
+        }
+    }
+
+    void checkIsRunning(Future<?> f) {
+        checkNotDone(f);
+        if (f instanceof FutureTask) {
+            FutureTask ft = (FutureTask<?>) f;
+            // Check that run methods do nothing
+            ft.run();
+            if (f instanceof PublicFutureTask) {
+                PublicFutureTask pf = (PublicFutureTask) f;
+                int savedRunCount = pf.runCount();
+                pf.run();
+                assertFalse(pf.runAndReset());
+                assertEquals(savedRunCount, pf.runCount());
+            }
+            checkNotDone(f);
+        }
+    }
+
+    <T> void checkCompletedNormally(Future<T> f, T expected) {
+        checkIsDone(f);
+        assertFalse(f.isCancelled());
+
+        try {
+            assertSame(expected, f.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertSame(expected, f.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(Future<?> f) {
+        checkIsDone(f);
+        assertTrue(f.isCancelled());
+
+        try {
+            f.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void tryToConfuseDoneTask(PublicFutureTask pf) {
+        pf.set(new Object());
+        pf.setException(new Error());
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+            pf.cancel(mayInterruptIfRunning);
+        }
+    }
+
+    void checkCompletedAbnormally(Future<?> f, Throwable t) {
+        checkIsDone(f);
+        assertFalse(f.isCancelled());
+
+        try {
+            f.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            f.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t, success.getCause());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    /**
+     * Subclass to expose protected methods
+     */
+    static class PublicFutureTask extends FutureTask {
+        private final AtomicInteger runCount;
+        private final AtomicInteger doneCount = new AtomicInteger(0);
+        private final AtomicInteger runAndResetCount = new AtomicInteger(0);
+        private final AtomicInteger setCount = new AtomicInteger(0);
+        private final AtomicInteger setExceptionCount = new AtomicInteger(0);
+        public int runCount() { return runCount.get(); }
+        public int doneCount() { return doneCount.get(); }
+        public int runAndResetCount() { return runAndResetCount.get(); }
+        public int setCount() { return setCount.get(); }
+        public int setExceptionCount() { return setExceptionCount.get(); }
+
+        PublicFutureTask(Runnable runnable) {
+            this(runnable, seven);
+        }
+        PublicFutureTask(Runnable runnable, Object result) {
+            this(runnable, result, new AtomicInteger(0));
+        }
+        private PublicFutureTask(final Runnable runnable, Object result,
+                                 final AtomicInteger runCount) {
+            super(new Runnable() {
+                public void run() {
+                    runCount.getAndIncrement();
+                    runnable.run();
+                }}, result);
+            this.runCount = runCount;
+        }
+        PublicFutureTask(Callable callable) {
+            this(callable, new AtomicInteger(0));
+        }
+        private PublicFutureTask(final Callable callable,
+                                 final AtomicInteger runCount) {
+            super(new Callable() {
+                public Object call() throws Exception {
+                    runCount.getAndIncrement();
+                    return callable.call();
+                }});
+            this.runCount = runCount;
+        }
+        @Override public void done() {
+            assertTrue(isDone());
+            doneCount.incrementAndGet();
+            super.done();
+        }
+        @Override public boolean runAndReset() {
+            runAndResetCount.incrementAndGet();
+            return super.runAndReset();
+        }
+        @Override public void set(Object x) {
+            setCount.incrementAndGet();
+            super.set(x);
+        }
+        @Override public void setException(Throwable t) {
+            setExceptionCount.incrementAndGet();
+            super.setException(t);
+        }
+    }
+
+    class Counter extends CheckedRunnable {
+        final AtomicInteger count = new AtomicInteger(0);
+        public int get() { return count.get(); }
+        public void realRun() {
+            count.getAndIncrement();
+        }
+    }
+
+    /**
+     * creating a future with a null callable throws NullPointerException
+     */
+    public void testConstructor() {
+        try {
+            new FutureTask(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * creating a future with null runnable throws NullPointerException
+     */
+    public void testConstructor2() {
+        try {
+            new FutureTask(null, Boolean.TRUE);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * isDone is true when a task completes
+     */
+    public void testIsDone() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        assertFalse(task.isDone());
+        task.run();
+        assertTrue(task.isDone());
+        checkCompletedNormally(task, Boolean.TRUE);
+        assertEquals(1, task.runCount());
+    }
+
+    /**
+     * runAndReset of a non-cancelled task succeeds
+     */
+    public void testRunAndReset() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        for (int i = 0; i < 3; i++) {
+            assertTrue(task.runAndReset());
+            checkNotDone(task);
+            assertEquals(i + 1, task.runCount());
+            assertEquals(i + 1, task.runAndResetCount());
+            assertEquals(0, task.setCount());
+            assertEquals(0, task.setExceptionCount());
+        }
+    }
+
+    /**
+     * runAndReset after cancellation fails
+     */
+    public void testRunAndResetAfterCancel() {
+        for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
+            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+            assertTrue(task.cancel(mayInterruptIfRunning));
+            for (int i = 0; i < 3; i++) {
+                assertFalse(task.runAndReset());
+                assertEquals(0, task.runCount());
+                assertEquals(i + 1, task.runAndResetCount());
+                assertEquals(0, task.setCount());
+                assertEquals(0, task.setExceptionCount());
+            }
+            tryToConfuseDoneTask(task);
+            checkCancelled(task);
+        }
+    }
+
+    /**
+     * setting value causes get to return it
+     */
+    public void testSet() throws Exception {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        task.set(one);
+        for (int i = 0; i < 3; i++) {
+            assertSame(one, task.get());
+            assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
+            assertEquals(1, task.setCount());
+        }
+        tryToConfuseDoneTask(task);
+        checkCompletedNormally(task, one);
+        assertEquals(0, task.runCount());
+    }
+
+    /**
+     * setException causes get to throw ExecutionException
+     */
+    public void testSetException_get() throws Exception {
+        Exception nse = new NoSuchElementException();
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        task.setException(nse);
+
+        try {
+            task.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(nse, success.getCause());
+            checkCompletedAbnormally(task, nse);
+        }
+
+        try {
+            task.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(nse, success.getCause());
+            checkCompletedAbnormally(task, nse);
+        }
+
+        assertEquals(1, task.setExceptionCount());
+        assertEquals(0, task.setCount());
+        tryToConfuseDoneTask(task);
+        checkCompletedAbnormally(task, nse);
+        assertEquals(0, task.runCount());
+    }
+
+    /**
+     * cancel(false) before run succeeds
+     */
+    public void testCancelBeforeRun() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        assertTrue(task.cancel(false));
+        task.run();
+        assertEquals(0, task.runCount());
+        assertEquals(0, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        assertTrue(task.isCancelled());
+        assertTrue(task.isDone());
+        tryToConfuseDoneTask(task);
+        assertEquals(0, task.runCount());
+        checkCancelled(task);
+    }
+
+    /**
+     * cancel(true) before run succeeds
+     */
+    public void testCancelBeforeRun2() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        assertTrue(task.cancel(true));
+        task.run();
+        assertEquals(0, task.runCount());
+        assertEquals(0, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        assertTrue(task.isCancelled());
+        assertTrue(task.isDone());
+        tryToConfuseDoneTask(task);
+        assertEquals(0, task.runCount());
+        checkCancelled(task);
+    }
+
+    /**
+     * cancel(false) of a completed task fails
+     */
+    public void testCancelAfterRun() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        task.run();
+        assertFalse(task.cancel(false));
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCompletedNormally(task, Boolean.TRUE);
+        assertEquals(1, task.runCount());
+    }
+
+    /**
+     * cancel(true) of a completed task fails
+     */
+    public void testCancelAfterRun2() {
+        PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
+        task.run();
+        assertFalse(task.cancel(true));
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCompletedNormally(task, Boolean.TRUE);
+        assertEquals(1, task.runCount());
+    }
+
+    /**
+     * cancel(true) interrupts a running task that subsequently succeeds
+     */
+    public void testCancelInterrupt() {
+        final CountDownLatch pleaseCancel = new CountDownLatch(1);
+        final PublicFutureTask task =
+            new PublicFutureTask(new CheckedRunnable() {
+                public void realRun() {
+                    pleaseCancel.countDown();
+                    try {
+                        delay(LONG_DELAY_MS);
+                        shouldThrow();
+                    } catch (InterruptedException success) {}
+                }});
+
+        Thread t = newStartedThread(task);
+        await(pleaseCancel);
+        assertTrue(task.cancel(true));
+        assertTrue(task.isCancelled());
+        assertTrue(task.isDone());
+        awaitTermination(t);
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCancelled(task);
+    }
+
+    /**
+     * cancel(true) tries to interrupt a running task, but
+     * Thread.interrupt throws (simulating a restrictive security
+     * manager)
+     */
+    public void testCancelInterrupt_ThrowsSecurityException() {
+        final CountDownLatch pleaseCancel = new CountDownLatch(1);
+        final CountDownLatch cancelled = new CountDownLatch(1);
+        final PublicFutureTask task =
+            new PublicFutureTask(new CheckedRunnable() {
+                public void realRun() {
+                    pleaseCancel.countDown();
+                    await(cancelled);
+                    assertFalse(Thread.interrupted());
+                }});
+
+        final Thread t = new Thread(task) {
+            // Simulate a restrictive security manager.
+            @Override public void interrupt() {
+                throw new SecurityException();
+            }};
+        t.setDaemon(true);
+        t.start();
+
+        await(pleaseCancel);
+        try {
+            task.cancel(true);
+            shouldThrow();
+        } catch (SecurityException expected) {}
+
+        // We failed to deliver the interrupt, but the world retains
+        // its sanity, as if we had done task.cancel(false)
+        assertTrue(task.isCancelled());
+        assertTrue(task.isDone());
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.doneCount());
+        assertEquals(0, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        cancelled.countDown();
+        awaitTermination(t);
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCancelled(task);
+    }
+
+    /**
+     * cancel(true) interrupts a running task that subsequently throws
+     */
+    public void testCancelInterrupt_taskFails() {
+        final CountDownLatch pleaseCancel = new CountDownLatch(1);
+        final PublicFutureTask task =
+            new PublicFutureTask(new Runnable() {
+                public void run() {
+                    pleaseCancel.countDown();
+                    try {
+                        delay(LONG_DELAY_MS);
+                        threadShouldThrow();
+                    } catch (InterruptedException success) {
+                    } catch (Throwable t) { threadUnexpectedException(t); }
+                    throw new RuntimeException();
+                }});
+
+        Thread t = newStartedThread(task);
+        await(pleaseCancel);
+        assertTrue(task.cancel(true));
+        assertTrue(task.isCancelled());
+        awaitTermination(t);
+        assertEquals(1, task.runCount());
+        assertEquals(0, task.setCount());
+        assertEquals(1, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCancelled(task);
+    }
+
+    /**
+     * cancel(false) does not interrupt a running task
+     */
+    public void testCancelNoInterrupt() {
+        final CountDownLatch pleaseCancel = new CountDownLatch(1);
+        final CountDownLatch cancelled = new CountDownLatch(1);
+        final PublicFutureTask task =
+            new PublicFutureTask(new CheckedCallable<Boolean>() {
+                public Boolean realCall() {
+                    pleaseCancel.countDown();
+                    await(cancelled);
+                    assertFalse(Thread.interrupted());
+                    return Boolean.TRUE;
+                }});
+
+        Thread t = newStartedThread(task);
+        await(pleaseCancel);
+        assertTrue(task.cancel(false));
+        assertTrue(task.isCancelled());
+        cancelled.countDown();
+        awaitTermination(t);
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCancelled(task);
+    }
+
+    /**
+     * run in one thread causes get in another thread to retrieve value
+     */
+    public void testGetRun() {
+        final CountDownLatch pleaseRun = new CountDownLatch(2);
+
+        final PublicFutureTask task =
+            new PublicFutureTask(new CheckedCallable<Object>() {
+                public Object realCall() {
+                    return two;
+                }});
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                pleaseRun.countDown();
+                assertSame(two, task.get());
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                pleaseRun.countDown();
+                assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        await(pleaseRun);
+        checkNotDone(task);
+        assertTrue(t1.isAlive());
+        assertTrue(t2.isAlive());
+        task.run();
+        checkCompletedNormally(task, two);
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        awaitTermination(t1);
+        awaitTermination(t2);
+        tryToConfuseDoneTask(task);
+        checkCompletedNormally(task, two);
+    }
+
+    /**
+     * set in one thread causes get in another thread to retrieve value
+     */
+    public void testGetSet() {
+        final CountDownLatch pleaseSet = new CountDownLatch(2);
+
+        final PublicFutureTask task =
+            new PublicFutureTask(new CheckedCallable<Object>() {
+                public Object realCall() throws InterruptedException {
+                    return two;
+                }});
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                pleaseSet.countDown();
+                assertSame(two, task.get());
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                pleaseSet.countDown();
+                assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        await(pleaseSet);
+        checkNotDone(task);
+        assertTrue(t1.isAlive());
+        assertTrue(t2.isAlive());
+        task.set(two);
+        assertEquals(0, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCompletedNormally(task, two);
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Cancelling a task causes timed get in another thread to throw
+     * CancellationException
+     */
+    public void testTimedGet_Cancellation() {
+        testTimedGet_Cancellation(false);
+    }
+    public void testTimedGet_Cancellation_interrupt() {
+        testTimedGet_Cancellation(true);
+    }
+    public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
+        final CountDownLatch pleaseCancel = new CountDownLatch(3);
+        final CountDownLatch cancelled = new CountDownLatch(1);
+        final Callable<Object> callable =
+            new CheckedCallable<Object>() {
+            public Object realCall() throws InterruptedException {
+                pleaseCancel.countDown();
+                if (mayInterruptIfRunning) {
+                    try {
+                        delay(2*LONG_DELAY_MS);
+                    } catch (InterruptedException success) {}
+                } else {
+                    await(cancelled);
+                }
+                return two;
+            }};
+        final PublicFutureTask task = new PublicFutureTask(callable);
+
+        Thread t1 = new ThreadShouldThrow(CancellationException.class) {
+                public void realRun() throws Exception {
+                    pleaseCancel.countDown();
+                    task.get();
+                }};
+        Thread t2 = new ThreadShouldThrow(CancellationException.class) {
+                public void realRun() throws Exception {
+                    pleaseCancel.countDown();
+                    task.get(2*LONG_DELAY_MS, MILLISECONDS);
+                }};
+        t1.start();
+        t2.start();
+        Thread t3 = newStartedThread(task);
+        await(pleaseCancel);
+        checkIsRunning(task);
+        task.cancel(mayInterruptIfRunning);
+        checkCancelled(task);
+        awaitTermination(t1);
+        awaitTermination(t2);
+        cancelled.countDown();
+        awaitTermination(t3);
+        assertEquals(1, task.runCount());
+        assertEquals(1, task.setCount());
+        assertEquals(0, task.setExceptionCount());
+        tryToConfuseDoneTask(task);
+        checkCancelled(task);
+    }
+
+    /**
+     * A runtime exception in task causes get to throw ExecutionException
+     */
+    public void testGet_ExecutionException() throws InterruptedException {
+        final ArithmeticException e = new ArithmeticException();
+        final PublicFutureTask task = new PublicFutureTask(new Callable() {
+            public Object call() {
+                throw e;
+            }});
+
+        task.run();
+        assertEquals(1, task.runCount());
+        assertEquals(0, task.setCount());
+        assertEquals(1, task.setExceptionCount());
+        try {
+            task.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(e, success.getCause());
+            tryToConfuseDoneTask(task);
+            checkCompletedAbnormally(task, success.getCause());
+        }
+    }
+
+    /**
+     * A runtime exception in task causes timed get to throw ExecutionException
+     */
+    public void testTimedGet_ExecutionException2() throws Exception {
+        final ArithmeticException e = new ArithmeticException();
+        final PublicFutureTask task = new PublicFutureTask(new Callable() {
+            public Object call() {
+                throw e;
+            }});
+
+        task.run();
+        try {
+            task.get(LONG_DELAY_MS, MILLISECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(e, success.getCause());
+            tryToConfuseDoneTask(task);
+            checkCompletedAbnormally(task, success.getCause());
+        }
+    }
+
+    /**
+     * get is interruptible
+     */
+    public void testGet_interruptible() {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final FutureTask task = new FutureTask(new NoOpCallable());
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Thread.currentThread().interrupt();
+                try {
+                    task.get();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    task.get();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        t.interrupt();
+        awaitTermination(t);
+        checkNotDone(task);
+    }
+
+    /**
+     * timed get is interruptible
+     */
+    public void testTimedGet_interruptible() {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final FutureTask task = new FutureTask(new NoOpCallable());
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                Thread.currentThread().interrupt();
+                try {
+                    task.get(2*LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    task.get(2*LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        t.interrupt();
+        awaitTermination(t);
+        checkNotDone(task);
+    }
+
+    /**
+     * A timed out timed get throws TimeoutException
+     */
+    public void testGet_TimeoutException() throws Exception {
+        FutureTask task = new FutureTask(new NoOpCallable());
+        long startTime = System.nanoTime();
+        try {
+            task.get(timeoutMillis(), MILLISECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * timed get with null TimeUnit throws NullPointerException
+     */
+    public void testGet_NullTimeUnit() throws Exception {
+        FutureTask task = new FutureTask(new NoOpCallable());
+        long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
+
+        for (long timeout : timeouts) {
+            try {
+                task.get(timeout, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+
+        task.run();
+
+        for (long timeout : timeouts) {
+            try {
+                task.get(timeout, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed get with most negative timeout works correctly (i.e. no
+     * underflow bug)
+     */
+    public void testGet_NegativeInfinityTimeout() throws Exception {
+        final ExecutorService pool = Executors.newFixedThreadPool(10);
+        final Runnable nop = new Runnable() { public void run() {}};
+        final FutureTask<Void> task = new FutureTask<>(nop, null);
+        final List<Future<?>> futures = new ArrayList<>();
+        Runnable r = new Runnable() { public void run() {
+            for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
+                try {
+                    task.get(timeout, NANOSECONDS);
+                    shouldThrow();
+                } catch (TimeoutException success) {
+                } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
+        for (int i = 0; i < 10; i++)
+            futures.add(pool.submit(r));
+        try {
+            joinPool(pool);
+            for (Future<?> future : futures)
+                checkCompletedNormally(future, null);
+        } finally {
+            task.run();         // last resort to help terminate
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
new file mode 100644
index 0000000..575a8f3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/JSR166TestCase.java
@@ -0,0 +1,2037 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+/*
+ * @test
+ * @summary JSR-166 tck tests (conformance testing mode)
+ * @build *
+ * @modules java.management
+ * @run junit/othervm/timeout=1000 JSR166TestCase
+ */
+
+/*
+ * @test
+ * @summary JSR-166 tck tests (whitebox tests allowed)
+ * @build *
+ * @modules java.base/java.util.concurrent:open
+ *          java.base/java.lang:open
+ *          java.management
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=0
+ *      JSR166TestCase
+ * @run junit/othervm/timeout=1000
+ *      -Djsr166.testImplementationDetails=true
+ *      -Djava.util.concurrent.ForkJoinPool.common.parallelism=1
+ *      -Djava.util.secureRandomSeed=true
+ *      JSR166TestCase
+ * @run junit/othervm/timeout=1000/policy=tck.policy
+ *      -Djsr166.testImplementationDetails=true
+ *      JSR166TestCase
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+//import java.lang.management.ManagementFactory;
+//import java.lang.management.ThreadInfo;
+//import java.lang.management.ThreadMXBean;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.security.SecurityPermission;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.PropertyPermission;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.Future;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestResult;
+import junit.framework.TestSuite;
+
+/**
+ * Base class for JSR166 Junit TCK tests.  Defines some constants,
+ * utility methods and classes, as well as a simple framework for
+ * helping to make sure that assertions failing in generated threads
+ * cause the associated test that generated them to itself fail (which
+ * JUnit does not otherwise arrange).  The rules for creating such
+ * tests are:
+ *
+ * <ol>
+ *
+ * <li>All assertions in code running in generated threads must use
+ * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
+ * #threadAssertEquals}, or {@link #threadAssertNull}, (not
+ * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
+ * particularly recommended) for other code to use these forms too.
+ * Only the most typically used JUnit assertion methods are defined
+ * this way, but enough to live with.
+ *
+ * <li>If you override {@link #setUp} or {@link #tearDown}, make sure
+ * to invoke {@code super.setUp} and {@code super.tearDown} within
+ * them. These methods are used to clear and check for thread
+ * assertion failures.
+ *
+ * <li>All delays and timeouts must use one of the constants {@code
+ * SHORT_DELAY_MS}, {@code SMALL_DELAY_MS}, {@code MEDIUM_DELAY_MS},
+ * {@code LONG_DELAY_MS}. The idea here is that a SHORT is always
+ * discriminable from zero time, and always allows enough time for the
+ * small amounts of computation (creating a thread, calling a few
+ * methods, etc) needed to reach a timeout point. Similarly, a SMALL
+ * is always discriminable as larger than SHORT and smaller than
+ * MEDIUM.  And so on. These constants are set to conservative values,
+ * but even so, if there is ever any doubt, they can all be increased
+ * in one spot to rerun tests on slower platforms.
+ *
+ * <li>All threads generated must be joined inside each test case
+ * method (or {@code fail} to do so) before returning from the
+ * method. The {@code joinPool} method can be used to do this when
+ * using Executors.
+ *
+ * </ol>
+ *
+ * <p><b>Other notes</b>
+ * <ul>
+ *
+ * <li>Usually, there is one testcase method per JSR166 method
+ * covering "normal" operation, and then as many exception-testing
+ * methods as there are exceptions the method can throw. Sometimes
+ * there are multiple tests per JSR166 method when the different
+ * "normal" behaviors differ significantly. And sometimes testcases
+ * cover multiple methods when they cannot be tested in isolation.
+ *
+ * <li>The documentation style for testcases is to provide as javadoc
+ * a simple sentence or two describing the property that the testcase
+ * method purports to test. The javadocs do not say anything about how
+ * the property is tested. To find out, read the code.
+ *
+ * <li>These tests are "conformance tests", and do not attempt to
+ * test throughput, latency, scalability or other performance factors
+ * (see the separate "jtreg" tests for a set intended to check these
+ * for the most central aspects of functionality.) So, most tests use
+ * the smallest sensible numbers of threads, collection sizes, etc
+ * needed to check basic conformance.
+ *
+ * <li>The test classes currently do not declare inclusion in
+ * any particular package to simplify things for people integrating
+ * them in TCK test suites.
+ *
+ * <li>As a convenience, the {@code main} of this class (JSR166TestCase)
+ * runs all JSR166 unit tests.
+ *
+ * </ul>
+ */
+public class JSR166TestCase extends TestCase {
+    private static final boolean useSecurityManager =
+        Boolean.getBoolean("jsr166.useSecurityManager");
+
+    protected static final boolean expensiveTests =
+        Boolean.getBoolean("jsr166.expensiveTests");
+
+    /**
+     * If true, also run tests that are not part of the official tck
+     * because they test unspecified implementation details.
+     */
+    protected static final boolean testImplementationDetails =
+        Boolean.getBoolean("jsr166.testImplementationDetails");
+
+    /**
+     * If true, report on stdout all "slow" tests, that is, ones that
+     * take more than profileThreshold milliseconds to execute.
+     */
+    private static final boolean profileTests =
+        Boolean.getBoolean("jsr166.profileTests");
+
+    /**
+     * The number of milliseconds that tests are permitted for
+     * execution without being reported, when profileTests is set.
+     */
+    private static final long profileThreshold =
+        Long.getLong("jsr166.profileThreshold", 100);
+
+    /**
+     * The number of repetitions per test (for tickling rare bugs).
+     */
+    private static final int runsPerTest =
+        Integer.getInteger("jsr166.runsPerTest", 1);
+
+    /**
+     * The number of repetitions of the test suite (for finding leaks?).
+     */
+    private static final int suiteRuns =
+        Integer.getInteger("jsr166.suiteRuns", 1);
+
+    /**
+     * Returns the value of the system property, or NaN if not defined.
+     */
+    private static float systemPropertyValue(String name) {
+        String floatString = System.getProperty(name);
+        if (floatString == null)
+            return Float.NaN;
+        try {
+            return Float.parseFloat(floatString);
+        } catch (NumberFormatException ex) {
+            throw new IllegalArgumentException(
+                String.format("Bad float value in system property %s=%s",
+                              name, floatString));
+        }
+    }
+
+    /**
+     * The scaling factor to apply to standard delays used in tests.
+     * May be initialized from any of:
+     * - the "jsr166.delay.factor" system property
+     * - the "test.timeout.factor" system property (as used by jtreg)
+     *   See: http://openjdk.java.net/jtreg/tag-spec.html
+     * - hard-coded fuzz factor when using a known slowpoke VM
+     */
+    private static final float delayFactor = delayFactor();
+
+    private static float delayFactor() {
+        float x;
+        if (!Float.isNaN(x = systemPropertyValue("jsr166.delay.factor")))
+            return x;
+        if (!Float.isNaN(x = systemPropertyValue("test.timeout.factor")))
+            return x;
+        String prop = System.getProperty("java.vm.version");
+        if (prop != null && prop.matches(".*debug.*"))
+            return 4.0f; // How much slower is fastdebug than product?!
+        return 1.0f;
+    }
+
+    public JSR166TestCase() { super(); }
+    public JSR166TestCase(String name) { super(name); }
+
+    /**
+     * A filter for tests to run, matching strings of the form
+     * methodName(className), e.g. "testInvokeAll5(ForkJoinPoolTest)"
+     * Usefully combined with jsr166.runsPerTest.
+     */
+    private static final Pattern methodFilter = methodFilter();
+
+    private static Pattern methodFilter() {
+        String regex = System.getProperty("jsr166.methodFilter");
+        return (regex == null) ? null : Pattern.compile(regex);
+    }
+
+    // Instrumentation to debug very rare, but very annoying hung test runs.
+    static volatile TestCase currentTestCase;
+    // static volatile int currentRun = 0;
+    static {
+        Runnable checkForWedgedTest = new Runnable() { public void run() {
+            // Avoid spurious reports with enormous runsPerTest.
+            // A single test case run should never take more than 1 second.
+            // But let's cap it at the high end too ...
+            final int timeoutMinutes =
+                Math.min(15, Math.max(runsPerTest / 60, 1));
+            for (TestCase lastTestCase = currentTestCase;;) {
+                try { MINUTES.sleep(timeoutMinutes); }
+                catch (InterruptedException unexpected) { break; }
+                if (lastTestCase == currentTestCase) {
+                    System.err.printf(
+                        "Looks like we're stuck running test: %s%n",
+                        lastTestCase);
+//                     System.err.printf(
+//                         "Looks like we're stuck running test: %s (%d/%d)%n",
+//                         lastTestCase, currentRun, runsPerTest);
+//                     System.err.println("availableProcessors=" +
+//                         Runtime.getRuntime().availableProcessors());
+//                     System.err.printf("cpu model = %s%n", cpuModel());
+                    dumpTestThreads();
+                    // one stack dump is probably enough; more would be spam
+                    break;
+                }
+                lastTestCase = currentTestCase;
+            }}};
+        Thread thread = new Thread(checkForWedgedTest, "checkForWedgedTest");
+        thread.setDaemon(true);
+        thread.start();
+    }
+
+//     public static String cpuModel() {
+//         try {
+//             Matcher matcher = Pattern.compile("model name\\s*: (.*)")
+//                 .matcher(new String(
+//                      Files.readAllBytes(Paths.get("/proc/cpuinfo")), "UTF-8"));
+//             matcher.find();
+//             return matcher.group(1);
+//         } catch (Exception ex) { return null; }
+//     }
+
+    public void runBare() throws Throwable {
+        currentTestCase = this;
+        if (methodFilter == null
+            || methodFilter.matcher(toString()).find())
+            super.runBare();
+    }
+
+    protected void runTest() throws Throwable {
+        for (int i = 0; i < runsPerTest; i++) {
+            // currentRun = i;
+            if (profileTests)
+                runTestProfiled();
+            else
+                super.runTest();
+        }
+    }
+
+    protected void runTestProfiled() throws Throwable {
+        for (int i = 0; i < 2; i++) {
+            long startTime = System.nanoTime();
+            super.runTest();
+            long elapsedMillis = millisElapsedSince(startTime);
+            if (elapsedMillis < profileThreshold)
+                break;
+            // Never report first run of any test; treat it as a
+            // warmup run, notably to trigger all needed classloading,
+            if (i > 0)
+                System.out.printf("%n%s: %d%n", toString(), elapsedMillis);
+        }
+    }
+
+    /**
+     * Runs all JSR166 unit tests using junit.textui.TestRunner.
+     */
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    static class PithyResultPrinter extends junit.textui.ResultPrinter {
+        PithyResultPrinter(java.io.PrintStream writer) { super(writer); }
+        long runTime;
+        public void startTest(Test test) {}
+        protected void printHeader(long runTime) {
+            this.runTime = runTime; // defer printing for later
+        }
+        protected void printFooter(TestResult result) {
+            if (result.wasSuccessful()) {
+                getWriter().println("OK (" + result.runCount() + " tests)"
+                    + "  Time: " + elapsedTimeAsString(runTime));
+            } else {
+                getWriter().println("Time: " + elapsedTimeAsString(runTime));
+                super.printFooter(result);
+            }
+        }
+    }
+
+    /**
+     * Returns a TestRunner that doesn't bother with unnecessary
+     * fluff, like printing a "." for each test case.
+     */
+    static junit.textui.TestRunner newPithyTestRunner() {
+        junit.textui.TestRunner runner = new junit.textui.TestRunner();
+        runner.setPrinter(new PithyResultPrinter(System.out));
+        return runner;
+    }
+
+    /**
+     * Runs all unit tests in the given test suite.
+     * Actual behavior influenced by jsr166.* system properties.
+     */
+    static void main(Test suite, String[] args) {
+        if (useSecurityManager) {
+            System.err.println("Setting a permissive security manager");
+            Policy.setPolicy(permissivePolicy());
+            System.setSecurityManager(new SecurityManager());
+        }
+        for (int i = 0; i < suiteRuns; i++) {
+            TestResult result = newPithyTestRunner().doRun(suite);
+            if (!result.wasSuccessful())
+                System.exit(1);
+            System.gc();
+            System.runFinalization();
+        }
+    }
+
+    public static TestSuite newTestSuite(Object... suiteOrClasses) {
+        TestSuite suite = new TestSuite();
+        for (Object suiteOrClass : suiteOrClasses) {
+            if (suiteOrClass instanceof TestSuite)
+                suite.addTest((TestSuite) suiteOrClass);
+            else if (suiteOrClass instanceof Class)
+                suite.addTest(new TestSuite((Class<?>) suiteOrClass));
+            else
+                throw new ClassCastException("not a test suite or class");
+        }
+        return suite;
+    }
+
+    public static void addNamedTestClasses(TestSuite suite,
+                                           String... testClassNames) {
+        for (String testClassName : testClassNames) {
+            try {
+                Class<?> testClass = Class.forName(testClassName);
+                Method m = testClass.getDeclaredMethod("suite",
+                                                       new Class<?>[0]);
+                suite.addTest(newTestSuite((Test)m.invoke(null)));
+            } catch (Exception e) {
+                throw new Error("Missing test class", e);
+            }
+        }
+    }
+
+    public static final double JAVA_CLASS_VERSION;
+    public static final String JAVA_SPECIFICATION_VERSION;
+    static {
+        try {
+            JAVA_CLASS_VERSION = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<Double>() {
+                public Double run() {
+                    return Double.valueOf(System.getProperty("java.class.version"));}});
+            JAVA_SPECIFICATION_VERSION = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<String>() {
+                public String run() {
+                    return System.getProperty("java.specification.version");}});
+        } catch (Throwable t) {
+            throw new Error(t);
+        }
+    }
+
+    public static boolean atLeastJava6() { return JAVA_CLASS_VERSION >= 50.0; }
+    public static boolean atLeastJava7() { return JAVA_CLASS_VERSION >= 51.0; }
+    public static boolean atLeastJava8() { return JAVA_CLASS_VERSION >= 52.0; }
+    public static boolean atLeastJava9() {
+        return JAVA_CLASS_VERSION >= 53.0
+            // As of 2015-09, java9 still uses 52.0 class file version
+            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?(9|[0-9][0-9])$");
+    }
+    public static boolean atLeastJava10() {
+        return JAVA_CLASS_VERSION >= 54.0
+            || JAVA_SPECIFICATION_VERSION.matches("^(1\\.)?[0-9][0-9]$");
+    }
+
+    /**
+     * Collects all JSR166 unit tests as one suite.
+     */
+    public static Test suite() {
+        // Java7+ test classes
+        TestSuite suite = newTestSuite(
+            ForkJoinPoolTest.suite(),
+            ForkJoinTaskTest.suite(),
+            RecursiveActionTest.suite(),
+            RecursiveTaskTest.suite(),
+            LinkedTransferQueueTest.suite(),
+            PhaserTest.suite(),
+            ThreadLocalRandomTest.suite(),
+            AbstractExecutorServiceTest.suite(),
+            AbstractQueueTest.suite(),
+            AbstractQueuedSynchronizerTest.suite(),
+            AbstractQueuedLongSynchronizerTest.suite(),
+            ArrayBlockingQueueTest.suite(),
+            ArrayDequeTest.suite(),
+            ArrayListTest.suite(),
+            AtomicBooleanTest.suite(),
+            AtomicIntegerArrayTest.suite(),
+            AtomicIntegerFieldUpdaterTest.suite(),
+            AtomicIntegerTest.suite(),
+            AtomicLongArrayTest.suite(),
+            AtomicLongFieldUpdaterTest.suite(),
+            AtomicLongTest.suite(),
+            AtomicMarkableReferenceTest.suite(),
+            AtomicReferenceArrayTest.suite(),
+            AtomicReferenceFieldUpdaterTest.suite(),
+            AtomicReferenceTest.suite(),
+            AtomicStampedReferenceTest.suite(),
+            ConcurrentHashMapTest.suite(),
+            ConcurrentLinkedDequeTest.suite(),
+            ConcurrentLinkedQueueTest.suite(),
+            ConcurrentSkipListMapTest.suite(),
+            ConcurrentSkipListSubMapTest.suite(),
+            ConcurrentSkipListSetTest.suite(),
+            ConcurrentSkipListSubSetTest.suite(),
+            CopyOnWriteArrayListTest.suite(),
+            CopyOnWriteArraySetTest.suite(),
+            CountDownLatchTest.suite(),
+            CountedCompleterTest.suite(),
+            CyclicBarrierTest.suite(),
+            DelayQueueTest.suite(),
+            EntryTest.suite(),
+            ExchangerTest.suite(),
+            ExecutorsTest.suite(),
+            ExecutorCompletionServiceTest.suite(),
+            FutureTaskTest.suite(),
+            LinkedBlockingDequeTest.suite(),
+            LinkedBlockingQueueTest.suite(),
+            LinkedListTest.suite(),
+            LockSupportTest.suite(),
+            PriorityBlockingQueueTest.suite(),
+            PriorityQueueTest.suite(),
+            ReentrantLockTest.suite(),
+            ReentrantReadWriteLockTest.suite(),
+            ScheduledExecutorTest.suite(),
+            ScheduledExecutorSubclassTest.suite(),
+            SemaphoreTest.suite(),
+            SynchronousQueueTest.suite(),
+            SystemTest.suite(),
+            ThreadLocalTest.suite(),
+            ThreadPoolExecutorTest.suite(),
+            ThreadPoolExecutorSubclassTest.suite(),
+            ThreadTest.suite(),
+            TimeUnitTest.suite(),
+            TreeMapTest.suite(),
+            TreeSetTest.suite(),
+            TreeSubMapTest.suite(),
+            TreeSubSetTest.suite(),
+            VectorTest.suite());
+
+        // Java8+ test classes
+        if (atLeastJava8()) {
+            String[] java8TestClassNames = {
+                "ArrayDeque8Test",
+                "Atomic8Test",
+                "CompletableFutureTest",
+                "ConcurrentHashMap8Test",
+                "CountedCompleter8Test",
+                "DoubleAccumulatorTest",
+                "DoubleAdderTest",
+                "ForkJoinPool8Test",
+                "ForkJoinTask8Test",
+                "LinkedBlockingDeque8Test",
+                "LinkedBlockingQueue8Test",
+                "LongAccumulatorTest",
+                "LongAdderTest",
+                "SplittableRandomTest",
+                "StampedLockTest",
+                "SubmissionPublisherTest",
+                "ThreadLocalRandom8Test",
+                "TimeUnit8Test",
+            };
+            addNamedTestClasses(suite, java8TestClassNames);
+        }
+
+        // Java9+ test classes
+        if (atLeastJava9()) {
+            String[] java9TestClassNames = {
+                "AtomicBoolean9Test",
+                "AtomicInteger9Test",
+                "AtomicIntegerArray9Test",
+                "AtomicLong9Test",
+                "AtomicLongArray9Test",
+                "AtomicReference9Test",
+                "AtomicReferenceArray9Test",
+                "ExecutorCompletionService9Test",
+                "ForkJoinPool9Test",
+            };
+            addNamedTestClasses(suite, java9TestClassNames);
+        }
+
+        return suite;
+    }
+
+    /** Returns list of junit-style test method names in given class. */
+    public static ArrayList<String> testMethodNames(Class<?> testClass) {
+        Method[] methods = testClass.getDeclaredMethods();
+        ArrayList<String> names = new ArrayList<>(methods.length);
+        for (Method method : methods) {
+            if (method.getName().startsWith("test")
+                && Modifier.isPublic(method.getModifiers())
+                // method.getParameterCount() requires jdk8+
+                && method.getParameterTypes().length == 0) {
+                names.add(method.getName());
+            }
+        }
+        return names;
+    }
+
+    /**
+     * Returns junit-style testSuite for the given test class, but
+     * parameterized by passing extra data to each test.
+     */
+    public static <ExtraData> Test parameterizedTestSuite
+        (Class<? extends JSR166TestCase> testClass,
+         Class<ExtraData> dataClass,
+         ExtraData data) {
+        try {
+            TestSuite suite = new TestSuite();
+            Constructor c =
+                testClass.getDeclaredConstructor(dataClass, String.class);
+            for (String methodName : testMethodNames(testClass))
+                suite.addTest((Test) c.newInstance(data, methodName));
+            return suite;
+        } catch (Exception e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * Returns junit-style testSuite for the jdk8 extension of the
+     * given test class, but parameterized by passing extra data to
+     * each test.  Uses reflection to allow compilation in jdk7.
+     */
+    public static <ExtraData> Test jdk8ParameterizedTestSuite
+        (Class<? extends JSR166TestCase> testClass,
+         Class<ExtraData> dataClass,
+         ExtraData data) {
+        if (atLeastJava8()) {
+            String name = testClass.getName();
+            String name8 = name.replaceAll("Test$", "8Test");
+            if (name.equals(name8)) throw new Error(name);
+            try {
+                return (Test)
+                    Class.forName(name8)
+                    .getMethod("testSuite", new Class[] { dataClass })
+                    .invoke(null, data);
+            } catch (Exception e) {
+                throw new Error(e);
+            }
+        } else {
+            return new TestSuite();
+        }
+    }
+
+    // Delays for timing-dependent tests, in milliseconds.
+
+    public static long SHORT_DELAY_MS;
+    public static long SMALL_DELAY_MS;
+    public static long MEDIUM_DELAY_MS;
+    public static long LONG_DELAY_MS;
+
+    /**
+     * Returns the shortest timed delay. This can be scaled up for
+     * slow machines using the jsr166.delay.factor system property,
+     * or via jtreg's -timeoutFactor: flag.
+     * http://openjdk.java.net/jtreg/command-help.html
+     */
+    protected long getShortDelay() {
+        return (long) (50 * delayFactor);
+    }
+
+    /**
+     * Sets delays as multiples of SHORT_DELAY.
+     */
+    protected void setDelays() {
+        SHORT_DELAY_MS = getShortDelay();
+        SMALL_DELAY_MS  = SHORT_DELAY_MS * 5;
+        MEDIUM_DELAY_MS = SHORT_DELAY_MS * 10;
+        LONG_DELAY_MS   = SHORT_DELAY_MS * 200;
+    }
+
+    /**
+     * Returns a timeout in milliseconds to be used in tests that
+     * verify that operations block or time out.
+     */
+    long timeoutMillis() {
+        return SHORT_DELAY_MS / 4;
+    }
+
+    /**
+     * Returns a new Date instance representing a time at least
+     * delayMillis milliseconds in the future.
+     */
+    Date delayedDate(long delayMillis) {
+        // Add 1 because currentTimeMillis is known to round into the past.
+        return new Date(System.currentTimeMillis() + delayMillis + 1);
+    }
+
+    /**
+     * The first exception encountered if any threadAssertXXX method fails.
+     */
+    private final AtomicReference<Throwable> threadFailure
+        = new AtomicReference<>(null);
+
+    /**
+     * Records an exception so that it can be rethrown later in the test
+     * harness thread, triggering a test case failure.  Only the first
+     * failure is recorded; subsequent calls to this method from within
+     * the same test have no effect.
+     */
+    public void threadRecordFailure(Throwable t) {
+        System.err.println(t);
+        dumpTestThreads();
+        threadFailure.compareAndSet(null, t);
+    }
+
+    public void setUp() {
+        setDelays();
+    }
+
+    void tearDownFail(String format, Object... args) {
+        String msg = toString() + ": " + String.format(format, args);
+        System.err.println(msg);
+        dumpTestThreads();
+        throw new AssertionFailedError(msg);
+    }
+
+    /**
+     * Extra checks that get done for all test cases.
+     *
+     * Triggers test case failure if any thread assertions have failed,
+     * by rethrowing, in the test harness thread, any exception recorded
+     * earlier by threadRecordFailure.
+     *
+     * Triggers test case failure if interrupt status is set in the main thread.
+     */
+    public void tearDown() throws Exception {
+        Throwable t = threadFailure.getAndSet(null);
+        if (t != null) {
+            if (t instanceof Error)
+                throw (Error) t;
+            else if (t instanceof RuntimeException)
+                throw (RuntimeException) t;
+            else if (t instanceof Exception)
+                throw (Exception) t;
+            else {
+                AssertionFailedError afe =
+                    new AssertionFailedError(t.toString());
+                afe.initCause(t);
+                throw afe;
+            }
+        }
+
+        if (Thread.interrupted())
+            tearDownFail("interrupt status set in main thread");
+
+        checkForkJoinPoolThreadLeaks();
+    }
+
+    /**
+     * Finds missing PoolCleaners
+     */
+    void checkForkJoinPoolThreadLeaks() throws InterruptedException {
+        Thread[] survivors = new Thread[7];
+        int count = Thread.enumerate(survivors);
+        for (int i = 0; i < count; i++) {
+            Thread thread = survivors[i];
+            String name = thread.getName();
+            if (name.startsWith("ForkJoinPool-")) {
+                // give thread some time to terminate
+                thread.join(LONG_DELAY_MS);
+                if (thread.isAlive())
+                    tearDownFail("Found leaked ForkJoinPool thread thread=%s",
+                                 thread);
+            }
+        }
+
+        if (!ForkJoinPool.commonPool()
+            .awaitQuiescence(LONG_DELAY_MS, MILLISECONDS))
+            tearDownFail("ForkJoin common pool thread stuck");
+    }
+
+    /**
+     * Just like fail(reason), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadFail(String reason) {
+        try {
+            fail(reason);
+        } catch (AssertionFailedError t) {
+            threadRecordFailure(t);
+            throw t;
+        }
+    }
+
+    /**
+     * Just like assertTrue(b), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertTrue(boolean b) {
+        try {
+            assertTrue(b);
+        } catch (AssertionFailedError t) {
+            threadRecordFailure(t);
+            throw t;
+        }
+    }
+
+    /**
+     * Just like assertFalse(b), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertFalse(boolean b) {
+        try {
+            assertFalse(b);
+        } catch (AssertionFailedError t) {
+            threadRecordFailure(t);
+            throw t;
+        }
+    }
+
+    /**
+     * Just like assertNull(x), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertNull(Object x) {
+        try {
+            assertNull(x);
+        } catch (AssertionFailedError t) {
+            threadRecordFailure(t);
+            throw t;
+        }
+    }
+
+    /**
+     * Just like assertEquals(x, y), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertEquals(long x, long y) {
+        try {
+            assertEquals(x, y);
+        } catch (AssertionFailedError t) {
+            threadRecordFailure(t);
+            throw t;
+        }
+    }
+
+    /**
+     * Just like assertEquals(x, y), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertEquals(Object x, Object y) {
+        try {
+            assertEquals(x, y);
+        } catch (AssertionFailedError fail) {
+            threadRecordFailure(fail);
+            throw fail;
+        } catch (Throwable fail) {
+            threadUnexpectedException(fail);
+        }
+    }
+
+    /**
+     * Just like assertSame(x, y), but additionally recording (using
+     * threadRecordFailure) any AssertionFailedError thrown, so that
+     * the current testcase will fail.
+     */
+    public void threadAssertSame(Object x, Object y) {
+        try {
+            assertSame(x, y);
+        } catch (AssertionFailedError fail) {
+            threadRecordFailure(fail);
+            throw fail;
+        }
+    }
+
+    /**
+     * Calls threadFail with message "should throw exception".
+     */
+    public void threadShouldThrow() {
+        threadFail("should throw exception");
+    }
+
+    /**
+     * Calls threadFail with message "should throw" + exceptionName.
+     */
+    public void threadShouldThrow(String exceptionName) {
+        threadFail("should throw " + exceptionName);
+    }
+
+    /**
+     * Records the given exception using {@link #threadRecordFailure},
+     * then rethrows the exception, wrapping it in an
+     * AssertionFailedError if necessary.
+     */
+    public void threadUnexpectedException(Throwable t) {
+        threadRecordFailure(t);
+        t.printStackTrace();
+        if (t instanceof RuntimeException)
+            throw (RuntimeException) t;
+        else if (t instanceof Error)
+            throw (Error) t;
+        else {
+            AssertionFailedError afe =
+                new AssertionFailedError("unexpected exception: " + t);
+            afe.initCause(t);
+            throw afe;
+        }
+    }
+
+    /**
+     * Delays, via Thread.sleep, for the given millisecond delay, but
+     * if the sleep is shorter than specified, may re-sleep or yield
+     * until time elapses.  Ensures that the given time, as measured
+     * by System.nanoTime(), has elapsed.
+     */
+    static void delay(long millis) throws InterruptedException {
+        long nanos = millis * (1000 * 1000);
+        final long wakeupTime = System.nanoTime() + nanos;
+        do {
+            if (millis > 0L)
+                Thread.sleep(millis);
+            else // too short to sleep
+                Thread.yield();
+            nanos = wakeupTime - System.nanoTime();
+            millis = nanos / (1000 * 1000);
+        } while (nanos >= 0L);
+    }
+
+    /**
+     * Allows use of try-with-resources with per-test thread pools.
+     */
+    class PoolCleaner implements AutoCloseable {
+        private final ExecutorService pool;
+        public PoolCleaner(ExecutorService pool) { this.pool = pool; }
+        public void close() { joinPool(pool); }
+    }
+
+    /**
+     * An extension of PoolCleaner that has an action to release the pool.
+     */
+    class PoolCleanerWithReleaser extends PoolCleaner {
+        private final Runnable releaser;
+        public PoolCleanerWithReleaser(ExecutorService pool, Runnable releaser) {
+            super(pool);
+            this.releaser = releaser;
+        }
+        public void close() {
+            try {
+                releaser.run();
+            } finally {
+                super.close();
+            }
+        }
+    }
+
+    PoolCleaner cleaner(ExecutorService pool) {
+        return new PoolCleaner(pool);
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, Runnable releaser) {
+        return new PoolCleanerWithReleaser(pool, releaser);
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, CountDownLatch latch) {
+        return new PoolCleanerWithReleaser(pool, releaser(latch));
+    }
+
+    Runnable releaser(final CountDownLatch latch) {
+        return new Runnable() { public void run() {
+            do { latch.countDown(); }
+            while (latch.getCount() > 0);
+        }};
+    }
+
+    PoolCleaner cleaner(ExecutorService pool, AtomicBoolean flag) {
+        return new PoolCleanerWithReleaser(pool, releaser(flag));
+    }
+
+    Runnable releaser(final AtomicBoolean flag) {
+        return new Runnable() { public void run() { flag.set(true); }};
+    }
+
+    /**
+     * Waits out termination of a thread pool or fails doing so.
+     */
+    void joinPool(ExecutorService pool) {
+        try {
+            pool.shutdown();
+            if (!pool.awaitTermination(2 * LONG_DELAY_MS, MILLISECONDS)) {
+                try {
+                    threadFail("ExecutorService " + pool +
+                               " did not terminate in a timely manner");
+                } finally {
+                    // last resort, for the benefit of subsequent tests
+                    pool.shutdownNow();
+                    pool.awaitTermination(MEDIUM_DELAY_MS, MILLISECONDS);
+                }
+            }
+        } catch (SecurityException ok) {
+            // Allowed in case test doesn't have privs
+        } catch (InterruptedException fail) {
+            threadFail("Unexpected InterruptedException");
+        }
+    }
+
+    /**
+     * Like Runnable, but with the freedom to throw anything.
+     * junit folks had the same idea:
+     * http://junit.org/junit5/docs/snapshot/api/org/junit/gen5/api/Executable.html
+     */
+    interface Action { public void run() throws Throwable; }
+
+    /**
+     * Runs all the given actions in parallel, failing if any fail.
+     * Useful for running multiple variants of tests that are
+     * necessarily individually slow because they must block.
+     */
+    void testInParallel(Action ... actions) {
+        ExecutorService pool = Executors.newCachedThreadPool();
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            ArrayList<Future<?>> futures = new ArrayList<>(actions.length);
+            for (final Action action : actions)
+                futures.add(pool.submit(new CheckedRunnable() {
+                    public void realRun() throws Throwable { action.run();}}));
+            for (Future<?> future : futures)
+                try {
+                    assertNull(future.get(LONG_DELAY_MS, MILLISECONDS));
+                } catch (ExecutionException ex) {
+                    threadUnexpectedException(ex.getCause());
+                } catch (Exception ex) {
+                    threadUnexpectedException(ex);
+                }
+        }
+    }
+
+    /**
+     * A debugging tool to print stack traces of most threads, as jstack does.
+     * Uninteresting threads are filtered out.
+     */
+    static void dumpTestThreads() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            try {
+                System.setSecurityManager(null);
+            } catch (SecurityException giveUp) {
+                return;
+            }
+        }
+
+        // Android-removed: Android doesn't have ManagementFactory.
+        /*
+        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
+        System.err.println("------ stacktrace dump start ------");
+        for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
+            final String name = info.getThreadName();
+            String lockName;
+            if ("Signal Dispatcher".equals(name))
+                continue;
+            if ("Reference Handler".equals(name)
+                && (lockName = info.getLockName()) != null
+                && lockName.startsWith("java.lang.ref.Reference$Lock"))
+                continue;
+            if ("Finalizer".equals(name)
+                && (lockName = info.getLockName()) != null
+                && lockName.startsWith("java.lang.ref.ReferenceQueue$Lock"))
+                continue;
+            if ("checkForWedgedTest".equals(name))
+                continue;
+            System.err.print(info);
+        }
+        System.err.println("------ stacktrace dump end ------");
+        */
+
+        if (sm != null) System.setSecurityManager(sm);
+    }
+
+    /**
+     * Checks that thread does not terminate within the default
+     * millisecond delay of {@code timeoutMillis()}.
+     */
+    void assertThreadStaysAlive(Thread thread) {
+        assertThreadStaysAlive(thread, timeoutMillis());
+    }
+
+    /**
+     * Checks that thread does not terminate within the given millisecond delay.
+     */
+    void assertThreadStaysAlive(Thread thread, long millis) {
+        try {
+            // No need to optimize the failing case via Thread.join.
+            delay(millis);
+            assertTrue(thread.isAlive());
+        } catch (InterruptedException fail) {
+            threadFail("Unexpected InterruptedException");
+        }
+    }
+
+    /**
+     * Checks that the threads do not terminate within the default
+     * millisecond delay of {@code timeoutMillis()}.
+     */
+    void assertThreadsStayAlive(Thread... threads) {
+        assertThreadsStayAlive(timeoutMillis(), threads);
+    }
+
+    /**
+     * Checks that the threads do not terminate within the given millisecond delay.
+     */
+    void assertThreadsStayAlive(long millis, Thread... threads) {
+        try {
+            // No need to optimize the failing case via Thread.join.
+            delay(millis);
+            for (Thread thread : threads)
+                assertTrue(thread.isAlive());
+        } catch (InterruptedException fail) {
+            threadFail("Unexpected InterruptedException");
+        }
+    }
+
+    /**
+     * Checks that future.get times out, with the default timeout of
+     * {@code timeoutMillis()}.
+     */
+    void assertFutureTimesOut(Future future) {
+        assertFutureTimesOut(future, timeoutMillis());
+    }
+
+    /**
+     * Checks that future.get times out, with the given millisecond timeout.
+     */
+    void assertFutureTimesOut(Future future, long timeoutMillis) {
+        long startTime = System.nanoTime();
+        try {
+            future.get(timeoutMillis, MILLISECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Exception fail) {
+            threadUnexpectedException(fail);
+        } finally { future.cancel(true); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+    }
+
+    /**
+     * Fails with message "should throw exception".
+     */
+    public void shouldThrow() {
+        fail("Should throw exception");
+    }
+
+    /**
+     * Fails with message "should throw " + exceptionName.
+     */
+    public void shouldThrow(String exceptionName) {
+        fail("Should throw " + exceptionName);
+    }
+
+    /**
+     * The number of elements to place in collections, arrays, etc.
+     */
+    public static final int SIZE = 20;
+
+    // Some convenient Integer constants
+
+    public static final Integer zero  = new Integer(0);
+    public static final Integer one   = new Integer(1);
+    public static final Integer two   = new Integer(2);
+    public static final Integer three = new Integer(3);
+    public static final Integer four  = new Integer(4);
+    public static final Integer five  = new Integer(5);
+    public static final Integer six   = new Integer(6);
+    public static final Integer seven = new Integer(7);
+    public static final Integer eight = new Integer(8);
+    public static final Integer nine  = new Integer(9);
+    public static final Integer m1  = new Integer(-1);
+    public static final Integer m2  = new Integer(-2);
+    public static final Integer m3  = new Integer(-3);
+    public static final Integer m4  = new Integer(-4);
+    public static final Integer m5  = new Integer(-5);
+    public static final Integer m6  = new Integer(-6);
+    public static final Integer m10 = new Integer(-10);
+
+    /**
+     * Runs Runnable r with a security policy that permits precisely
+     * the specified permissions.  If there is no current security
+     * manager, the runnable is run twice, both with and without a
+     * security manager.  We require that any security manager permit
+     * getPolicy/setPolicy.
+     */
+    public void runWithPermissions(Runnable r, Permission... permissions) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            r.run();
+        }
+        runWithSecurityManagerWithPermissions(r, permissions);
+    }
+
+    /**
+     * Runs Runnable r with a security policy that permits precisely
+     * the specified permissions.  If there is no current security
+     * manager, a temporary one is set for the duration of the
+     * Runnable.  We require that any security manager permit
+     * getPolicy/setPolicy.
+     */
+    public void runWithSecurityManagerWithPermissions(Runnable r,
+                                                      Permission... permissions) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            Policy savedPolicy = Policy.getPolicy();
+            try {
+                Policy.setPolicy(permissivePolicy());
+                System.setSecurityManager(new SecurityManager());
+                runWithSecurityManagerWithPermissions(r, permissions);
+            } finally {
+                System.setSecurityManager(null);
+                Policy.setPolicy(savedPolicy);
+            }
+        } else {
+            Policy savedPolicy = Policy.getPolicy();
+            AdjustablePolicy policy = new AdjustablePolicy(permissions);
+            Policy.setPolicy(policy);
+
+            try {
+                r.run();
+            } finally {
+                policy.addPermission(new SecurityPermission("setPolicy"));
+                Policy.setPolicy(savedPolicy);
+            }
+        }
+    }
+
+    /**
+     * Runs a runnable without any permissions.
+     */
+    public void runWithoutPermissions(Runnable r) {
+        runWithPermissions(r);
+    }
+
+    /**
+     * A security policy where new permissions can be dynamically added
+     * or all cleared.
+     */
+    public static class AdjustablePolicy extends java.security.Policy {
+        Permissions perms = new Permissions();
+        AdjustablePolicy(Permission... permissions) {
+            for (Permission permission : permissions)
+                perms.add(permission);
+        }
+        void addPermission(Permission perm) { perms.add(perm); }
+        void clearPermissions() { perms = new Permissions(); }
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+        public boolean implies(ProtectionDomain pd, Permission p) {
+            return perms.implies(p);
+        }
+        public void refresh() {}
+        public String toString() {
+            List<Permission> ps = new ArrayList<>();
+            for (Enumeration<Permission> e = perms.elements(); e.hasMoreElements();)
+                ps.add(e.nextElement());
+            return "AdjustablePolicy with permissions " + ps;
+        }
+    }
+
+    /**
+     * Returns a policy containing all the permissions we ever need.
+     */
+    public static Policy permissivePolicy() {
+        return new AdjustablePolicy
+            // Permissions j.u.c. needs directly
+            (new RuntimePermission("modifyThread"),
+             new RuntimePermission("getClassLoader"),
+             new RuntimePermission("setContextClassLoader"),
+             // Permissions needed to change permissions!
+             new SecurityPermission("getPolicy"),
+             new SecurityPermission("setPolicy"),
+             new RuntimePermission("setSecurityManager"),
+             // Permissions needed by the junit test harness
+             new RuntimePermission("accessDeclaredMembers"),
+             new PropertyPermission("*", "read"),
+             new java.io.FilePermission("<<ALL FILES>>", "read"));
+    }
+
+    /**
+     * Sleeps until the given time has elapsed.
+     * Throws AssertionFailedError if interrupted.
+     */
+    static void sleep(long millis) {
+        try {
+            delay(millis);
+        } catch (InterruptedException fail) {
+            AssertionFailedError afe =
+                new AssertionFailedError("Unexpected InterruptedException");
+            afe.initCause(fail);
+            throw afe;
+        }
+    }
+
+    /**
+     * Spin-waits up to the specified number of milliseconds for the given
+     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+     */
+    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
+        long startTime = 0L;
+        for (;;) {
+            Thread.State s = thread.getState();
+            if (s == Thread.State.BLOCKED ||
+                s == Thread.State.WAITING ||
+                s == Thread.State.TIMED_WAITING)
+                return;
+            else if (s == Thread.State.TERMINATED)
+                fail("Unexpected thread termination");
+            else if (startTime == 0L)
+                startTime = System.nanoTime();
+            else if (millisElapsedSince(startTime) > timeoutMillis) {
+                threadAssertTrue(thread.isAlive());
+                fail("timed out waiting for thread to enter wait state");
+            }
+            Thread.yield();
+        }
+    }
+
+    /**
+     * Spin-waits up to the specified number of milliseconds for the given
+     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
+     * and additionally satisfy the given condition.
+     */
+    void waitForThreadToEnterWaitState(
+        Thread thread, long timeoutMillis, Callable<Boolean> waitingForGodot) {
+        long startTime = 0L;
+        for (;;) {
+            Thread.State s = thread.getState();
+            if (s == Thread.State.BLOCKED ||
+                s == Thread.State.WAITING ||
+                s == Thread.State.TIMED_WAITING) {
+                try {
+                    if (waitingForGodot.call())
+                        return;
+                } catch (Throwable fail) { threadUnexpectedException(fail); }
+            }
+            else if (s == Thread.State.TERMINATED)
+                fail("Unexpected thread termination");
+            else if (startTime == 0L)
+                startTime = System.nanoTime();
+            else if (millisElapsedSince(startTime) > timeoutMillis) {
+                threadAssertTrue(thread.isAlive());
+                fail("timed out waiting for thread to enter wait state");
+            }
+            Thread.yield();
+        }
+    }
+
+    /**
+     * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
+     * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+     */
+    void waitForThreadToEnterWaitState(Thread thread) {
+        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
+    }
+
+    /**
+     * Spin-waits up to LONG_DELAY_MS milliseconds for the given thread to
+     * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
+     * and additionally satisfy the given condition.
+     */
+    void waitForThreadToEnterWaitState(
+        Thread thread, Callable<Boolean> waitingForGodot) {
+        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
+    }
+
+    /**
+     * Returns the number of milliseconds since time given by
+     * startNanoTime, which must have been previously returned from a
+     * call to {@link System#nanoTime()}.
+     */
+    static long millisElapsedSince(long startNanoTime) {
+        return NANOSECONDS.toMillis(System.nanoTime() - startNanoTime);
+    }
+
+//     void assertTerminatesPromptly(long timeoutMillis, Runnable r) {
+//         long startTime = System.nanoTime();
+//         try {
+//             r.run();
+//         } catch (Throwable fail) { threadUnexpectedException(fail); }
+//         if (millisElapsedSince(startTime) > timeoutMillis/2)
+//             throw new AssertionFailedError("did not return promptly");
+//     }
+
+//     void assertTerminatesPromptly(Runnable r) {
+//         assertTerminatesPromptly(LONG_DELAY_MS/2, r);
+//     }
+
+    /**
+     * Checks that timed f.get() returns the expected value, and does not
+     * wait for the timeout to elapse before returning.
+     */
+    <T> void checkTimedGet(Future<T> f, T expectedValue, long timeoutMillis) {
+        long startTime = System.nanoTime();
+        try {
+            assertEquals(expectedValue, f.get(timeoutMillis, MILLISECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        if (millisElapsedSince(startTime) > timeoutMillis/2)
+            throw new AssertionFailedError("timed get did not return promptly");
+    }
+
+    <T> void checkTimedGet(Future<T> f, T expectedValue) {
+        checkTimedGet(f, expectedValue, LONG_DELAY_MS);
+    }
+
+    /**
+     * Returns a new started daemon Thread running the given runnable.
+     */
+    Thread newStartedThread(Runnable runnable) {
+        Thread t = new Thread(runnable);
+        t.setDaemon(true);
+        t.start();
+        return t;
+    }
+
+    /**
+     * Waits for the specified time (in milliseconds) for the thread
+     * to terminate (using {@link Thread#join(long)}), else interrupts
+     * the thread (in the hope that it may terminate later) and fails.
+     */
+    void awaitTermination(Thread t, long timeoutMillis) {
+        try {
+            t.join(timeoutMillis);
+        } catch (InterruptedException fail) {
+            threadUnexpectedException(fail);
+        } finally {
+            if (t.getState() != Thread.State.TERMINATED) {
+                t.interrupt();
+                threadFail("timed out waiting for thread to terminate");
+            }
+        }
+    }
+
+    /**
+     * Waits for LONG_DELAY_MS milliseconds for the thread to
+     * terminate (using {@link Thread#join(long)}), else interrupts
+     * the thread (in the hope that it may terminate later) and fails.
+     */
+    void awaitTermination(Thread t) {
+        awaitTermination(t, LONG_DELAY_MS);
+    }
+
+    // Some convenient Runnable classes
+
+    public abstract class CheckedRunnable implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        public final void run() {
+            try {
+                realRun();
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+            }
+        }
+    }
+
+    public abstract class RunnableShouldThrow implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        final Class<?> exceptionClass;
+
+        <T extends Throwable> RunnableShouldThrow(Class<T> exceptionClass) {
+            this.exceptionClass = exceptionClass;
+        }
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow(exceptionClass.getSimpleName());
+            } catch (Throwable t) {
+                if (! exceptionClass.isInstance(t))
+                    threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class ThreadShouldThrow extends Thread {
+        protected abstract void realRun() throws Throwable;
+
+        final Class<?> exceptionClass;
+
+        <T extends Throwable> ThreadShouldThrow(Class<T> exceptionClass) {
+            this.exceptionClass = exceptionClass;
+        }
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow(exceptionClass.getSimpleName());
+            } catch (Throwable t) {
+                if (! exceptionClass.isInstance(t))
+                    threadUnexpectedException(t);
+            }
+        }
+    }
+
+    public abstract class CheckedInterruptedRunnable implements Runnable {
+        protected abstract void realRun() throws Throwable;
+
+        public final void run() {
+            try {
+                realRun();
+                threadShouldThrow("InterruptedException");
+            } catch (InterruptedException success) {
+                threadAssertFalse(Thread.interrupted());
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+            }
+        }
+    }
+
+    public abstract class CheckedCallable<T> implements Callable<T> {
+        protected abstract T realCall() throws Throwable;
+
+        public final T call() {
+            try {
+                return realCall();
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+                return null;
+            }
+        }
+    }
+
+    public abstract class CheckedInterruptedCallable<T>
+        implements Callable<T> {
+        protected abstract T realCall() throws Throwable;
+
+        public final T call() {
+            try {
+                T result = realCall();
+                threadShouldThrow("InterruptedException");
+                return result;
+            } catch (InterruptedException success) {
+                threadAssertFalse(Thread.interrupted());
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+            }
+            return null;
+        }
+    }
+
+    public static class NoOpRunnable implements Runnable {
+        public void run() {}
+    }
+
+    public static class NoOpCallable implements Callable {
+        public Object call() { return Boolean.TRUE; }
+    }
+
+    public static final String TEST_STRING = "a test string";
+
+    public static class StringTask implements Callable<String> {
+        final String value;
+        public StringTask() { this(TEST_STRING); }
+        public StringTask(String value) { this.value = value; }
+        public String call() { return value; }
+    }
+
+    public Callable<String> latchAwaitingStringTask(final CountDownLatch latch) {
+        return new CheckedCallable<String>() {
+            protected String realCall() {
+                try {
+                    latch.await();
+                } catch (InterruptedException quittingTime) {}
+                return TEST_STRING;
+            }};
+    }
+
+    public Runnable countDowner(final CountDownLatch latch) {
+        return new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                latch.countDown();
+            }};
+    }
+
+    class LatchAwaiter extends CheckedRunnable {
+        static final int NEW = 0;
+        static final int RUNNING = 1;
+        static final int DONE = 2;
+        final CountDownLatch latch;
+        int state = NEW;
+        LatchAwaiter(CountDownLatch latch) { this.latch = latch; }
+        public void realRun() throws InterruptedException {
+            state = 1;
+            await(latch);
+            state = 2;
+        }
+    }
+
+    public LatchAwaiter awaiter(CountDownLatch latch) {
+        return new LatchAwaiter(latch);
+    }
+
+    public void await(CountDownLatch latch, long timeoutMillis) {
+        try {
+            if (!latch.await(timeoutMillis, MILLISECONDS))
+                fail("timed out waiting for CountDownLatch for "
+                     + (timeoutMillis/1000) + " sec");
+        } catch (Throwable fail) {
+            threadUnexpectedException(fail);
+        }
+    }
+
+    public void await(CountDownLatch latch) {
+        await(latch, LONG_DELAY_MS);
+    }
+
+    public void await(Semaphore semaphore) {
+        try {
+            if (!semaphore.tryAcquire(LONG_DELAY_MS, MILLISECONDS))
+                fail("timed out waiting for Semaphore for "
+                     + (LONG_DELAY_MS/1000) + " sec");
+        } catch (Throwable fail) {
+            threadUnexpectedException(fail);
+        }
+    }
+
+//     /**
+//      * Spin-waits up to LONG_DELAY_MS until flag becomes true.
+//      */
+//     public void await(AtomicBoolean flag) {
+//         await(flag, LONG_DELAY_MS);
+//     }
+
+//     /**
+//      * Spin-waits up to the specified timeout until flag becomes true.
+//      */
+//     public void await(AtomicBoolean flag, long timeoutMillis) {
+//         long startTime = System.nanoTime();
+//         while (!flag.get()) {
+//             if (millisElapsedSince(startTime) > timeoutMillis)
+//                 throw new AssertionFailedError("timed out");
+//             Thread.yield();
+//         }
+//     }
+
+    public static class NPETask implements Callable<String> {
+        public String call() { throw new NullPointerException(); }
+    }
+
+    public static class CallableOne implements Callable<Integer> {
+        public Integer call() { return one; }
+    }
+
+    public class ShortRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            delay(SHORT_DELAY_MS);
+        }
+    }
+
+    public class ShortInterruptedRunnable extends CheckedInterruptedRunnable {
+        protected void realRun() throws InterruptedException {
+            delay(SHORT_DELAY_MS);
+        }
+    }
+
+    public class SmallRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            delay(SMALL_DELAY_MS);
+        }
+    }
+
+    public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
+            try {
+                delay(SMALL_DELAY_MS);
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public class SmallCallable extends CheckedCallable {
+        protected Object realCall() throws InterruptedException {
+            delay(SMALL_DELAY_MS);
+            return Boolean.TRUE;
+        }
+    }
+
+    public class MediumRunnable extends CheckedRunnable {
+        protected void realRun() throws Throwable {
+            delay(MEDIUM_DELAY_MS);
+        }
+    }
+
+    public class MediumInterruptedRunnable extends CheckedInterruptedRunnable {
+        protected void realRun() throws InterruptedException {
+            delay(MEDIUM_DELAY_MS);
+        }
+    }
+
+    public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
+        return new CheckedRunnable() {
+            protected void realRun() {
+                try {
+                    delay(timeoutMillis);
+                } catch (InterruptedException ok) {}
+            }};
+    }
+
+    public class MediumPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
+            try {
+                delay(MEDIUM_DELAY_MS);
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public class LongPossiblyInterruptedRunnable extends CheckedRunnable {
+        protected void realRun() {
+            try {
+                delay(LONG_DELAY_MS);
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    /**
+     * For use as ThreadFactory in constructors
+     */
+    public static class SimpleThreadFactory implements ThreadFactory {
+        public Thread newThread(Runnable r) {
+            return new Thread(r);
+        }
+    }
+
+    public interface TrackedRunnable extends Runnable {
+        boolean isDone();
+    }
+
+    public static TrackedRunnable trackedRunnable(final long timeoutMillis) {
+        return new TrackedRunnable() {
+                private volatile boolean done = false;
+                public boolean isDone() { return done; }
+                public void run() {
+                    try {
+                        delay(timeoutMillis);
+                        done = true;
+                    } catch (InterruptedException ok) {}
+                }
+            };
+    }
+
+    public static class TrackedShortRunnable implements Runnable {
+        public volatile boolean done = false;
+        public void run() {
+            try {
+                delay(SHORT_DELAY_MS);
+                done = true;
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public static class TrackedSmallRunnable implements Runnable {
+        public volatile boolean done = false;
+        public void run() {
+            try {
+                delay(SMALL_DELAY_MS);
+                done = true;
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public static class TrackedMediumRunnable implements Runnable {
+        public volatile boolean done = false;
+        public void run() {
+            try {
+                delay(MEDIUM_DELAY_MS);
+                done = true;
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public static class TrackedLongRunnable implements Runnable {
+        public volatile boolean done = false;
+        public void run() {
+            try {
+                delay(LONG_DELAY_MS);
+                done = true;
+            } catch (InterruptedException ok) {}
+        }
+    }
+
+    public static class TrackedNoOpRunnable implements Runnable {
+        public volatile boolean done = false;
+        public void run() {
+            done = true;
+        }
+    }
+
+    public static class TrackedCallable implements Callable {
+        public volatile boolean done = false;
+        public Object call() {
+            try {
+                delay(SMALL_DELAY_MS);
+                done = true;
+            } catch (InterruptedException ok) {}
+            return Boolean.TRUE;
+        }
+    }
+
+    /**
+     * Analog of CheckedRunnable for RecursiveAction
+     */
+    public abstract class CheckedRecursiveAction extends RecursiveAction {
+        protected abstract void realCompute() throws Throwable;
+
+        @Override protected final void compute() {
+            try {
+                realCompute();
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+            }
+        }
+    }
+
+    /**
+     * Analog of CheckedCallable for RecursiveTask
+     */
+    public abstract class CheckedRecursiveTask<T> extends RecursiveTask<T> {
+        protected abstract T realCompute() throws Throwable;
+
+        @Override protected final T compute() {
+            try {
+                return realCompute();
+            } catch (Throwable fail) {
+                threadUnexpectedException(fail);
+                return null;
+            }
+        }
+    }
+
+    /**
+     * For use as RejectedExecutionHandler in constructors
+     */
+    public static class NoOpREHandler implements RejectedExecutionHandler {
+        public void rejectedExecution(Runnable r,
+                                      ThreadPoolExecutor executor) {}
+    }
+
+    /**
+     * A CyclicBarrier that uses timed await and fails with
+     * AssertionFailedErrors instead of throwing checked exceptions.
+     */
+    public static class CheckedBarrier extends CyclicBarrier {
+        public CheckedBarrier(int parties) { super(parties); }
+
+        public int await() {
+            try {
+                return super.await(2 * LONG_DELAY_MS, MILLISECONDS);
+            } catch (TimeoutException timedOut) {
+                throw new AssertionFailedError("timed out");
+            } catch (Exception fail) {
+                AssertionFailedError afe =
+                    new AssertionFailedError("Unexpected exception: " + fail);
+                afe.initCause(fail);
+                throw afe;
+            }
+        }
+    }
+
+    void checkEmpty(BlockingQueue q) {
+        try {
+            assertTrue(q.isEmpty());
+            assertEquals(0, q.size());
+            assertNull(q.peek());
+            assertNull(q.poll());
+            assertNull(q.poll(0, MILLISECONDS));
+            assertEquals(q.toString(), "[]");
+            assertTrue(Arrays.equals(q.toArray(), new Object[0]));
+            assertFalse(q.iterator().hasNext());
+            try {
+                q.element();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                q.iterator().next();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                q.remove();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+    }
+
+    void assertSerialEquals(Object x, Object y) {
+        assertTrue(Arrays.equals(serialBytes(x), serialBytes(y)));
+    }
+
+    void assertNotSerialEquals(Object x, Object y) {
+        assertFalse(Arrays.equals(serialBytes(x), serialBytes(y)));
+    }
+
+    byte[] serialBytes(Object o) {
+        try {
+            ByteArrayOutputStream bos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(bos);
+            oos.writeObject(o);
+            oos.flush();
+            oos.close();
+            return bos.toByteArray();
+        } catch (Throwable fail) {
+            threadUnexpectedException(fail);
+            return new byte[0];
+        }
+    }
+
+    void assertImmutable(final Object o) {
+        if (o instanceof Collection) {
+            assertThrows(
+                UnsupportedOperationException.class,
+                new Runnable() { public void run() {
+                        ((Collection) o).add(null);}});
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    <T> T serialClone(T o) {
+        try {
+            ObjectInputStream ois = new ObjectInputStream
+                (new ByteArrayInputStream(serialBytes(o)));
+            T clone = (T) ois.readObject();
+            if (o == clone) assertImmutable(o);
+            assertSame(o.getClass(), clone.getClass());
+            return clone;
+        } catch (Throwable fail) {
+            threadUnexpectedException(fail);
+            return null;
+        }
+    }
+
+    /**
+     * A version of serialClone that leaves error handling (for
+     * e.g. NotSerializableException) up to the caller.
+     */
+    @SuppressWarnings("unchecked")
+    <T> T serialClonePossiblyFailing(T o)
+        throws ReflectiveOperationException, java.io.IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(bos);
+        oos.writeObject(o);
+        oos.flush();
+        oos.close();
+        ObjectInputStream ois = new ObjectInputStream
+            (new ByteArrayInputStream(bos.toByteArray()));
+        T clone = (T) ois.readObject();
+        if (o == clone) assertImmutable(o);
+        assertSame(o.getClass(), clone.getClass());
+        return clone;
+    }
+
+    /**
+     * If o implements Cloneable and has a public clone method,
+     * returns a clone of o, else null.
+     */
+    @SuppressWarnings("unchecked")
+    <T> T cloneableClone(T o) {
+        if (!(o instanceof Cloneable)) return null;
+        final T clone;
+        try {
+            clone = (T) o.getClass().getMethod("clone").invoke(o);
+        } catch (NoSuchMethodException ok) {
+            return null;
+        } catch (ReflectiveOperationException unexpected) {
+            throw new Error(unexpected);
+        }
+        assertNotSame(o, clone); // not 100% guaranteed by spec
+        assertSame(o.getClass(), clone.getClass());
+        return clone;
+    }
+
+    public void assertThrows(Class<? extends Throwable> expectedExceptionClass,
+                             Runnable... throwingActions) {
+        for (Runnable throwingAction : throwingActions) {
+            boolean threw = false;
+            try { throwingAction.run(); }
+            catch (Throwable t) {
+                threw = true;
+                if (!expectedExceptionClass.isInstance(t)) {
+                    AssertionFailedError afe =
+                        new AssertionFailedError
+                        ("Expected " + expectedExceptionClass.getName() +
+                         ", got " + t.getClass().getName());
+                    afe.initCause(t);
+                    threadUnexpectedException(afe);
+                }
+            }
+            if (!threw)
+                shouldThrow(expectedExceptionClass.getName());
+        }
+    }
+
+    public void assertIteratorExhausted(Iterator<?> it) {
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertFalse(it.hasNext());
+    }
+
+    public <T> Callable<T> callableThrowing(final Exception ex) {
+        return new Callable<T>() { public T call() throws Exception { throw ex; }};
+    }
+
+    public Runnable runnableThrowing(final RuntimeException ex) {
+        return new Runnable() { public void run() { throw ex; }};
+    }
+
+    /** A reusable thread pool to be shared by tests. */
+    static final ExecutorService cachedThreadPool =
+        new ThreadPoolExecutor(0, Integer.MAX_VALUE,
+                               1000L, MILLISECONDS,
+                               new SynchronousQueue<Runnable>());
+
+    static <T> void shuffle(T[] array) {
+        Collections.shuffle(Arrays.asList(array), ThreadLocalRandom.current());
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDeque8Test.java b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDeque8Test.java
new file mode 100644
index 0000000..29b2704
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDeque8Test.java
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.Spliterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LinkedBlockingDeque8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(LinkedBlockingDeque8Test.class);
+    }
+
+    /**
+     * Spliterator.getComparator always throws IllegalStateException
+     */
+    public void testSpliterator_getComparator() {
+        assertThrows(IllegalStateException.class,
+                     () -> new LinkedBlockingDeque().spliterator().getComparator());
+    }
+
+    /**
+     * Spliterator characteristics are as advertised
+     */
+    public void testSpliterator_characteristics() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        Spliterator s = q.spliterator();
+        int characteristics = s.characteristics();
+        int required = Spliterator.CONCURRENT
+            | Spliterator.NONNULL
+            | Spliterator.ORDERED;
+        assertEquals(required, characteristics & required);
+        assertTrue(s.hasCharacteristics(required));
+        assertEquals(0, characteristics
+                     & (Spliterator.DISTINCT
+                        | Spliterator.IMMUTABLE
+                        | Spliterator.SORTED));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java
new file mode 100644
index 0000000..c8cc4a1
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingDequeTest.java
@@ -0,0 +1,1859 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingDeque;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingDeque;
+
+import junit.framework.Test;
+
+public class LinkedBlockingDequeTest extends JSR166TestCase {
+
+    public static class Unbounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingDeque();
+        }
+    }
+
+    public static class Bounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingDeque(SIZE);
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return LinkedBlockingDeque.class; }
+            public Collection emptyCollection() { return new LinkedBlockingDeque(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(LinkedBlockingDequeTest.class,
+                            new Unbounded().testSuite(),
+                            new Bounded().testSuite(),
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Returns a new deque of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private LinkedBlockingDeque<Integer> populatedDeque(int n) {
+        LinkedBlockingDeque<Integer> q =
+            new LinkedBlockingDeque<Integer>(n);
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; i++)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peekFirst());
+        assertEquals((Integer) (n - 1), q.peekLast());
+        return q;
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.removeFirst();
+        q.removeFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.removeFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offerFirst(null) throws NullPointerException
+     */
+    public void testOfferFirstNull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        try {
+            q.offerFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * offerLast(null) throws NullPointerException
+     */
+    public void testOfferLastNull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        try {
+            q.offerLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * OfferFirst succeeds
+     */
+    public void testOfferFirst() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.offerFirst(new Integer(0)));
+        assertTrue(q.offerFirst(new Integer(1)));
+    }
+
+    /**
+     * OfferLast succeeds
+     */
+    public void testOfferLast() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        assertTrue(q.offerLast(new Integer(0)));
+        assertTrue(q.offerLast(new Integer(1)));
+    }
+
+    /**
+     * pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     * peekFirst returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * peekLast returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * getFirst() returns first element, or throws NSEE if empty
+     */
+    public void testFirstElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * getLast() returns last element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirst() removes first element, or throws NSEE if empty
+     */
+    public void testRemoveFirst() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.removeFirst());
+        }
+        try {
+            q.removeFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * removeLast() removes last element, or throws NSEE if empty
+     */
+    public void testRemoveLast() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.removeLast());
+        }
+        try {
+            q.removeLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * peekFirst returns element inserted with addFirst
+     */
+    public void testAddFirst() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.addFirst(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * peekLast returns element inserted with addLast
+     */
+    public void testAddLast() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.addLast(four);
+        assertSame(four, q.peekLast());
+    }
+
+    /**
+     * A new deque has the indicated capacity, or Integer.MAX_VALUE if
+     * none given
+     */
+    public void testConstructor1() {
+        assertEquals(SIZE, new LinkedBlockingDeque(SIZE).remainingCapacity());
+        assertEquals(Integer.MAX_VALUE, new LinkedBlockingDeque().remainingCapacity());
+    }
+
+    /**
+     * Constructor throws IllegalArgumentException if capacity argument nonpositive
+     */
+    public void testConstructor2() {
+        try {
+            new LinkedBlockingDeque(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Initializing from null Collection throws NullPointerException
+     */
+    public void testConstructor3() {
+        try {
+            new LinkedBlockingDeque(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NullPointerException
+     */
+    public void testConstructor4() {
+        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            new LinkedBlockingDeque(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws
+     * NullPointerException
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            new LinkedBlockingDeque(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Deque contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = i;
+        LinkedBlockingDeque q = new LinkedBlockingDeque(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * Deque transitions from empty to full when elements added
+     */
+    public void testEmptyFull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        assertTrue(q.isEmpty());
+        assertEquals("should have room for 2", 2, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertFalse(q.offer(three));
+    }
+
+    /**
+     * remainingCapacity decreases on add, increases on remove
+     */
+    public void testRemainingCapacity() {
+        BlockingQueue q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remainingCapacity());
+            assertEquals(SIZE, q.size() + q.remainingCapacity());
+            assertEquals(i, q.remove());
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.remainingCapacity());
+            assertEquals(SIZE, q.size() + q.remainingCapacity());
+            assertTrue(q.add(i));
+        }
+    }
+
+    /**
+     * push(null) throws NPE
+     */
+    public void testPushNull() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+        try {
+            q.push(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * push succeeds if not full; throws ISE if full
+     */
+    public void testPush() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.push(x);
+            assertEquals(x, q.peek());
+        }
+        assertEquals(0, q.remainingCapacity());
+        try {
+            q.push(new Integer(SIZE));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * peekFirst returns element inserted with push
+     */
+    public void testPushWithPeek() {
+        LinkedBlockingDeque q = populatedDeque(3);
+        q.pollLast();
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * pop removes next element, or throws NSEE if empty
+     */
+    public void testPop() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * Offer succeeds if not full; fails if full
+     */
+    public void testOffer() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(1);
+        assertTrue(q.offer(zero));
+        assertFalse(q.offer(one));
+    }
+
+    /**
+     * add succeeds if not full; throws ISE if full
+     */
+    public void testAdd() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertTrue(q.add(new Integer(i)));
+        assertEquals(0, q.remainingCapacity());
+        try {
+            q.add(new Integer(SIZE));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            q.addAll(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll throws IllegalStateException if not enough room
+     */
+    public void testAddAll4() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE - 1);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            q.addAll(elements);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * Deque contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.put(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly if full
+     */
+    public void testBlockingPut() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly waiting for take when full
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity; i++)
+                    q.put(i);
+                pleaseTake.countDown();
+                q.put(86);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(0, q.take());
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offer times out if full and elements not taken
+     */
+    public void testTimedOffer() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                long startTime = System.nanoTime();
+                assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTake() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
+    }
+
+    /**
+     * take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(i, q.poll(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedDeque(SIZE);
+        final CountDownLatch aboutToWait = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                }
+                aboutToWait.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }
+            }});
+
+        aboutToWait.await();
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * putFirst(null) throws NPE
+     */
+    public void testPutFirstNull() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        try {
+            q.putFirst(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * all elements successfully putFirst are contained
+     */
+    public void testPutFirst() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.putFirst(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putFirst blocks interruptibly if full
+     */
+    public void testBlockingPutFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.putFirst(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.putFirst(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.putFirst(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putFirst blocks interruptibly waiting for take when full
+     */
+    public void testPutFirstWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity; i++)
+                    q.putFirst(i);
+                pleaseTake.countDown();
+                q.putFirst(86);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.putFirst(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(capacity - 1, q.take());
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offerFirst times out if full and elements not taken
+     */
+    public void testTimedOfferFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.putFirst(new Object());
+                q.putFirst(new Object());
+                long startTime = System.nanoTime();
+                assertFalse(q.offerFirst(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offerFirst(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTakeFirst() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.takeFirst());
+        }
+    }
+
+    /**
+     * takeFirst() blocks interruptibly when empty
+     */
+    public void testTakeFirstFromEmptyBlocksInterruptibly() {
+        final BlockingDeque q = new LinkedBlockingDeque();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                threadStarted.countDown();
+                try {
+                    q.takeFirst();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(threadStarted);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * takeFirst() throws InterruptedException immediately if interrupted
+     * before waiting
+     */
+    public void testTakeFirstFromEmptyAfterInterrupt() {
+        final BlockingDeque q = new LinkedBlockingDeque();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                try {
+                    q.takeFirst();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * takeLast() blocks interruptibly when empty
+     */
+    public void testTakeLastFromEmptyBlocksInterruptibly() {
+        final BlockingDeque q = new LinkedBlockingDeque();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                threadStarted.countDown();
+                try {
+                    q.takeLast();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(threadStarted);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * takeLast() throws InterruptedException immediately if interrupted
+     * before waiting
+     */
+    public void testTakeLastFromEmptyAfterInterrupt() {
+        final BlockingDeque q = new LinkedBlockingDeque();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                try {
+                    q.takeLast();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * takeFirst removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTakeFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.takeFirst());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.takeFirst();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.takeFirst();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed pollFirst with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollFirst0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst(0, MILLISECONDS));
+        }
+        assertNull(q.pollFirst(0, MILLISECONDS));
+    }
+
+    /**
+     * timed pollFirst with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollFirst() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed pollFirst throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPollFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed pollFirst before a delayed offerFirst fails; after offerFirst succeeds;
+     * on interruption throws
+     */
+    public void testTimedPollFirstWithOfferFirst() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CheckedBarrier barrier = new CheckedBarrier(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertNull(q.pollFirst(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+                barrier.await();
+
+                assertSame(zero, q.pollFirst(LONG_DELAY_MS, MILLISECONDS));
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+
+                barrier.await();
+                try {
+                    q.pollFirst(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        barrier.await();
+        long startTime = System.nanoTime();
+        assertTrue(q.offerFirst(zero, LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        barrier.await();
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * putLast(null) throws NPE
+     */
+    public void testPutLastNull() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        try {
+            q.putLast(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * all elements successfully putLast are contained
+     */
+    public void testPutLast() throws InterruptedException {
+        LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.putLast(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putLast blocks interruptibly if full
+     */
+    public void testBlockingPutLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.putLast(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.putLast(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.putLast(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * putLast blocks interruptibly waiting for take when full
+     */
+    public void testPutLastWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(capacity);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity; i++)
+                    q.putLast(i);
+                pleaseTake.countDown();
+                q.putLast(86);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.putLast(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(0, q.take());
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offerLast times out if full and elements not taken
+     */
+    public void testTimedOfferLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.putLast(new Object());
+                q.putLast(new Object());
+                long startTime = System.nanoTime();
+                assertFalse(q.offerLast(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offerLast(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * takeLast retrieves elements in FIFO order
+     */
+    public void testTakeLast() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i - 1, q.takeLast());
+        }
+    }
+
+    /**
+     * takeLast removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTakeLast() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(SIZE - i - 1, q.takeLast());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.takeLast();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.takeLast();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timed pollLast with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollLast0() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i - 1, q.pollLast(0, MILLISECONDS));
+        }
+        assertNull(q.pollLast(0, MILLISECONDS));
+    }
+
+    /**
+     * timed pollLast with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPollLast() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(SIZE - i - 1, q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.pollLast(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed pollLast throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPollLast() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(SIZE - i - 1,
+                                 q.pollLast(LONG_DELAY_MS, MILLISECONDS));
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.pollLast(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.pollLast(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * timed poll before a delayed offerLast fails; after offerLast succeeds;
+     * on interruption throws
+     */
+    public void testTimedPollWithOfferLast() throws InterruptedException {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CheckedBarrier barrier = new CheckedBarrier(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+                barrier.await();
+
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                barrier.await();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        barrier.await();
+        long startTime = System.nanoTime();
+        assertTrue(q.offerLast(zero, LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+        barrier.await();
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            q.poll();
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(SIZE, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        LinkedBlockingDeque p = new LinkedBlockingDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        LinkedBlockingDeque p = populatedDeque(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            LinkedBlockingDeque q = populatedDeque(SIZE);
+            LinkedBlockingDeque p = populatedDeque(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements in FIFO order
+     */
+    public void testToArray() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() {
+        LinkedBlockingDeque<Integer> q = populatedDeque(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.remove());
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() throws InterruptedException {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+
+        it = q.iterator();
+        for (i = 0; it.hasNext(); i++)
+            assertEquals(it.next(), q.take());
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        Deque c = new LinkedBlockingDeque();
+        assertIteratorExhausted(c.iterator());
+        assertIteratorExhausted(c.descendingIterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(two);
+        q.add(one);
+        q.add(three);
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        assertEquals(0, q.remainingCapacity());
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+        assertEquals(0, q.size());
+    }
+
+    /**
+     * Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            int k = 0;
+            for (Iterator it = q.descendingIterator(); it.hasNext();) {
+                assertEquals(++k, it.next());
+            }
+
+            assertEquals(3, k);
+            q.remove();
+            q.remove();
+            q.remove();
+        }
+    }
+
+    /**
+     * descendingIterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int iters = 0; iters < 100; ++iters) {
+            q.add(new Integer(3));
+            q.add(new Integer(2));
+            q.add(new Integer(1));
+            Iterator it = q.descendingIterator();
+            assertEquals(it.next(), new Integer(1));
+            it.remove();
+            assertEquals(it.next(), new Integer(2));
+            it = q.descendingIterator();
+            assertEquals(it.next(), new Integer(2));
+            assertEquals(it.next(), new Integer(3));
+            it.remove();
+            assertFalse(it.hasNext());
+            q.remove();
+        }
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        q.add(one);
+        q.add(two);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
+    }
+
+    /**
+     * timed poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor() {
+        final LinkedBlockingDeque q = new LinkedBlockingDeque(2);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * A deserialized serialized deque has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedDeque(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * drainTo(c) empties deque into another collection c
+     */
+    public void testDrainTo() {
+        LinkedBlockingDeque q = populatedDeque(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(SIZE, l.size());
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), new Integer(i));
+    }
+
+    /**
+     * drainTo empties full deque, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final LinkedBlockingDeque q = populatedDeque(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE + 1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        LinkedBlockingDeque q = new LinkedBlockingDeque();
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(k, l.size());
+            assertEquals(SIZE - k, q.size());
+            for (int j = 0; j < k; ++j)
+                assertEquals(l.get(j), new Integer(j));
+            do {} while (q.poll() != null);
+        }
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Deque<?>[] qs = {
+            new LinkedBlockingDeque<Object>(),
+            populatedDeque(2),
+        };
+
+        for (Deque<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+            assertFalse(q.removeFirstOccurrence(null));
+            assertFalse(q.removeLastOccurrence(null));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueue8Test.java b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueue8Test.java
new file mode 100644
index 0000000..4a6e42a
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueue8Test.java
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.Spliterator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LinkedBlockingQueue8Test extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(LinkedBlockingQueue8Test.class);
+    }
+
+    /**
+     * Spliterator.getComparator always throws IllegalStateException
+     */
+    public void testSpliterator_getComparator() {
+        assertThrows(IllegalStateException.class,
+                     () -> new LinkedBlockingQueue().spliterator().getComparator());
+    }
+
+    /**
+     * Spliterator characteristics are as advertised
+     */
+    public void testSpliterator_characteristics() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
+        Spliterator s = q.spliterator();
+        int characteristics = s.characteristics();
+        int required = Spliterator.CONCURRENT
+            | Spliterator.NONNULL
+            | Spliterator.ORDERED;
+        assertEquals(required, characteristics & required);
+        assertTrue(s.hasCharacteristics(required));
+        assertEquals(0, characteristics
+                     & (Spliterator.DISTINCT
+                        | Spliterator.IMMUTABLE
+                        | Spliterator.SORTED));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java
new file mode 100644
index 0000000..4580f86
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedBlockingQueueTest.java
@@ -0,0 +1,899 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import junit.framework.Test;
+
+public class LinkedBlockingQueueTest extends JSR166TestCase {
+
+    public static class Unbounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingQueue();
+        }
+    }
+
+    public static class Bounded extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedBlockingQueue(SIZE);
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return LinkedBlockingQueue.class; }
+            public Collection emptyCollection() { return new LinkedBlockingQueue(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(LinkedBlockingQueueTest.class,
+                            new Unbounded().testSuite(),
+                            new Bounded().testSuite(),
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private LinkedBlockingQueue<Integer> populatedQueue(int n) {
+        LinkedBlockingQueue<Integer> q =
+            new LinkedBlockingQueue<Integer>(n);
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; i++)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peek());
+        return q;
+    }
+
+    /**
+     * A new queue has the indicated capacity, or Integer.MAX_VALUE if
+     * none given
+     */
+    public void testConstructor1() {
+        assertEquals(SIZE, new LinkedBlockingQueue(SIZE).remainingCapacity());
+        assertEquals(Integer.MAX_VALUE, new LinkedBlockingQueue().remainingCapacity());
+    }
+
+    /**
+     * Constructor throws IllegalArgumentException if capacity argument nonpositive
+     */
+    public void testConstructor2() {
+        try {
+            new LinkedBlockingQueue(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Initializing from null Collection throws NullPointerException
+     */
+    public void testConstructor3() {
+        try {
+            new LinkedBlockingQueue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NullPointerException
+     */
+    public void testConstructor4() {
+        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            new LinkedBlockingQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws
+     * NullPointerException
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            new LinkedBlockingQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingQueue q = new LinkedBlockingQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * Queue transitions from empty to full when elements added
+     */
+    public void testEmptyFull() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+        assertTrue(q.isEmpty());
+        assertEquals("should have room for 2", 2, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        assertFalse(q.isEmpty());
+        assertEquals(0, q.remainingCapacity());
+        assertFalse(q.offer(three));
+    }
+
+    /**
+     * remainingCapacity decreases on add, increases on remove
+     */
+    public void testRemainingCapacity() {
+        BlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remainingCapacity());
+            assertEquals(SIZE, q.size() + q.remainingCapacity());
+            assertEquals(i, q.remove());
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.remainingCapacity());
+            assertEquals(SIZE, q.size() + q.remainingCapacity());
+            assertTrue(q.add(i));
+        }
+    }
+
+    /**
+     * Offer succeeds if not full; fails if full
+     */
+    public void testOffer() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(1);
+        assertTrue(q.offer(zero));
+        assertFalse(q.offer(one));
+    }
+
+    /**
+     * add succeeds if not full; throws IllegalStateException if full
+     */
+    public void testAdd() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertTrue(q.add(new Integer(i)));
+        assertEquals(0, q.remainingCapacity());
+        try {
+            q.add(new Integer(SIZE));
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * addAll(this) throws IllegalArgumentException
+     */
+    public void testAddAllSelf() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            q.addAll(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll throws IllegalStateException if not enough room
+     */
+    public void testAddAll4() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE - 1);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            q.addAll(elements);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() throws InterruptedException {
+        LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.put(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly if full
+     */
+    public void testBlockingPut() throws InterruptedException {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i)
+                    q.put(i);
+                assertEquals(SIZE, q.size());
+                assertEquals(0, q.remainingCapacity());
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(SIZE, q.size());
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly waiting for take when full
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final int capacity = 2;
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < capacity; i++)
+                    q.put(i);
+                pleaseTake.countDown();
+                q.put(86);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        assertEquals(0, q.take());
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offer times out if full and elements not taken
+     */
+    public void testTimedOffer() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Object());
+                q.put(new Object());
+                long startTime = System.nanoTime();
+                assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTake() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
+    }
+
+    /**
+     * Take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final BlockingQueue q = populatedQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        LinkedBlockingQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedQueue(SIZE);
+        final CountDownLatch aboutToWait = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                }
+                aboutToWait.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }
+            }});
+
+        await(aboutToWait);
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * An add following remove(x) succeeds
+     */
+    public void testRemoveElementAndAdd() throws InterruptedException {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
+        assertTrue(q.add(new Integer(1)));
+        assertTrue(q.add(new Integer(2)));
+        assertTrue(q.remove(new Integer(1)));
+        assertTrue(q.remove(new Integer(2)));
+        assertTrue(q.add(new Integer(3)));
+        assertNotNull(q.take());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(SIZE, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        LinkedBlockingQueue p = new LinkedBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        LinkedBlockingQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            LinkedBlockingQueue q = populatedQueue(SIZE);
+            LinkedBlockingQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements in FIFO order
+     */
+    public void testToArray() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() throws InterruptedException {
+        LinkedBlockingQueue<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.poll());
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() throws InterruptedException {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+
+        it = q.iterator();
+        for (i = 0; it.hasNext(); i++)
+            assertEquals(it.next(), q.take());
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new LinkedBlockingQueue().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+        q.add(two);
+        q.add(one);
+        q.add(three);
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        assertEquals(0, q.remainingCapacity());
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(3);
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+        assertEquals(0, q.size());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+        q.add(one);
+        q.add(two);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(three));
+                    threadsStarted.await();
+                    assertTrue(q.offer(three, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
+    }
+
+    /**
+     * timed poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor() {
+        final LinkedBlockingQueue q = new LinkedBlockingQueue(2);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * drainTo(c) empties queue into another collection c
+     */
+    public void testDrainTo() {
+        LinkedBlockingQueue q = populatedQueue(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(SIZE, l.size());
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), new Integer(i));
+    }
+
+    /**
+     * drainTo empties full queue, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final LinkedBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(new Integer(SIZE + 1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        LinkedBlockingQueue q = new LinkedBlockingQueue();
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(k, l.size());
+            assertEquals(SIZE - k, q.size());
+            for (int j = 0; j < k; ++j)
+                assertEquals(l.get(j), new Integer(j));
+            do {} while (q.poll() != null);
+        }
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?>[] qs = {
+            new LinkedBlockingQueue<Object>(),
+            populatedQueue(2),
+        };
+
+        for (Collection<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedListTest.java b/ojluni/src/test/java/util/concurrent/tck/LinkedListTest.java
new file mode 100644
index 0000000..b0afd4f
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedListTest.java
@@ -0,0 +1,687 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.NoSuchElementException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LinkedListTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return LinkedList.class; }
+            public Collection emptyCollection() { return new LinkedList(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return true; }
+        }
+        class SubListImplementation extends Implementation {
+            public Collection emptyCollection() {
+                return new LinkedList().subList(0, 0);
+            }
+        }
+        return newTestSuite(
+                LinkedListTest.class,
+                CollectionTest.testSuite(new Implementation()),
+                CollectionTest.testSuite(new SubListImplementation()));
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private LinkedList<Integer> populatedQueue(int n) {
+        LinkedList<Integer> q = new LinkedList<>();
+        assertTrue(q.isEmpty());
+        for (int i = 0; i < n; ++i)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peekFirst());
+        assertEquals((Integer) (n - 1), q.peekLast());
+        return q;
+    }
+
+    /**
+     * new queue is empty
+     */
+    public void testConstructor1() {
+        assertEquals(0, new LinkedList().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new LinkedList((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = i;
+        LinkedList q = new LinkedList(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        LinkedList q = new LinkedList();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.remove();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offer(null) succeeds
+     */
+    public void testOfferNull() {
+        LinkedList q = new LinkedList();
+        q.offer(null);
+        assertNull(q.get(0));
+        assertTrue(q.contains(null));
+    }
+
+    /**
+     * Offer succeeds
+     */
+    public void testOffer() {
+        LinkedList q = new LinkedList();
+        assertTrue(q.offer(new Integer(0)));
+        assertTrue(q.offer(new Integer(1)));
+    }
+
+    /**
+     * add succeeds
+     */
+    public void testAdd() {
+        LinkedList q = new LinkedList();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new Integer(i)));
+        }
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        LinkedList q = new LinkedList();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = i;
+        LinkedList q = new LinkedList();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * addAll with too large an index throws IOOBE
+     */
+    public void testAddAll2_IndexOutOfBoundsException() {
+        LinkedList l = new LinkedList();
+        l.add(new Object());
+        LinkedList m = new LinkedList();
+        m.add(new Object());
+        try {
+            l.addAll(4,m);
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {}
+    }
+
+    /**
+     * addAll with negative index throws IOOBE
+     */
+    public void testAddAll4_BadIndex() {
+        LinkedList l = new LinkedList();
+        l.add(new Object());
+        LinkedList m = new LinkedList();
+        m.add(new Object());
+        try {
+            l.addAll(-1,m);
+            shouldThrow();
+        } catch (IndexOutOfBoundsException success) {}
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove((Integer)i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove((Integer)i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove((Integer)(i + 1)));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        LinkedList q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        LinkedList q = populatedQueue(SIZE);
+        LinkedList p = new LinkedList();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            assertTrue(p.add(new Integer(i)));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        LinkedList q = populatedQueue(SIZE);
+        LinkedList p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            LinkedList q = populatedQueue(SIZE);
+            LinkedList p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements in FIFO order
+     */
+    public void testToArray() {
+        LinkedList q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() {
+        LinkedList<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.poll());
+    }
+
+    /**
+     * toArray(null) throws NullPointerException
+     */
+    public void testToArray_NullArg() {
+        LinkedList l = new LinkedList();
+        l.add(new Object());
+        try {
+            l.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        LinkedList l = new LinkedList();
+        l.add(new Integer(5));
+        try {
+            l.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        LinkedList q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new LinkedList().iterator());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final LinkedList q = new LinkedList();
+        q.add(new Integer(1));
+        q.add(new Integer(2));
+        q.add(new Integer(3));
+        int k = 0;
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final LinkedList q = new LinkedList();
+        q.add(new Integer(1));
+        q.add(new Integer(2));
+        q.add(new Integer(3));
+        Iterator it = q.iterator();
+        assertEquals(1, it.next());
+        it.remove();
+        it = q.iterator();
+        assertEquals(2, it.next());
+        assertEquals(3, it.next());
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * Descending iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        LinkedList q = populatedQueue(SIZE);
+        int i = 0;
+        Iterator it = q.descendingIterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+        assertFalse(it.hasNext());
+        try {
+            it.next();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * Descending iterator ordering is reverse FIFO
+     */
+    public void testDescendingIteratorOrdering() {
+        final LinkedList q = new LinkedList();
+        q.add(new Integer(3));
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        int k = 0;
+        for (Iterator it = q.descendingIterator(); it.hasNext();) {
+            assertEquals(++k, it.next());
+        }
+
+        assertEquals(3, k);
+    }
+
+    /**
+     * descendingIterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final LinkedList q = new LinkedList();
+        q.add(three);
+        q.add(two);
+        q.add(one);
+        Iterator it = q.descendingIterator();
+        it.next();
+        it.remove();
+        it = q.descendingIterator();
+        assertSame(it.next(), two);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        LinkedList q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * peek returns element inserted with addFirst
+     */
+    public void testAddFirst() {
+        LinkedList q = populatedQueue(3);
+        q.addFirst(four);
+        assertSame(four, q.peek());
+    }
+
+    /**
+     * peekFirst returns element inserted with push
+     */
+    public void testPush() {
+        LinkedList q = populatedQueue(3);
+        q.push(four);
+        assertSame(four, q.peekFirst());
+    }
+
+    /**
+     * pop removes next element, or throws NSEE if empty
+     */
+    public void testPop() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pop());
+        }
+        try {
+            q.pop();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * OfferFirst succeeds
+     */
+    public void testOfferFirst() {
+        LinkedList q = new LinkedList();
+        assertTrue(q.offerFirst(new Integer(0)));
+        assertTrue(q.offerFirst(new Integer(1)));
+    }
+
+    /**
+     * OfferLast succeeds
+     */
+    public void testOfferLast() {
+        LinkedList q = new LinkedList();
+        assertTrue(q.offerLast(new Integer(0)));
+        assertTrue(q.offerLast(new Integer(1)));
+    }
+
+    /**
+     * pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollLast());
+    }
+
+    /**
+     * peekFirst returns next element, or null if empty
+     */
+    public void testPeekFirst() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peekFirst());
+            assertEquals(i, q.pollFirst());
+            assertTrue(q.peekFirst() == null ||
+                       !q.peekFirst().equals(i));
+        }
+        assertNull(q.peekFirst());
+    }
+
+    /**
+     * peekLast returns next element, or null if empty
+     */
+    public void testPeekLast() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.peekLast());
+            assertEquals(i, q.pollLast());
+            assertTrue(q.peekLast() == null ||
+                       !q.peekLast().equals(i));
+        }
+        assertNull(q.peekLast());
+    }
+
+    public void testFirstElement() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.getFirst());
+            assertEquals(i, q.pollFirst());
+        }
+        try {
+            q.getFirst();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * getLast returns next element, or throws NSEE if empty
+     */
+    public void testLastElement() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.getLast());
+            assertEquals(i, q.pollLast());
+        }
+        try {
+            q.getLast();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        assertNull(q.peekLast());
+    }
+
+    /**
+     * removeFirstOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveFirstOccurrence() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeFirstOccurrence(new Integer(i)));
+            assertFalse(q.removeFirstOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * removeLastOccurrence(x) removes x and returns true if present
+     */
+    public void testRemoveLastOccurrence() {
+        LinkedList q = populatedQueue(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.removeLastOccurrence(new Integer(i)));
+            assertFalse(q.removeLastOccurrence(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LinkedTransferQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/LinkedTransferQueueTest.java
new file mode 100644
index 0000000..ee53cf9
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LinkedTransferQueueTest.java
@@ -0,0 +1,1087 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include John Vint
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedTransferQueue;
+
+import junit.framework.Test;
+
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class LinkedTransferQueueTest extends JSR166TestCase {
+    public static class Generic extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new LinkedTransferQueue();
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return LinkedTransferQueue.class; }
+            public Collection emptyCollection() { return new LinkedTransferQueue(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(LinkedTransferQueueTest.class,
+                            new Generic().testSuite(),
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /**
+     * Constructor builds new queue with size being zero and empty
+     * being true
+     */
+    public void testConstructor1() {
+        assertEquals(0, new LinkedTransferQueue().size());
+        assertTrue(new LinkedTransferQueue().isEmpty());
+    }
+
+    /**
+     * Initializing constructor with null collection throws
+     * NullPointerException
+     */
+    public void testConstructor2() {
+        try {
+            new LinkedTransferQueue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws
+     * NullPointerException
+     */
+    public void testConstructor3() {
+        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            new LinkedTransferQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing constructor with a collection containing some null elements
+     * throws NullPointerException
+     */
+    public void testConstructor4() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            new LinkedTransferQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of the collection it is initialized by
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i) {
+            ints[i] = i;
+        }
+        List intList = Arrays.asList(ints);
+        LinkedTransferQueue q
+            = new LinkedTransferQueue(intList);
+        assertEquals(q.size(), intList.size());
+        assertEquals(q.toString(), intList.toString());
+        assertTrue(Arrays.equals(q.toArray(),
+                                     intList.toArray()));
+        assertTrue(Arrays.equals(q.toArray(new Object[0]),
+                                 intList.toArray(new Object[0])));
+        assertTrue(Arrays.equals(q.toArray(new Object[SIZE]),
+                                 intList.toArray(new Object[SIZE])));
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(ints[i], q.poll());
+        }
+    }
+
+    /**
+     * remainingCapacity() always returns Integer.MAX_VALUE
+     */
+    public void testRemainingCapacity() {
+        BlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(SIZE - i, q.size());
+            assertEquals(i, q.remove());
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(i, q.size());
+            assertTrue(q.add(i));
+        }
+    }
+
+    /**
+     * addAll(this) throws IllegalArgumentException
+     */
+    public void testAddAllSelf() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws
+     * NullPointerException after possibly adding some elements
+     */
+    public void testAddAll3() {
+        LinkedTransferQueue q = new LinkedTransferQueue();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements, in traversal order, of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i) {
+            ints[i] = i;
+        }
+        LinkedTransferQueue q = new LinkedTransferQueue();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(ints[i], q.poll());
+        }
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() {
+        LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.put(i);
+            assertTrue(q.contains(i));
+        }
+    }
+
+    /**
+     * take retrieves elements in FIFO order
+     */
+    public void testTake() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.take());
+        }
+    }
+
+    /**
+     * take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final BlockingQueue q = populatedQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.poll());
+        }
+        assertNull(q.poll());
+        checkEmpty(q);
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+        checkEmpty(q);
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        long startTime = System.nanoTime();
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+        startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedQueue(SIZE);
+        final CountDownLatch aboutToWait = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i)
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                aboutToWait.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        aboutToWait.await();
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * timed poll after thread interrupted throws InterruptedException
+     * instead of returning timeout status
+     */
+    public void testTimedPollAfterInterrupt() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedQueue(SIZE);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                Thread.currentThread().interrupt();
+                for (int i = 0; i < SIZE; ++i)
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.peek());
+            assertEquals(i, (int) q.poll());
+            assertTrue(q.peek() == null ||
+                       i != (int) q.peek());
+        }
+        assertNull(q.peek());
+        checkEmpty(q);
+    }
+
+    /**
+     * element returns next element, or throws NoSuchElementException if empty
+     */
+    public void testElement() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.element());
+            assertEquals(i, (int) q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        checkEmpty(q);
+    }
+
+    /**
+     * remove removes next element, or throws NoSuchElementException if empty
+     */
+    public void testRemove() throws InterruptedException {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, (int) q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+        checkEmpty(q);
+    }
+
+    /**
+     * An add following remove(x) succeeds
+     */
+    public void testRemoveElementAndAdd() throws InterruptedException {
+        LinkedTransferQueue q = new LinkedTransferQueue();
+        assertTrue(q.add(one));
+        assertTrue(q.add(two));
+        assertTrue(q.remove(one));
+        assertTrue(q.remove(two));
+        assertTrue(q.add(three));
+        assertSame(q.take(), three);
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(i));
+            assertEquals(i, (int) q.poll());
+            assertFalse(q.contains(i));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() throws InterruptedException {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        q.clear();
+        checkEmpty(q);
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertEquals(1, q.size());
+        assertTrue(q.contains(one));
+        q.clear();
+        checkEmpty(q);
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        LinkedTransferQueue<Integer> p = new LinkedTransferQueue<>();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(i);
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true
+     * if changed
+     */
+    public void testRetainAll() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        LinkedTransferQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0) {
+                assertFalse(changed);
+            } else {
+                assertTrue(changed);
+            }
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true
+     * if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            LinkedTransferQueue q = populatedQueue(SIZE);
+            LinkedTransferQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                assertFalse(q.contains(p.remove()));
+            }
+        }
+    }
+
+    /**
+     * toArray() contains all elements in FIFO order
+     */
+    public void testToArray() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++) {
+            assertSame(o[i], q.poll());
+        }
+    }
+
+    /**
+     * toArray(a) contains all elements in FIFO order
+     */
+    public void testToArray2() {
+        LinkedTransferQueue<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++) {
+            assertSame(ints[i], q.poll());
+        }
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() throws InterruptedException {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+
+        it = q.iterator();
+        for (i = 0; it.hasNext(); i++)
+            assertEquals(it.next(), q.take());
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new LinkedTransferQueue().iterator());
+    }
+
+    /**
+     * iterator.remove() removes current element
+     */
+    public void testIteratorRemove() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        q.add(two);
+        q.add(one);
+        q.add(three);
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertSame(it.next(), one);
+        assertSame(it.next(), three);
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * iterator ordering is FIFO
+     */
+    public void testIteratorOrdering() {
+        final LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        int k = 0;
+        for (Integer n : q) {
+            assertEquals(++k, (int) n);
+        }
+        assertEquals(3, k);
+    }
+
+    /**
+     * Modifications do not cause iterators to fail
+     */
+    public void testWeaklyConsistentIteration() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        for (Iterator it = q.iterator(); it.hasNext();) {
+            q.remove();
+            it.next();
+        }
+        assertEquals(0, q.size());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    long startTime = System.nanoTime();
+                    assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                    checkEmpty(q);
+                }});
+        }
+    }
+
+    /**
+     * timed poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    long startTime = System.nanoTime();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements in same order
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(y, x);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertTrue(Arrays.equals(x.toArray(), y.toArray()));
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * drainTo(c) empties queue into another collection c
+     */
+    public void testDrainTo() {
+        LinkedTransferQueue q = populatedQueue(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(SIZE, l.size());
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, l.get(i));
+        }
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i) {
+            assertEquals(i, l.get(i));
+        }
+    }
+
+    /**
+     * drainTo(c) empties full queue, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final LinkedTransferQueue q = populatedQueue(SIZE);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(SIZE + 1);
+            }});
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(i, l.get(i));
+        awaitTermination(t);
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        LinkedTransferQueue q = new LinkedTransferQueue();
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++) {
+                assertTrue(q.offer(j));
+            }
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(k, l.size());
+            assertEquals(SIZE - k, q.size());
+            for (int j = 0; j < k; ++j)
+                assertEquals(j, l.get(j));
+            do {} while (q.poll() != null);
+        }
+    }
+
+    /**
+     * timed poll() or take() increments the waiting consumer count;
+     * offer(e) decrements the waiting consumer count
+     */
+    public void testWaitingConsumer() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        assertEquals(0, q.getWaitingConsumerCount());
+        assertFalse(q.hasWaitingConsumer());
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadStarted.countDown();
+                long startTime = System.nanoTime();
+                assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                assertEquals(0, q.getWaitingConsumerCount());
+                assertFalse(q.hasWaitingConsumer());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        threadStarted.await();
+        Callable<Boolean> oneConsumer
+            = new Callable<Boolean>() { public Boolean call() {
+                return q.hasWaitingConsumer()
+                && q.getWaitingConsumerCount() == 1; }};
+        waitForThreadToEnterWaitState(t, oneConsumer);
+
+        assertTrue(q.offer(one));
+        assertEquals(0, q.getWaitingConsumerCount());
+        assertFalse(q.hasWaitingConsumer());
+
+        awaitTermination(t);
+    }
+
+    /**
+     * transfer(null) throws NullPointerException
+     */
+    public void testTransfer1() throws InterruptedException {
+        try {
+            LinkedTransferQueue q = new LinkedTransferQueue();
+            q.transfer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * transfer waits until a poll occurs. The transfered element
+     * is returned by the associated poll.
+     */
+    public void testTransfer2() throws InterruptedException {
+        final LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                threadStarted.countDown();
+                q.transfer(five);
+                checkEmpty(q);
+            }});
+
+        threadStarted.await();
+        Callable<Boolean> oneElement
+            = new Callable<Boolean>() { public Boolean call() {
+                return !q.isEmpty() && q.size() == 1; }};
+        waitForThreadToEnterWaitState(t, oneElement);
+
+        assertSame(five, q.poll());
+        checkEmpty(q);
+        awaitTermination(t);
+    }
+
+    /**
+     * transfer waits until a poll occurs, and then transfers in fifo order
+     */
+    public void testTransfer3() throws InterruptedException {
+        final LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+
+        Thread first = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.transfer(four);
+                assertTrue(!q.contains(four));
+                assertEquals(1, q.size());
+            }});
+
+        Thread interruptedThread = newStartedThread(
+            new CheckedInterruptedRunnable() {
+                public void realRun() throws InterruptedException {
+                    while (q.isEmpty())
+                        Thread.yield();
+                    q.transfer(five);
+                }});
+
+        while (q.size() < 2)
+            Thread.yield();
+        assertEquals(2, q.size());
+        assertSame(four, q.poll());
+        first.join();
+        assertEquals(1, q.size());
+        interruptedThread.interrupt();
+        interruptedThread.join();
+        checkEmpty(q);
+    }
+
+    /**
+     * transfer waits until a poll occurs, at which point the polling
+     * thread returns the element
+     */
+    public void testTransfer4() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.transfer(four);
+                assertFalse(q.contains(four));
+                assertSame(three, q.poll());
+            }});
+
+        while (q.isEmpty())
+            Thread.yield();
+        assertFalse(q.isEmpty());
+        assertEquals(1, q.size());
+        assertTrue(q.offer(three));
+        assertSame(four, q.poll());
+        awaitTermination(t);
+    }
+
+    /**
+     * transfer waits until a take occurs. The transfered element
+     * is returned by the associated take.
+     */
+    public void testTransfer5() throws InterruptedException {
+        final LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.transfer(four);
+                checkEmpty(q);
+            }});
+
+        while (q.isEmpty())
+            Thread.yield();
+        assertFalse(q.isEmpty());
+        assertEquals(1, q.size());
+        assertSame(four, q.take());
+        checkEmpty(q);
+        awaitTermination(t);
+    }
+
+    /**
+     * tryTransfer(null) throws NullPointerException
+     */
+    public void testTryTransfer1() {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        try {
+            q.tryTransfer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * tryTransfer returns false and does not enqueue if there are no
+     * consumers waiting to poll or take.
+     */
+    public void testTryTransfer2() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        assertFalse(q.tryTransfer(new Object()));
+        assertFalse(q.hasWaitingConsumer());
+        checkEmpty(q);
+    }
+
+    /**
+     * If there is a consumer waiting in timed poll, tryTransfer
+     * returns true while successfully transfering object.
+     */
+    public void testTryTransfer3() throws InterruptedException {
+        final Object hotPotato = new Object();
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                while (! q.hasWaitingConsumer())
+                    Thread.yield();
+                assertTrue(q.hasWaitingConsumer());
+                checkEmpty(q);
+                assertTrue(q.tryTransfer(hotPotato));
+            }});
+
+        long startTime = System.nanoTime();
+        assertSame(hotPotato, q.poll(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        checkEmpty(q);
+        awaitTermination(t);
+    }
+
+    /**
+     * If there is a consumer waiting in take, tryTransfer returns
+     * true while successfully transfering object.
+     */
+    public void testTryTransfer4() throws InterruptedException {
+        final Object hotPotato = new Object();
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                while (! q.hasWaitingConsumer())
+                    Thread.yield();
+                assertTrue(q.hasWaitingConsumer());
+                checkEmpty(q);
+                assertTrue(q.tryTransfer(hotPotato));
+            }});
+
+        assertSame(q.take(), hotPotato);
+        checkEmpty(q);
+        awaitTermination(t);
+    }
+
+    /**
+     * tryTransfer blocks interruptibly if no takers
+     */
+    public void testTryTransfer5() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        assertTrue(q.isEmpty());
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                Thread.currentThread().interrupt();
+                try {
+                    q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.tryTransfer(new Object(), LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * tryTransfer gives up after the timeout and returns false
+     */
+    public void testTryTransfer6() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertFalse(q.tryTransfer(new Object(),
+                                          timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                checkEmpty(q);
+            }});
+
+        awaitTermination(t);
+        checkEmpty(q);
+    }
+
+    /**
+     * tryTransfer waits for any elements previously in to be removed
+     * before transfering to a poll or take
+     */
+    public void testTryTransfer7() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        assertTrue(q.offer(four));
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertTrue(q.tryTransfer(five, LONG_DELAY_MS, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                checkEmpty(q);
+            }});
+
+        while (q.size() != 2)
+            Thread.yield();
+        assertEquals(2, q.size());
+        assertSame(four, q.poll());
+        assertSame(five, q.poll());
+        checkEmpty(q);
+        awaitTermination(t);
+    }
+
+    /**
+     * tryTransfer attempts to enqueue into the queue and fails
+     * returning false not enqueueing and the successive poll is null
+     */
+    public void testTryTransfer8() throws InterruptedException {
+        final LinkedTransferQueue q = new LinkedTransferQueue();
+        assertTrue(q.offer(four));
+        assertEquals(1, q.size());
+        long startTime = System.nanoTime();
+        assertFalse(q.tryTransfer(five, timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        assertEquals(1, q.size());
+        assertSame(four, q.poll());
+        assertNull(q.poll());
+        checkEmpty(q);
+    }
+
+    private LinkedTransferQueue<Integer> populatedQueue(int n) {
+        LinkedTransferQueue<Integer> q = new LinkedTransferQueue<>();
+        checkEmpty(q);
+        for (int i = 0; i < n; i++) {
+            assertEquals(i, q.size());
+            assertTrue(q.offer(i));
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        }
+        assertFalse(q.isEmpty());
+        return q;
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?>[] qs = {
+            new LinkedTransferQueue<Object>(),
+            populatedQueue(2),
+        };
+
+        for (Collection<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LockSupportTest.java b/ojluni/src/test/java/util/concurrent/tck/LockSupportTest.java
new file mode 100644
index 0000000..1a31cbd
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LockSupportTest.java
@@ -0,0 +1,404 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LockSupportTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(LockSupportTest.class);
+    }
+
+    static {
+        // Reduce the risk of rare disastrous classloading in first call to
+        // LockSupport.park: https://bugs.openjdk.java.net/browse/JDK-8074773
+        Class<?> ensureLoaded = LockSupport.class;
+    }
+
+    /**
+     * Returns the blocker object used by tests in this file.
+     * Any old object will do; we'll return a convenient one.
+     */
+    static Object theBlocker() {
+        return LockSupportTest.class;
+    }
+
+    enum ParkMethod {
+        park() {
+            void park() {
+                LockSupport.park();
+            }
+            void park(long millis) {
+                throw new UnsupportedOperationException();
+            }
+        },
+        parkUntil() {
+            void park(long millis) {
+                LockSupport.parkUntil(deadline(millis));
+            }
+        },
+        parkNanos() {
+            void park(long millis) {
+                LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
+            }
+        },
+        parkBlocker() {
+            void park() {
+                LockSupport.park(theBlocker());
+            }
+            void park(long millis) {
+                throw new UnsupportedOperationException();
+            }
+        },
+        parkUntilBlocker() {
+            void park(long millis) {
+                LockSupport.parkUntil(theBlocker(), deadline(millis));
+            }
+        },
+        parkNanosBlocker() {
+            void park(long millis) {
+                LockSupport.parkNanos(theBlocker(),
+                                      MILLISECONDS.toNanos(millis));
+            }
+        };
+
+        void park() { park(2 * LONG_DELAY_MS); }
+        abstract void park(long millis);
+
+        /** Returns a deadline to use with parkUntil. */
+        long deadline(long millis) {
+            // beware of rounding
+            return System.currentTimeMillis() + millis + 1;
+        }
+    }
+
+    /**
+     * park is released by subsequent unpark
+     */
+    public void testParkBeforeUnpark_park() {
+        testParkBeforeUnpark(ParkMethod.park);
+    }
+    public void testParkBeforeUnpark_parkNanos() {
+        testParkBeforeUnpark(ParkMethod.parkNanos);
+    }
+    public void testParkBeforeUnpark_parkUntil() {
+        testParkBeforeUnpark(ParkMethod.parkUntil);
+    }
+    public void testParkBeforeUnpark_parkBlocker() {
+        testParkBeforeUnpark(ParkMethod.parkBlocker);
+    }
+    public void testParkBeforeUnpark_parkNanosBlocker() {
+        testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkBeforeUnpark_parkUntilBlocker() {
+        testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkBeforeUnpark(final ParkMethod parkMethod) {
+        final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                pleaseUnpark.countDown();
+                parkMethod.park();
+            }});
+
+        await(pleaseUnpark);
+        LockSupport.unpark(t);
+        awaitTermination(t);
+    }
+
+    /**
+     * park is released by preceding unpark
+     */
+    public void testParkAfterUnpark_park() {
+        testParkAfterUnpark(ParkMethod.park);
+    }
+    public void testParkAfterUnpark_parkNanos() {
+        testParkAfterUnpark(ParkMethod.parkNanos);
+    }
+    public void testParkAfterUnpark_parkUntil() {
+        testParkAfterUnpark(ParkMethod.parkUntil);
+    }
+    public void testParkAfterUnpark_parkBlocker() {
+        testParkAfterUnpark(ParkMethod.parkBlocker);
+    }
+    public void testParkAfterUnpark_parkNanosBlocker() {
+        testParkAfterUnpark(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkAfterUnpark_parkUntilBlocker() {
+        testParkAfterUnpark(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkAfterUnpark(final ParkMethod parkMethod) {
+        final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+        final AtomicBoolean pleasePark = new AtomicBoolean(false);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                pleaseUnpark.countDown();
+                while (!pleasePark.get())
+                    Thread.yield();
+                parkMethod.park();
+            }});
+
+        await(pleaseUnpark);
+        LockSupport.unpark(t);
+        pleasePark.set(true);
+        awaitTermination(t);
+    }
+
+    /**
+     * park is released by subsequent interrupt
+     */
+    public void testParkBeforeInterrupt_park() {
+        testParkBeforeInterrupt(ParkMethod.park);
+    }
+    public void testParkBeforeInterrupt_parkNanos() {
+        testParkBeforeInterrupt(ParkMethod.parkNanos);
+    }
+    public void testParkBeforeInterrupt_parkUntil() {
+        testParkBeforeInterrupt(ParkMethod.parkUntil);
+    }
+    public void testParkBeforeInterrupt_parkBlocker() {
+        testParkBeforeInterrupt(ParkMethod.parkBlocker);
+    }
+    public void testParkBeforeInterrupt_parkNanosBlocker() {
+        testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkBeforeInterrupt_parkUntilBlocker() {
+        testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                pleaseInterrupt.countDown();
+                do {
+                    parkMethod.park();
+                    // park may return spuriously
+                } while (! Thread.currentThread().isInterrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * park is released by preceding interrupt
+     */
+    public void testParkAfterInterrupt_park() {
+        testParkAfterInterrupt(ParkMethod.park);
+    }
+    public void testParkAfterInterrupt_parkNanos() {
+        testParkAfterInterrupt(ParkMethod.parkNanos);
+    }
+    public void testParkAfterInterrupt_parkUntil() {
+        testParkAfterInterrupt(ParkMethod.parkUntil);
+    }
+    public void testParkAfterInterrupt_parkBlocker() {
+        testParkAfterInterrupt(ParkMethod.parkBlocker);
+    }
+    public void testParkAfterInterrupt_parkNanosBlocker() {
+        testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkAfterInterrupt_parkUntilBlocker() {
+        testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkAfterInterrupt(final ParkMethod parkMethod) {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final AtomicBoolean pleasePark = new AtomicBoolean(false);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws Exception {
+                pleaseInterrupt.countDown();
+                while (!pleasePark.get())
+                    Thread.yield();
+                assertTrue(Thread.currentThread().isInterrupted());
+                parkMethod.park();
+                assertTrue(Thread.currentThread().isInterrupted());
+            }});
+
+        await(pleaseInterrupt);
+        t.interrupt();
+        pleasePark.set(true);
+        awaitTermination(t);
+    }
+
+    /**
+     * timed park times out if not unparked
+     */
+    public void testParkTimesOut_parkNanos() {
+        testParkTimesOut(ParkMethod.parkNanos);
+    }
+    public void testParkTimesOut_parkUntil() {
+        testParkTimesOut(ParkMethod.parkUntil);
+    }
+    public void testParkTimesOut_parkNanosBlocker() {
+        testParkTimesOut(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkTimesOut_parkUntilBlocker() {
+        testParkTimesOut(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkTimesOut(final ParkMethod parkMethod) {
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                for (;;) {
+                    long startTime = System.nanoTime();
+                    parkMethod.park(timeoutMillis());
+                    // park may return spuriously
+                    if (millisElapsedSince(startTime) >= timeoutMillis())
+                        return;
+                }
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * getBlocker(null) throws NullPointerException
+     */
+    public void testGetBlockerNull() {
+        try {
+            LockSupport.getBlocker(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getBlocker returns the blocker object passed to park
+     */
+    public void testGetBlocker_parkBlocker() {
+        testGetBlocker(ParkMethod.parkBlocker);
+    }
+    public void testGetBlocker_parkNanosBlocker() {
+        testGetBlocker(ParkMethod.parkNanosBlocker);
+    }
+    public void testGetBlocker_parkUntilBlocker() {
+        testGetBlocker(ParkMethod.parkUntilBlocker);
+    }
+    public void testGetBlocker(final ParkMethod parkMethod) {
+        final CountDownLatch started = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread t = Thread.currentThread();
+                started.countDown();
+                do {
+                    assertNull(LockSupport.getBlocker(t));
+                    parkMethod.park();
+                    assertNull(LockSupport.getBlocker(t));
+                    // park may return spuriously
+                } while (! Thread.currentThread().isInterrupted());
+            }});
+
+        long startTime = System.nanoTime();
+        await(started);
+        for (;;) {
+            Object x = LockSupport.getBlocker(t);
+            if (x == theBlocker()) { // success
+                t.interrupt();
+                awaitTermination(t);
+                assertNull(LockSupport.getBlocker(t));
+                return;
+            } else {
+                assertNull(x);  // ok
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    fail("timed out");
+                Thread.yield();
+            }
+        }
+    }
+
+    /**
+     * timed park(0) returns immediately.
+     *
+     * Requires hotspot fix for:
+     * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
+     * which is in jdk7-b118 and 6u25.
+     */
+    public void testPark0_parkNanos() {
+        testPark0(ParkMethod.parkNanos);
+    }
+    public void testPark0_parkUntil() {
+        testPark0(ParkMethod.parkUntil);
+    }
+    public void testPark0_parkNanosBlocker() {
+        testPark0(ParkMethod.parkNanosBlocker);
+    }
+    public void testPark0_parkUntilBlocker() {
+        testPark0(ParkMethod.parkUntilBlocker);
+    }
+    public void testPark0(final ParkMethod parkMethod) {
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                parkMethod.park(0L);
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * timed park(Long.MIN_VALUE) returns immediately.
+     */
+    public void testParkNeg_parkNanos() {
+        testParkNeg(ParkMethod.parkNanos);
+    }
+    public void testParkNeg_parkUntil() {
+        testParkNeg(ParkMethod.parkUntil);
+    }
+    public void testParkNeg_parkNanosBlocker() {
+        testParkNeg(ParkMethod.parkNanosBlocker);
+    }
+    public void testParkNeg_parkUntilBlocker() {
+        testParkNeg(ParkMethod.parkUntilBlocker);
+    }
+    public void testParkNeg(final ParkMethod parkMethod) {
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                parkMethod.park(Long.MIN_VALUE);
+            }});
+
+        awaitTermination(t);
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LongAccumulatorTest.java b/ojluni/src/test/java/util/concurrent/tck/LongAccumulatorTest.java
new file mode 100644
index 0000000..36386fc
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LongAccumulatorTest.java
@@ -0,0 +1,184 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.atomic.LongAccumulator;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LongAccumulatorTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(LongAccumulatorTest.class);
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * accumulate accumulates given value to current, and get returns current value
+     */
+    public void testAccumulateAndGet() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        ai.accumulate(-4);
+        assertEquals(2, ai.get());
+        ai.accumulate(4);
+        assertEquals(4, ai.get());
+    }
+
+    /**
+     * reset() causes subsequent get() to return zero
+     */
+    public void testReset() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        ai.reset();
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * getThenReset() returns current value; subsequent get() returns zero
+     */
+    public void testGetThenReset() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        ai.accumulate(2);
+        assertEquals(2, ai.get());
+        assertEquals(2, ai.getThenReset());
+        assertEquals(0, ai.get());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals("0", ai.toString());
+        ai.accumulate(1);
+        assertEquals(Long.toString(1), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.intValue());
+        ai.accumulate(1);
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0, ai.longValue());
+        ai.accumulate(1);
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0.0f, ai.floatValue());
+        ai.accumulate(1);
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        LongAccumulator ai = new LongAccumulator(Long::max, 0L);
+        assertEquals(0.0, ai.doubleValue());
+        ai.accumulate(1);
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * accumulates by multiple threads produce correct result
+     */
+    public void testAccumulateAndGetMT() {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        LongAccumulator a = new LongAccumulator(Long::max, 0L);
+        Phaser phaser = new Phaser(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AccTask(a, phaser, incs));
+        phaser.arriveAndAwaitAdvance();
+        phaser.arriveAndAwaitAdvance();
+        long expected = incs - 1;
+        long result = a.get();
+        assertEquals(expected, result);
+        pool.shutdown();
+    }
+
+    static final class AccTask implements Runnable {
+        final LongAccumulator acc;
+        final Phaser phaser;
+        final int incs;
+        volatile long result;
+        AccTask(LongAccumulator acc, Phaser phaser, int incs) {
+            this.acc = acc;
+            this.phaser = phaser;
+            this.incs = incs;
+        }
+
+        public void run() {
+            phaser.arriveAndAwaitAdvance();
+            LongAccumulator a = acc;
+            for (int i = 0; i < incs; ++i)
+                a.accumulate(i);
+            result = a.get();
+            phaser.arrive();
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/LongAdderTest.java b/ojluni/src/test/java/util/concurrent/tck/LongAdderTest.java
new file mode 100644
index 0000000..d980185
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/LongAdderTest.java
@@ -0,0 +1,221 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.atomic.LongAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class LongAdderTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(LongAdderTest.class);
+    }
+
+    /**
+     * default constructed initializes to zero
+     */
+    public void testConstructor() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * add adds given value to current, and sum returns current value
+     */
+    public void testAddAndSum() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        ai.add(-4);
+        assertEquals(-2, ai.sum());
+    }
+
+    /**
+     * decrement decrements and sum returns current value
+     */
+    public void testDecrementAndsum() {
+        LongAdder ai = new LongAdder();
+        ai.decrement();
+        assertEquals(-1, ai.sum());
+        ai.decrement();
+        assertEquals(-2, ai.sum());
+    }
+
+    /**
+     * incrementAndGet increments and returns current value
+     */
+    public void testIncrementAndsum() {
+        LongAdder ai = new LongAdder();
+        ai.increment();
+        assertEquals(1, ai.sum());
+        ai.increment();
+        assertEquals(2, ai.sum());
+    }
+
+    /**
+     * reset() causes subsequent sum() to return zero
+     */
+    public void testReset() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        ai.reset();
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * sumThenReset() returns sum; subsequent sum() returns zero
+     */
+    public void testSumThenReset() {
+        LongAdder ai = new LongAdder();
+        ai.add(2);
+        assertEquals(2, ai.sum());
+        assertEquals(2, ai.sumThenReset());
+        assertEquals(0, ai.sum());
+    }
+
+    /**
+     * a deserialized serialized adder holds same value
+     */
+    public void testSerialization() throws Exception {
+        LongAdder x = new LongAdder();
+        LongAdder y = serialClone(x);
+        assertNotSame(x, y);
+        x.add(-22);
+        LongAdder z = serialClone(x);
+        assertNotSame(y, z);
+        assertEquals(-22, x.sum());
+        assertEquals(0, y.sum());
+        assertEquals(-22, z.sum());
+    }
+
+    /**
+     * toString returns current value.
+     */
+    public void testToString() {
+        LongAdder ai = new LongAdder();
+        assertEquals("0", ai.toString());
+        ai.increment();
+        assertEquals(Long.toString(1), ai.toString());
+    }
+
+    /**
+     * intValue returns current value.
+     */
+    public void testIntValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.intValue());
+        ai.increment();
+        assertEquals(1, ai.intValue());
+    }
+
+    /**
+     * longValue returns current value.
+     */
+    public void testLongValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0, ai.longValue());
+        ai.increment();
+        assertEquals(1, ai.longValue());
+    }
+
+    /**
+     * floatValue returns current value.
+     */
+    public void testFloatValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0.0f, ai.floatValue());
+        ai.increment();
+        assertEquals(1.0f, ai.floatValue());
+    }
+
+    /**
+     * doubleValue returns current value.
+     */
+    public void testDoubleValue() {
+        LongAdder ai = new LongAdder();
+        assertEquals(0.0, ai.doubleValue());
+        ai.increment();
+        assertEquals(1.0, ai.doubleValue());
+    }
+
+    /**
+     * adds by multiple threads produce correct sum
+     */
+    public void testAddAndSumMT() throws Throwable {
+        final int incs = 1000000;
+        final int nthreads = 4;
+        final ExecutorService pool = Executors.newCachedThreadPool();
+        LongAdder a = new LongAdder();
+        CyclicBarrier barrier = new CyclicBarrier(nthreads + 1);
+        for (int i = 0; i < nthreads; ++i)
+            pool.execute(new AdderTask(a, barrier, incs));
+        barrier.await();
+        barrier.await();
+        long total = (long)nthreads * incs;
+        long sum = a.sum();
+        assertEquals(sum, total);
+        pool.shutdown();
+    }
+
+    static final class AdderTask implements Runnable {
+        final LongAdder adder;
+        final CyclicBarrier barrier;
+        final int incs;
+        volatile long result;
+        AdderTask(LongAdder adder, CyclicBarrier barrier, int incs) {
+            this.adder = adder;
+            this.barrier = barrier;
+            this.incs = incs;
+        }
+
+        public void run() {
+            try {
+                barrier.await();
+                LongAdder a = adder;
+                for (int i = 0; i < incs; ++i)
+                    a.add(1L);
+                result = a.sum();
+                barrier.await();
+            } catch (Throwable t) { throw new Error(t); }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/PhaserTest.java b/ojluni/src/test/java/util/concurrent/tck/PhaserTest.java
new file mode 100644
index 0000000..f6764c8
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/PhaserTest.java
@@ -0,0 +1,821 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include John Vint
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Phaser;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class PhaserTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(PhaserTest.class);
+    }
+
+    private static final int maxParties = 65535;
+
+    /** Checks state of unterminated phaser. */
+    protected void assertState(Phaser phaser,
+                               int phase, int parties, int unarrived) {
+        assertEquals(phase, phaser.getPhase());
+        assertEquals(parties, phaser.getRegisteredParties());
+        assertEquals(unarrived, phaser.getUnarrivedParties());
+        assertEquals(parties - unarrived, phaser.getArrivedParties());
+        assertFalse(phaser.isTerminated());
+    }
+
+    /** Checks state of terminated phaser. */
+    protected void assertTerminated(Phaser phaser, int maxPhase, int parties) {
+        assertTrue(phaser.isTerminated());
+        int expectedPhase = maxPhase + Integer.MIN_VALUE;
+        assertEquals(expectedPhase, phaser.getPhase());
+        assertEquals(parties, phaser.getRegisteredParties());
+        assertEquals(expectedPhase, phaser.register());
+        assertEquals(expectedPhase, phaser.arrive());
+        assertEquals(expectedPhase, phaser.arriveAndDeregister());
+    }
+
+    protected void assertTerminated(Phaser phaser, int maxPhase) {
+        assertTerminated(phaser, maxPhase, 0);
+    }
+
+    /**
+     * Empty constructor builds a new Phaser with no parent, no registered
+     * parties and initial phase number of 0
+     */
+    public void testConstructorDefaultValues() {
+        Phaser phaser = new Phaser();
+        assertNull(phaser.getParent());
+        assertEquals(0, phaser.getRegisteredParties());
+        assertEquals(0, phaser.getArrivedParties());
+        assertEquals(0, phaser.getUnarrivedParties());
+        assertEquals(0, phaser.getPhase());
+    }
+
+    /**
+     * Constructing with a negative number of parties throws
+     * IllegalArgumentException
+     */
+    public void testConstructorNegativeParties() {
+        try {
+            new Phaser(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructing with a negative number of parties throws
+     * IllegalArgumentException
+     */
+    public void testConstructorNegativeParties2() {
+        try {
+            new Phaser(new Phaser(), -1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructing with a number of parties > 65535 throws
+     * IllegalArgumentException
+     */
+    public void testConstructorPartiesExceedsLimit() {
+        new Phaser(maxParties);
+        try {
+            new Phaser(maxParties + 1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+
+        new Phaser(new Phaser(), maxParties);
+        try {
+            new Phaser(new Phaser(), maxParties + 1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * The parent provided to the constructor should be returned from
+     * a later call to getParent
+     */
+    public void testConstructor3() {
+        Phaser parent = new Phaser();
+        assertSame(parent, new Phaser(parent).getParent());
+        assertNull(new Phaser(null).getParent());
+    }
+
+    /**
+     * The parent being input into the parameter should equal the original
+     * parent when being returned
+     */
+    public void testConstructor5() {
+        Phaser parent = new Phaser();
+        assertSame(parent, new Phaser(parent, 0).getParent());
+        assertNull(new Phaser(null, 0).getParent());
+    }
+
+    /**
+     * register() will increment the number of unarrived parties by
+     * one and not affect its arrived parties
+     */
+    public void testRegister1() {
+        Phaser phaser = new Phaser();
+        assertState(phaser, 0, 0, 0);
+        assertEquals(0, phaser.register());
+        assertState(phaser, 0, 1, 1);
+    }
+
+    /**
+     * Registering more than 65536 parties causes IllegalStateException
+     */
+    public void testRegister2() {
+        Phaser phaser = new Phaser(0);
+        assertState(phaser, 0, 0, 0);
+        assertEquals(0, phaser.bulkRegister(maxParties - 10));
+        assertState(phaser, 0, maxParties - 10, maxParties - 10);
+        for (int i = 0; i < 10; i++) {
+            assertState(phaser, 0, maxParties - 10 + i, maxParties - 10 + i);
+            assertEquals(0, phaser.register());
+        }
+        assertState(phaser, 0, maxParties, maxParties);
+        try {
+            phaser.register();
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+
+        try {
+            phaser.bulkRegister(Integer.MAX_VALUE);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+
+        assertEquals(0, phaser.bulkRegister(0));
+        assertState(phaser, 0, maxParties, maxParties);
+    }
+
+    /**
+     * register() correctly returns the current barrier phase number
+     * when invoked
+     */
+    public void testRegister3() {
+        Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        assertEquals(0, phaser.arrive());
+        assertEquals(1, phaser.register());
+        assertState(phaser, 1, 2, 2);
+    }
+
+    /**
+     * register causes the next arrive to not increment the phase
+     * rather retain the phase number
+     */
+    public void testRegister4() {
+        Phaser phaser = new Phaser(1);
+        assertEquals(0, phaser.arrive());
+        assertEquals(1, phaser.register());
+        assertEquals(1, phaser.arrive());
+        assertState(phaser, 1, 2, 1);
+    }
+
+    /**
+     * register on a subphaser that is currently empty succeeds, even
+     * in the presence of another non-empty subphaser
+     */
+    public void testRegisterEmptySubPhaser() {
+        Phaser root = new Phaser();
+        Phaser child1 = new Phaser(root, 1);
+        Phaser child2 = new Phaser(root, 0);
+        assertEquals(0, child2.register());
+        assertState(root, 0, 2, 2);
+        assertState(child1, 0, 1, 1);
+        assertState(child2, 0, 1, 1);
+        assertEquals(0, child2.arriveAndDeregister());
+        assertState(root, 0, 1, 1);
+        assertState(child1, 0, 1, 1);
+        assertState(child2, 0, 0, 0);
+        assertEquals(0, child2.register());
+        assertEquals(0, child2.arriveAndDeregister());
+        assertState(root, 0, 1, 1);
+        assertState(child1, 0, 1, 1);
+        assertState(child2, 0, 0, 0);
+        assertEquals(0, child1.arriveAndDeregister());
+        assertTerminated(root, 1);
+        assertTerminated(child1, 1);
+        assertTerminated(child2, 1);
+    }
+
+    /**
+     * Invoking bulkRegister with a negative parameter throws an
+     * IllegalArgumentException
+     */
+    public void testBulkRegister1() {
+        try {
+            new Phaser().bulkRegister(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * bulkRegister should correctly record the number of unarrived
+     * parties with the number of parties being registered
+     */
+    public void testBulkRegister2() {
+        Phaser phaser = new Phaser();
+        assertEquals(0, phaser.bulkRegister(0));
+        assertState(phaser, 0, 0, 0);
+        assertEquals(0, phaser.bulkRegister(20));
+        assertState(phaser, 0, 20, 20);
+    }
+
+    /**
+     * Registering with a number of parties greater than or equal to 1<<16
+     * throws IllegalStateException.
+     */
+    public void testBulkRegister3() {
+        assertEquals(0, new Phaser().bulkRegister((1 << 16) - 1));
+
+        try {
+            new Phaser().bulkRegister(1 << 16);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+
+        try {
+            new Phaser(2).bulkRegister((1 << 16) - 2);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * the phase number increments correctly when tripping the barrier
+     */
+    public void testPhaseIncrement1() {
+        for (int size = 1; size < nine; size++) {
+            final Phaser phaser = new Phaser(size);
+            for (int index = 0; index <= (1 << size); index++) {
+                int phase = phaser.arrive();
+                assertTrue(index % size == 0 ? (index / size) == phase : index - (phase * size) > 0);
+            }
+        }
+    }
+
+    /**
+     * arrive() on a registered phaser increments phase.
+     */
+    public void testArrive1() {
+        Phaser phaser = new Phaser(1);
+        assertState(phaser, 0, 1, 1);
+        assertEquals(0, phaser.arrive());
+        assertState(phaser, 1, 1, 1);
+    }
+
+    /**
+     * arriveAndDeregister does not wait for others to arrive at barrier
+     */
+    public void testArriveAndDeregister() {
+        final Phaser phaser = new Phaser(1);
+        for (int i = 0; i < 10; i++) {
+            assertState(phaser, 0, 1, 1);
+            assertEquals(0, phaser.register());
+            assertState(phaser, 0, 2, 2);
+            assertEquals(0, phaser.arriveAndDeregister());
+            assertState(phaser, 0, 1, 1);
+        }
+        assertEquals(0, phaser.arriveAndDeregister());
+        assertTerminated(phaser, 1);
+    }
+
+    /**
+     * arriveAndDeregister does not wait for others to arrive at barrier
+     */
+    public void testArrive2() {
+        final Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            assertEquals(0, phaser.register());
+            threads.add(newStartedThread(new CheckedRunnable() {
+                public void realRun() {
+                    assertEquals(0, phaser.arriveAndDeregister());
+                }}));
+        }
+
+        for (Thread thread : threads)
+            awaitTermination(thread);
+        assertState(phaser, 0, 1, 1);
+        assertEquals(0, phaser.arrive());
+        assertState(phaser, 1, 1, 1);
+    }
+
+    /**
+     * arrive() returns a negative number if the Phaser is terminated
+     */
+    public void testArrive3() {
+        Phaser phaser = new Phaser(1);
+        phaser.forceTermination();
+        assertTerminated(phaser, 0, 1);
+        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+        assertTrue(phaser.arrive() < 0);
+        assertTrue(phaser.register() < 0);
+        assertTrue(phaser.arriveAndDeregister() < 0);
+        assertTrue(phaser.awaitAdvance(1) < 0);
+        assertTrue(phaser.getPhase() < 0);
+    }
+
+    /**
+     * arriveAndDeregister() throws IllegalStateException if number of
+     * registered or unarrived parties would become negative
+     */
+    public void testArriveAndDeregister1() {
+        Phaser phaser = new Phaser();
+        try {
+            phaser.arriveAndDeregister();
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * arriveAndDeregister reduces the number of arrived parties
+     */
+    public void testArriveAndDeregister2() {
+        final Phaser phaser = new Phaser(1);
+        assertEquals(0, phaser.register());
+        assertEquals(0, phaser.arrive());
+        assertState(phaser, 0, 2, 1);
+        assertEquals(0, phaser.arriveAndDeregister());
+        assertState(phaser, 1, 1, 1);
+    }
+
+    /**
+     * arriveAndDeregister arrives at the barrier on a phaser with a parent and
+     * when a deregistration occurs and causes the phaser to have zero parties
+     * its parent will be deregistered as well
+     */
+    public void testArriveAndDeregister3() {
+        Phaser parent = new Phaser();
+        Phaser child = new Phaser(parent);
+        assertState(child, 0, 0, 0);
+        assertState(parent, 0, 0, 0);
+        assertEquals(0, child.register());
+        assertState(child, 0, 1, 1);
+        assertState(parent, 0, 1, 1);
+        assertEquals(0, child.arriveAndDeregister());
+        assertTerminated(child, 1);
+        assertTerminated(parent, 1);
+    }
+
+    /**
+     * arriveAndDeregister deregisters one party from its parent when
+     * the number of parties of child is zero after deregistration
+     */
+    public void testArriveAndDeregister4() {
+        Phaser parent = new Phaser();
+        Phaser child = new Phaser(parent);
+        assertEquals(0, parent.register());
+        assertEquals(0, child.register());
+        assertState(child, 0, 1, 1);
+        assertState(parent, 0, 2, 2);
+        assertEquals(0, child.arriveAndDeregister());
+        assertState(child, 0, 0, 0);
+        assertState(parent, 0, 1, 1);
+    }
+
+    /**
+     * arriveAndDeregister deregisters one party from its parent when
+     * the number of parties of root is nonzero after deregistration.
+     */
+    public void testArriveAndDeregister5() {
+        Phaser root = new Phaser();
+        Phaser parent = new Phaser(root);
+        Phaser child = new Phaser(parent);
+        assertState(root, 0, 0, 0);
+        assertState(parent, 0, 0, 0);
+        assertState(child, 0, 0, 0);
+        assertEquals(0, child.register());
+        assertState(root, 0, 1, 1);
+        assertState(parent, 0, 1, 1);
+        assertState(child, 0, 1, 1);
+        assertEquals(0, child.arriveAndDeregister());
+        assertTerminated(child, 1);
+        assertTerminated(parent, 1);
+        assertTerminated(root, 1);
+    }
+
+    /**
+     * arriveAndDeregister returns the phase in which it leaves the
+     * phaser in after deregistration
+     */
+    public void testArriveAndDeregister6() {
+        final Phaser phaser = new Phaser(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(0, phaser.arrive());
+            }});
+        assertEquals(1, phaser.arriveAndAwaitAdvance());
+        assertState(phaser, 1, 2, 2);
+        assertEquals(1, phaser.arriveAndDeregister());
+        assertState(phaser, 1, 1, 1);
+        assertEquals(1, phaser.arriveAndDeregister());
+        assertTerminated(phaser, 2);
+        awaitTermination(t);
+    }
+
+    /**
+     * awaitAdvance succeeds upon advance
+     */
+    public void testAwaitAdvance1() {
+        final Phaser phaser = new Phaser(1);
+        assertEquals(0, phaser.arrive());
+        assertEquals(1, phaser.awaitAdvance(0));
+    }
+
+    /**
+     * awaitAdvance with a negative parameter will return without affecting the
+     * phaser
+     */
+    public void testAwaitAdvance2() {
+        Phaser phaser = new Phaser();
+        assertTrue(phaser.awaitAdvance(-1) < 0);
+        assertState(phaser, 0, 0, 0);
+    }
+
+    /**
+     * awaitAdvanceInterruptibly blocks interruptibly
+     */
+    public void testAwaitAdvanceInterruptibly_interruptible() throws InterruptedException {
+        final Phaser phaser = new Phaser(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                try {
+                    phaser.awaitAdvanceInterruptibly(0);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    phaser.awaitAdvanceInterruptibly(0);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws TimeoutException {
+                Thread.currentThread().interrupt();
+                try {
+                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    phaser.awaitAdvanceInterruptibly(0, 2*LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertState(phaser, 0, 1, 1);
+        assertThreadsStayAlive(t1, t2);
+        t1.interrupt();
+        t2.interrupt();
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertState(phaser, 0, 1, 1);
+        assertEquals(0, phaser.arrive());
+        assertState(phaser, 1, 1, 1);
+    }
+
+    /**
+     * awaitAdvance continues waiting if interrupted before waiting
+     */
+    public void testAwaitAdvanceAfterInterrupt() {
+        final Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        final CountDownLatch pleaseArrive = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                assertEquals(0, phaser.register());
+                assertEquals(0, phaser.arrive());
+                pleaseArrive.countDown();
+                assertTrue(Thread.currentThread().isInterrupted());
+                assertEquals(1, phaser.awaitAdvance(0));
+                assertTrue(Thread.interrupted());
+            }});
+
+        await(pleaseArrive);
+        waitForThreadToEnterWaitState(t);
+        assertEquals(0, phaser.arrive());
+        awaitTermination(t);
+
+        Thread.currentThread().interrupt();
+        assertEquals(1, phaser.awaitAdvance(0));
+        assertTrue(Thread.interrupted());
+    }
+
+    /**
+     *  awaitAdvance continues waiting if interrupted while waiting
+     */
+    public void testAwaitAdvanceBeforeInterrupt() {
+        final Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        final CountDownLatch pleaseArrive = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(0, phaser.register());
+                assertEquals(0, phaser.arrive());
+                assertFalse(Thread.currentThread().isInterrupted());
+                pleaseArrive.countDown();
+                assertEquals(1, phaser.awaitAdvance(0));
+                assertTrue(Thread.interrupted());
+            }});
+
+        await(pleaseArrive);
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        assertEquals(0, phaser.arrive());
+        awaitTermination(t);
+
+        Thread.currentThread().interrupt();
+        assertEquals(1, phaser.awaitAdvance(0));
+        assertTrue(Thread.interrupted());
+    }
+
+    /**
+     * arriveAndAwaitAdvance continues waiting if interrupted before waiting
+     */
+    public void testArriveAndAwaitAdvanceAfterInterrupt() {
+        final Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        final CountDownLatch pleaseArrive = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                Thread.currentThread().interrupt();
+                assertEquals(0, phaser.register());
+                pleaseArrive.countDown();
+                assertTrue(Thread.currentThread().isInterrupted());
+                assertEquals(1, phaser.arriveAndAwaitAdvance());
+                assertTrue(Thread.interrupted());
+            }});
+
+        await(pleaseArrive);
+        waitForThreadToEnterWaitState(t);
+        Thread.currentThread().interrupt();
+        assertEquals(1, phaser.arriveAndAwaitAdvance());
+        assertTrue(Thread.interrupted());
+        awaitTermination(t);
+    }
+
+    /**
+     * arriveAndAwaitAdvance continues waiting if interrupted while waiting
+     */
+    public void testArriveAndAwaitAdvanceBeforeInterrupt() {
+        final Phaser phaser = new Phaser();
+        assertEquals(0, phaser.register());
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(0, phaser.register());
+                assertFalse(Thread.currentThread().isInterrupted());
+                pleaseInterrupt.countDown();
+                assertEquals(1, phaser.arriveAndAwaitAdvance());
+                assertTrue(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        Thread.currentThread().interrupt();
+        assertEquals(1, phaser.arriveAndAwaitAdvance());
+        assertTrue(Thread.interrupted());
+        awaitTermination(t);
+    }
+
+    /**
+     * awaitAdvance atomically waits for all parties within the same phase to
+     * complete before continuing
+     */
+    public void testAwaitAdvance4() {
+        final Phaser phaser = new Phaser(4);
+        final AtomicInteger count = new AtomicInteger(0);
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 4; i++)
+            threads.add(newStartedThread(new CheckedRunnable() {
+                public void realRun() {
+                    for (int k = 0; k < 3; k++) {
+                        assertEquals(2 * k + 1, phaser.arriveAndAwaitAdvance());
+                        count.incrementAndGet();
+                        assertEquals(2 * k + 1, phaser.arrive());
+                        assertEquals(2 * k + 2, phaser.awaitAdvance(2 * k + 1));
+                        assertEquals(4 * (k + 1), count.get());
+                    }}}));
+
+        for (Thread thread : threads)
+            awaitTermination(thread);
+    }
+
+    /**
+     * awaitAdvance returns the current phase
+     */
+    public void testAwaitAdvance5() {
+        final Phaser phaser = new Phaser(1);
+        assertEquals(1, phaser.awaitAdvance(phaser.arrive()));
+        assertEquals(1, phaser.getPhase());
+        assertEquals(1, phaser.register());
+        List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 8; i++) {
+            final CountDownLatch latch = new CountDownLatch(1);
+            final boolean goesFirst = ((i & 1) == 0);
+            threads.add(newStartedThread(new CheckedRunnable() {
+                public void realRun() {
+                    if (goesFirst)
+                        latch.countDown();
+                    else
+                        await(latch);
+                    phaser.arrive();
+                }}));
+            if (goesFirst)
+                await(latch);
+            else
+                latch.countDown();
+            assertEquals(i + 2, phaser.awaitAdvance(phaser.arrive()));
+            assertEquals(i + 2, phaser.getPhase());
+        }
+        for (Thread thread : threads)
+            awaitTermination(thread);
+    }
+
+    /**
+     * awaitAdvance returns the current phase in child phasers
+     */
+    public void testAwaitAdvanceTieredPhaser() throws Exception {
+        final Phaser parent = new Phaser();
+        final List<Phaser> zeroPartyChildren = new ArrayList<>(3);
+        final List<Phaser> onePartyChildren = new ArrayList<>(3);
+        for (int i = 0; i < 3; i++) {
+            zeroPartyChildren.add(new Phaser(parent, 0));
+            onePartyChildren.add(new Phaser(parent, 1));
+        }
+        final List<Phaser> phasers = new ArrayList<>();
+        phasers.addAll(zeroPartyChildren);
+        phasers.addAll(onePartyChildren);
+        phasers.add(parent);
+        for (Phaser phaser : phasers) {
+            assertEquals(-42, phaser.awaitAdvance(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
+        }
+
+        for (Phaser child : onePartyChildren)
+            assertEquals(0, child.arrive());
+        for (Phaser phaser : phasers) {
+            assertEquals(-42, phaser.awaitAdvance(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
+            assertEquals(1, phaser.awaitAdvance(0));
+            assertEquals(1, phaser.awaitAdvanceInterruptibly(0));
+            assertEquals(1, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
+        }
+
+        for (Phaser child : onePartyChildren)
+            assertEquals(1, child.arrive());
+        for (Phaser phaser : phasers) {
+            assertEquals(-42, phaser.awaitAdvance(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42));
+            assertEquals(-42, phaser.awaitAdvanceInterruptibly(-42, MEDIUM_DELAY_MS, MILLISECONDS));
+            assertEquals(2, phaser.awaitAdvance(0));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(0));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(0, MEDIUM_DELAY_MS, MILLISECONDS));
+            assertEquals(2, phaser.awaitAdvance(1));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(1));
+            assertEquals(2, phaser.awaitAdvanceInterruptibly(1, MEDIUM_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * awaitAdvance returns when the phaser is externally terminated
+     */
+    public void testAwaitAdvance6() {
+        final Phaser phaser = new Phaser(3);
+        final CountDownLatch pleaseForceTermination = new CountDownLatch(2);
+        final List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < 2; i++) {
+            Runnable r = new CheckedRunnable() {
+                public void realRun() {
+                    assertEquals(0, phaser.arrive());
+                    pleaseForceTermination.countDown();
+                    assertTrue(phaser.awaitAdvance(0) < 0);
+                    assertTrue(phaser.isTerminated());
+                    assertTrue(phaser.getPhase() < 0);
+                    assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+                    assertEquals(3, phaser.getRegisteredParties());
+                }};
+            threads.add(newStartedThread(r));
+        }
+        await(pleaseForceTermination);
+        phaser.forceTermination();
+        assertTrue(phaser.isTerminated());
+        assertEquals(0, phaser.getPhase() + Integer.MIN_VALUE);
+        for (Thread thread : threads)
+            awaitTermination(thread);
+        assertEquals(3, phaser.getRegisteredParties());
+    }
+
+    /**
+     * arriveAndAwaitAdvance throws IllegalStateException with no
+     * unarrived parties
+     */
+    public void testArriveAndAwaitAdvance1() {
+        Phaser phaser = new Phaser();
+        try {
+            phaser.arriveAndAwaitAdvance();
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * arriveAndAwaitAdvance waits for all threads to arrive, the
+     * number of arrived parties is the same number that is accounted
+     * for when the main thread awaitsAdvance
+     */
+    public void testArriveAndAwaitAdvance3() {
+        final Phaser phaser = new Phaser(1);
+        final int THREADS = 3;
+        final CountDownLatch pleaseArrive = new CountDownLatch(THREADS);
+        final List<Thread> threads = new ArrayList<>();
+        for (int i = 0; i < THREADS; i++)
+            threads.add(newStartedThread(new CheckedRunnable() {
+                public void realRun() {
+                    assertEquals(0, phaser.register());
+                    pleaseArrive.countDown();
+                    assertEquals(1, phaser.arriveAndAwaitAdvance());
+                }}));
+
+        await(pleaseArrive);
+        long startTime = System.nanoTime();
+        while (phaser.getArrivedParties() < THREADS)
+            Thread.yield();
+        assertEquals(THREADS, phaser.getArrivedParties());
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        for (Thread thread : threads)
+            waitForThreadToEnterWaitState(thread);
+        for (Thread thread : threads)
+            assertTrue(thread.isAlive());
+        assertState(phaser, 0, THREADS + 1, 1);
+        phaser.arriveAndAwaitAdvance();
+        for (Thread thread : threads)
+            awaitTermination(thread);
+        assertState(phaser, 1, THREADS + 1, THREADS + 1);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java
new file mode 100644
index 0000000..9aacce3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/PriorityBlockingQueueTest.java
@@ -0,0 +1,777 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.PriorityBlockingQueue;
+
+import junit.framework.Test;
+
+public class PriorityBlockingQueueTest extends JSR166TestCase {
+
+    public static class Generic extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new PriorityBlockingQueue();
+        }
+    }
+
+    public static class InitialCapacity extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new PriorityBlockingQueue(SIZE);
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return PriorityBlockingQueue.class; }
+            public Collection emptyCollection() { return new PriorityBlockingQueue(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return true; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(PriorityBlockingQueueTest.class,
+                            new Generic().testSuite(),
+                            new InitialCapacity().testSuite(),
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    /** Sample Comparator */
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private PriorityBlockingQueue<Integer> populatedQueue(int n) {
+        PriorityBlockingQueue<Integer> q =
+            new PriorityBlockingQueue<Integer>(n);
+        assertTrue(q.isEmpty());
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.offer(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peek());
+        return q;
+    }
+
+    /**
+     * A new queue has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(Integer.MAX_VALUE,
+                     new PriorityBlockingQueue(SIZE).remainingCapacity());
+    }
+
+    /**
+     * Constructor throws IAE if capacity argument nonpositive
+     */
+    public void testConstructor2() {
+        try {
+            new PriorityBlockingQueue(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new PriorityBlockingQueue(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        Collection<Integer> elements = Arrays.asList(new Integer[SIZE]);
+        try {
+            new PriorityBlockingQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = i;
+        Collection<Integer> elements = Arrays.asList(ints);
+        try {
+            new PriorityBlockingQueue(elements);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = i;
+        PriorityBlockingQueue q = new PriorityBlockingQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * The comparator used in constructor is used
+     */
+    public void testConstructor7() {
+        MyReverseComparator cmp = new MyReverseComparator();
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE, cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE - 1; i >= 0; --i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+        assertTrue(q.isEmpty());
+        assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        q.add(two);
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * remainingCapacity() always returns Integer.MAX_VALUE
+     */
+    public void testRemainingCapacity() {
+        BlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(SIZE - i, q.size());
+            assertEquals(i, q.remove());
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(Integer.MAX_VALUE, q.remainingCapacity());
+            assertEquals(i, q.size());
+            assertTrue(q.add(i));
+        }
+    }
+
+    /**
+     * Offer of comparable element succeeds
+     */
+    public void testOffer() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(1);
+        assertTrue(q.offer(zero));
+        assertTrue(q.offer(one));
+    }
+
+    /**
+     * Offer of non-Comparable throws CCE
+     */
+    public void testOfferNonComparable() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(1);
+        try {
+            q.offer(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {
+            assertTrue(q.isEmpty());
+            assertEquals(0, q.size());
+            assertNull(q.poll());
+        }
+    }
+
+    /**
+     * add of comparable succeeds
+     */
+    public void testAdd() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new Integer(i)));
+        }
+    }
+
+    /**
+     * addAll(this) throws IAE
+     */
+    public void testAddAllSelf() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = SIZE - 1; i >= 0; --i)
+            ints[i] = new Integer(i);
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * all elements successfully put are contained
+     */
+    public void testPut() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            Integer x = new Integer(i);
+            q.put(x);
+            assertTrue(q.contains(x));
+        }
+        assertEquals(SIZE, q.size());
+    }
+
+    /**
+     * put doesn't block waiting for take
+     */
+    public void testPutWithTake() throws InterruptedException {
+        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+        final int size = 4;
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                for (int i = 0; i < size; i++)
+                    q.put(new Integer(0));
+            }});
+
+        awaitTermination(t);
+        assertEquals(size, q.size());
+        q.take();
+    }
+
+    /**
+     * timed offer does not time out
+     */
+    public void testTimedOffer() throws InterruptedException {
+        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new Integer(0));
+                q.put(new Integer(0));
+                assertTrue(q.offer(new Integer(0), SHORT_DELAY_MS, MILLISECONDS));
+                assertTrue(q.offer(new Integer(0), LONG_DELAY_MS, MILLISECONDS));
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * take retrieves elements in priority order
+     */
+    public void testTake() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.take());
+        }
+    }
+
+    /**
+     * Take removes existing elements until empty, then blocks interruptibly
+     */
+    public void testBlockingTake() throws InterruptedException {
+        final PriorityBlockingQueue q = populatedQueue(SIZE);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, q.take());
+                }
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.take();
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll0() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll(0, MILLISECONDS));
+        }
+        assertNull(q.poll(0, MILLISECONDS));
+    }
+
+    /**
+     * timed poll with nonzero timeout succeeds when non-empty, else times out
+     */
+    public void testTimedPoll() throws InterruptedException {
+        PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            long startTime = System.nanoTime();
+            assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+        long startTime = System.nanoTime();
+        assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        checkEmpty(q);
+    }
+
+    /**
+     * Interrupted timed poll throws InterruptedException instead of
+     * returning timeout status
+     */
+    public void testInterruptedTimedPoll() throws InterruptedException {
+        final BlockingQueue<Integer> q = populatedQueue(SIZE);
+        final CountDownLatch aboutToWait = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                for (int i = 0; i < SIZE; ++i) {
+                    assertEquals(i, (int) q.poll(LONG_DELAY_MS, MILLISECONDS));
+                }
+                aboutToWait.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {
+                    assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+                }
+            }});
+
+        aboutToWait.await();
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(one));
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        PriorityBlockingQueue p = new PriorityBlockingQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        PriorityBlockingQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            PriorityBlockingQueue q = populatedQueue(SIZE);
+            PriorityBlockingQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() throws InterruptedException {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.take());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() throws InterruptedException {
+        PriorityBlockingQueue<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.take());
+    }
+
+    /**
+     * toArray(incompatible array type) throws ArrayStoreException
+     */
+    public void testToArray1_BadArg() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        try {
+            q.toArray(new String[10]);
+            shouldThrow();
+        } catch (ArrayStoreException success) {}
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new PriorityBlockingQueue().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final PriorityBlockingQueue q = new PriorityBlockingQueue(3);
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * timed poll transfers elements across Executor tasks
+     */
+    public void testPollInExecutor() {
+        final PriorityBlockingQueue q = new PriorityBlockingQueue(2);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    checkEmpty(q);
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * drainTo(c) empties queue into another collection c
+     */
+    public void testDrainTo() {
+        PriorityBlockingQueue q = populatedQueue(SIZE);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(SIZE, l.size());
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        q.add(zero);
+        q.add(one);
+        assertFalse(q.isEmpty());
+        assertTrue(q.contains(zero));
+        assertTrue(q.contains(one));
+        l.clear();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(2, l.size());
+        for (int i = 0; i < 2; ++i)
+            assertEquals(l.get(i), new Integer(i));
+    }
+
+    /**
+     * drainTo empties queue
+     */
+    public void testDrainToWithActivePut() throws InterruptedException {
+        final PriorityBlockingQueue q = populatedQueue(SIZE);
+        Thread t = new Thread(new CheckedRunnable() {
+            public void realRun() {
+                q.put(new Integer(SIZE + 1));
+            }});
+
+        t.start();
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertTrue(l.size() >= SIZE);
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(l.get(i), new Integer(i));
+        t.join();
+        assertTrue(q.size() + l.size() >= SIZE);
+    }
+
+    /**
+     * drainTo(c, n) empties first min(n, size) elements of queue into c
+     */
+    public void testDrainToN() {
+        PriorityBlockingQueue q = new PriorityBlockingQueue(SIZE * 2);
+        for (int i = 0; i < SIZE + 2; ++i) {
+            for (int j = 0; j < SIZE; j++)
+                assertTrue(q.offer(new Integer(j)));
+            ArrayList l = new ArrayList();
+            q.drainTo(l, i);
+            int k = (i < SIZE) ? i : SIZE;
+            assertEquals(k, l.size());
+            assertEquals(SIZE - k, q.size());
+            for (int j = 0; j < k; ++j)
+                assertEquals(l.get(j), new Integer(j));
+            do {} while (q.poll() != null);
+        }
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?>[] qs = {
+            new PriorityBlockingQueue<Object>(),
+            populatedQueue(2),
+        };
+
+        for (Collection<?> q : qs) {
+            assertFalse(q.contains(null));
+            assertFalse(q.remove(null));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java
new file mode 100644
index 0000000..072abac
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/PriorityQueueTest.java
@@ -0,0 +1,541 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.PriorityQueue;
+import java.util.Queue;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class PriorityQueueTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return PriorityQueue.class; }
+            public Collection emptyCollection() { return new PriorityQueue(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return false; }
+        }
+        return newTestSuite(PriorityQueueTest.class,
+                            CollectionTest.testSuite(new Implementation()));
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Returns a new queue of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private PriorityQueue<Integer> populatedQueue(int n) {
+        PriorityQueue<Integer> q = new PriorityQueue<>(n);
+        assertTrue(q.isEmpty());
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.offer(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.offer(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        assertEquals((Integer) 0, q.peek());
+        return q;
+    }
+
+    /**
+     * A new queue has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, new PriorityQueue(SIZE).size());
+    }
+
+    /**
+     * Constructor throws IAE if capacity argument nonpositive
+     */
+    public void testConstructor2() {
+        try {
+            new PriorityQueue(0);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new PriorityQueue((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new PriorityQueue(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new PriorityQueue(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        PriorityQueue q = new PriorityQueue(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * The comparator used in constructor is used
+     */
+    public void testConstructor7() {
+        MyReverseComparator cmp = new MyReverseComparator();
+        PriorityQueue q = new PriorityQueue(SIZE, cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE - 1; i >= 0; --i)
+            assertEquals(ints[i], q.poll());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        PriorityQueue q = new PriorityQueue(2);
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.remove();
+        q.remove();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.remove();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * offer(null) throws NPE
+     */
+    public void testOfferNull() {
+        PriorityQueue q = new PriorityQueue(1);
+        try {
+            q.offer(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        PriorityQueue q = new PriorityQueue(1);
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Offer of comparable element succeeds
+     */
+    public void testOffer() {
+        PriorityQueue q = new PriorityQueue(1);
+        assertTrue(q.offer(zero));
+        assertTrue(q.offer(one));
+    }
+
+    /**
+     * Offer of non-Comparable throws CCE
+     */
+    public void testOfferNonComparable() {
+        PriorityQueue q = new PriorityQueue(1);
+        try {
+            q.offer(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {
+            assertTrue(q.isEmpty());
+            assertEquals(0, q.size());
+            assertNull(q.poll());
+        }
+    }
+
+    /**
+     * add of comparable succeeds
+     */
+    public void testAdd() {
+        PriorityQueue q = new PriorityQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            assertTrue(q.add(new Integer(i)));
+        }
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        PriorityQueue q = new PriorityQueue(1);
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        PriorityQueue q = new PriorityQueue(SIZE);
+        try {
+            q.addAll(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        PriorityQueue q = new PriorityQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Queue contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        PriorityQueue q = new PriorityQueue(SIZE);
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.poll());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.poll());
+        }
+        assertNull(q.poll());
+    }
+
+    /**
+     * peek returns next element, or null if empty
+     */
+    public void testPeek() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.peek());
+            assertEquals(i, q.poll());
+            assertTrue(q.peek() == null ||
+                       !q.peek().equals(i));
+        }
+        assertNull(q.peek());
+    }
+
+    /**
+     * element returns next element, or throws NSEE if empty
+     */
+    public void testElement() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.element());
+            assertEquals(i, q.poll());
+        }
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove removes next element, or throws NSEE if empty
+     */
+    public void testRemove() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.remove());
+        }
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        PriorityQueue q = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.poll();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        PriorityQueue q = populatedQueue(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        PriorityQueue q = populatedQueue(SIZE);
+        PriorityQueue p = new PriorityQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        PriorityQueue q = populatedQueue(SIZE);
+        PriorityQueue p = populatedQueue(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.remove();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            PriorityQueue q = populatedQueue(SIZE);
+            PriorityQueue p = populatedQueue(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.remove());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testToArray() {
+        PriorityQueue q = populatedQueue(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.poll());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testToArray2() {
+        PriorityQueue<Integer> q = populatedQueue(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.poll());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        PriorityQueue q = populatedQueue(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty collection has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new PriorityQueue().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final PriorityQueue q = new PriorityQueue(3);
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        PriorityQueue q = populatedQueue(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized queue has same elements
+     */
+    public void testSerialization() throws Exception {
+        Queue x = populatedQueue(SIZE);
+        Queue y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.remove(), y.remove());
+        }
+        assertTrue(y.isEmpty());
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/RecursiveActionTest.java b/ojluni/src/test/java/util/concurrent/tck/RecursiveActionTest.java
new file mode 100644
index 0000000..7ec6cc8
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/RecursiveActionTest.java
@@ -0,0 +1,1261 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.ForkJoinWorkerThread;
+import java.util.concurrent.RecursiveAction;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class RecursiveActionTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(RecursiveActionTest.class);
+    }
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool();
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            checkNotDone(a);
+
+            assertNull(pool.invoke(a));
+
+            checkCompletedNormally(a);
+        }
+    }
+
+    void checkNotDone(RecursiveAction a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        if (! ForkJoinTask.inForkJoinPool()) {
+            Thread.currentThread().interrupt();
+            try {
+                a.get();
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+            Thread.currentThread().interrupt();
+            try {
+                a.get(5L, SECONDS);
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+        }
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedNormally(RecursiveAction a) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+        assertNull(a.join());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertNull(a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertNull(a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCancelled(RecursiveAction a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(expected.getClass(), t.getClass());
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        public FJException() { super(); }
+        public FJException(Throwable cause) { super(cause); }
+    }
+
+    // A simple recursive action for testing
+    final class FibAction extends CheckedRecursiveAction {
+        final int number;
+        int result;
+        FibAction(int n) { number = n; }
+        protected void realCompute() {
+            int n = number;
+            if (n <= 1)
+                result = n;
+            else {
+                FibAction f1 = new FibAction(n - 1);
+                FibAction f2 = new FibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    // A recursive action failing in base case
+    static final class FailingFibAction extends RecursiveAction {
+        final int number;
+        int result;
+        FailingFibAction(int n) { number = n; }
+        public void compute() {
+            int n = number;
+            if (n <= 1)
+                throw new FJException();
+            else {
+                FailingFibAction f1 = new FailingFibAction(n - 1);
+                FailingFibAction f2 = new FailingFibAction(n - 2);
+                invokeAll(f1, f2);
+                result = f1.result + f2.result;
+            }
+        }
+    }
+
+    /**
+     * invoke returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks. getRawResult of a RecursiveAction returns null;
+     */
+    public void testInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertNull(f.invoke());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.quietlyInvoke();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.join());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
+     */
+    public void testJoinIgnoresInterrupts() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                final Thread currentThread = Thread.currentThread();
+
+                // test join()
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                assertNull(f.join());
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    Thread.interrupted();
+                    checkCancelled(f);
+                }
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    Thread.interrupted();
+                    checkCompletedAbnormally(f, success);
+                }
+
+                // test quietlyJoin()
+                f = new FibAction(8);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = new FibAction(8);
+                f.cancel(true);
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCancelled(f);
+
+                f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                assertSame(f, f.fork());
+                currentThread.interrupt();
+                f.quietlyJoin();
+                Thread.interrupted();
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+        a.reinitialize();
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * join/quietlyJoin of a forked task when not in ForkJoinPool
+     * succeeds in the presence of interrupts
+     */
+    public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
+        final SynchronousQueue<FibAction[]> sq =
+            new SynchronousQueue<FibAction[]>();
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws InterruptedException {
+                FibAction[] fibActions = new FibAction[6];
+                for (int i = 0; i < fibActions.length; i++)
+                    fibActions[i] = new FibAction(8);
+
+                fibActions[1].cancel(false);
+                fibActions[2].completeExceptionally(new FJException());
+                fibActions[4].cancel(true);
+                fibActions[5].completeExceptionally(new FJException());
+
+                for (int i = 0; i < fibActions.length; i++)
+                    fibActions[i].fork();
+
+                sq.put(fibActions);
+
+                helpQuiesce();
+            }};
+
+        Runnable r = new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                FibAction[] fibActions = sq.take();
+                FibAction f;
+                final Thread currentThread = Thread.currentThread();
+
+                // test join() ------------
+
+                f = fibActions[0];
+                assertFalse(ForkJoinTask.inForkJoinPool());
+                currentThread.interrupt();
+                assertNull(f.join());
+                assertTrue(Thread.interrupted());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = fibActions[1];
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    assertTrue(Thread.interrupted());
+                    checkCancelled(f);
+                }
+
+                f = fibActions[2];
+                currentThread.interrupt();
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    assertTrue(Thread.interrupted());
+                    checkCompletedAbnormally(f, success);
+                }
+
+                // test quietlyJoin() ---------
+
+                f = fibActions[3];
+                currentThread.interrupt();
+                f.quietlyJoin();
+                assertTrue(Thread.interrupted());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+
+                f = fibActions[4];
+                currentThread.interrupt();
+                f.quietlyJoin();
+                assertTrue(Thread.interrupted());
+                checkCancelled(f);
+
+                f = fibActions[5];
+                currentThread.interrupt();
+                f.quietlyJoin();
+                assertTrue(Thread.interrupted());
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+
+        Thread t;
+
+        t = newStartedThread(r);
+        testInvokeOnPool(mainPool(), a);
+        awaitTermination(t);
+
+        a.reinitialize();
+        t = newStartedThread(r);
+        testInvokeOnPool(singletonPool(), a);
+        awaitTermination(t);
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get());
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertNull(f.get(5L, SECONDS));
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get with null time unit throws NPE
+     */
+    public void testForkTimedGetNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, null);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertEquals(21, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                while (!f.isDone()) // wait out race
+                    ;
+                assertEquals(21, f.result);
+                assertEquals(0, getQueuedTaskCount());
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() throws Exception {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        final ForkJoinPool mainPool = mainPool();
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertSame(mainPool, getPool());
+            }};
+        testInvokeOnPool(mainPool, a);
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertNull(getPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertTrue(inForkJoinPool());
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                assertFalse(inForkJoinPool());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * getPool of current thread in pool returns its pool
+     */
+    public void testWorkerGetPool() {
+        final ForkJoinPool mainPool = mainPool();
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                ForkJoinWorkerThread w =
+                    (ForkJoinWorkerThread) Thread.currentThread();
+                assertSame(mainPool, w.getPool());
+            }};
+        testInvokeOnPool(mainPool, a);
+    }
+
+    /**
+     * getPoolIndex of current thread in pool returns 0 <= value < poolSize
+     */
+    public void testWorkerGetPoolIndex() {
+        final ForkJoinPool mainPool = mainPool();
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                ForkJoinWorkerThread w =
+                    (ForkJoinWorkerThread) Thread.currentThread();
+                assertTrue(w.getPoolIndex() >= 0);
+                // pool size can shrink after assigning index, so cannot check
+                // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
+            }};
+        testInvokeOnPool(mainPool, a);
+    }
+
+    /**
+     * setRawResult(null) succeeds
+     */
+    public void testSetRawResult() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                setRawResult(null);
+                assertNull(getRawResult());
+            }};
+        assertNull(a.invoke());
+    }
+
+    /**
+     * A reinitialized normally completed task may be re-invoked
+     */
+    public void testReinitialize() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    assertNull(f.invoke());
+                    assertEquals(21, f.result);
+                    checkCompletedNormally(f);
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * A reinitialized abnormally completed task may be re-invoked
+     */
+    public void testReinitializeAbnormal() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    try {
+                        f.invoke();
+                        shouldThrow();
+                    } catch (FJException success) {
+                        checkCompletedAbnormally(f, success);
+                    }
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invoke task suppresses execution invoking complete
+     */
+    public void testComplete() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                f.complete(null);
+                assertNull(f.invoke());
+                assertEquals(0, f.result);
+                checkCompletedNormally(f);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                invokeAll(f, g);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                invokeAll(f);
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                invokeAll(f, g, h);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f);
+                assertEquals(21, f.result);
+                checkCompletedNormally(g);
+                assertEquals(34, g.result);
+                checkCompletedNormally(g);
+                assertEquals(13, h.result);
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction g = new FailingFibAction(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction f = new FibAction(8);
+                FailingFibAction g = new FailingFibAction(9);
+                FibAction h = new FibAction(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FailingFibAction f = new FailingFibAction(8);
+                FibAction g = new FibAction(9);
+                FibAction h = new FibAction(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+            }};
+        testInvokeOnPool(mainPool(), a);
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction h = new FibAction(7);
+                assertSame(h, h.fork());
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+                checkCompletedNormally(h);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                assertNull(f.join());
+                checkCompletedNormally(f);
+                helpQuiesce();
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task
+     * without executing it
+     */
+    public void testPollNextLocalTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(singletonPool(), a);
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertNull(f.join());
+                helpQuiesce();
+                checkCompletedNormally(f);
+                checkCompletedNormally(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        RecursiveAction a = new CheckedRecursiveAction() {
+            protected void realCompute() {
+                FibAction g = new FibAction(9);
+                assertSame(g, g.fork());
+                FibAction f = new FibAction(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                checkCompletedNormally(f);
+                checkNotDone(g);
+            }};
+        testInvokeOnPool(asyncSingletonPool(), a);
+    }
+
+    /** Demo from RecursiveAction javadoc */
+    static class SortTask extends RecursiveAction {
+        final long[] array; final int lo, hi;
+        SortTask(long[] array, int lo, int hi) {
+            this.array = array; this.lo = lo; this.hi = hi;
+        }
+        SortTask(long[] array) { this(array, 0, array.length); }
+        protected void compute() {
+            if (hi - lo < THRESHOLD)
+                sortSequentially(lo, hi);
+            else {
+                int mid = (lo + hi) >>> 1;
+                invokeAll(new SortTask(array, lo, mid),
+                          new SortTask(array, mid, hi));
+                merge(lo, mid, hi);
+            }
+        }
+        // implementation details follow:
+        static final int THRESHOLD = 100;
+        void sortSequentially(int lo, int hi) {
+            Arrays.sort(array, lo, hi);
+        }
+        void merge(int lo, int mid, int hi) {
+            long[] buf = Arrays.copyOfRange(array, lo, mid);
+            for (int i = 0, j = lo, k = mid; i < buf.length; j++)
+                array[j] = (k == hi || buf[i] < array[k]) ?
+                    buf[i++] : array[k++];
+        }
+    }
+
+    /**
+     * SortTask demo works as advertised
+     */
+    public void testSortTaskDemo() {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        long[] array = new long[1007];
+        for (int i = 0; i < array.length; i++)
+            array[i] = rnd.nextLong();
+        long[] arrayClone = array.clone();
+        testInvokeOnPool(mainPool(), new SortTask(array));
+        Arrays.sort(arrayClone);
+        assertTrue(Arrays.equals(array, arrayClone));
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/RecursiveTaskTest.java b/ojluni/src/test/java/util/concurrent/tck/RecursiveTaskTest.java
new file mode 100644
index 0000000..39b3010
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/RecursiveTaskTest.java
@@ -0,0 +1,1054 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
+import java.util.concurrent.ForkJoinTask;
+import java.util.concurrent.RecursiveTask;
+import java.util.concurrent.TimeoutException;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class RecursiveTaskTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(RecursiveTaskTest.class);
+    }
+
+    private static ForkJoinPool mainPool() {
+        return new ForkJoinPool();
+    }
+
+    private static ForkJoinPool singletonPool() {
+        return new ForkJoinPool(1);
+    }
+
+    private static ForkJoinPool asyncSingletonPool() {
+        return new ForkJoinPool(1,
+                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
+                                null, true);
+    }
+
+    private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
+        try (PoolCleaner cleaner = cleaner(pool)) {
+            checkNotDone(a);
+
+            T result = pool.invoke(a);
+
+            checkCompletedNormally(a, result);
+            return result;
+        }
+    }
+
+    void checkNotDone(RecursiveTask a) {
+        assertFalse(a.isDone());
+        assertFalse(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertFalse(a.isCancelled());
+        assertNull(a.getException());
+        assertNull(a.getRawResult());
+
+        if (! ForkJoinTask.inForkJoinPool()) {
+            Thread.currentThread().interrupt();
+            try {
+                a.get();
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+            Thread.currentThread().interrupt();
+            try {
+                a.get(5L, SECONDS);
+                shouldThrow();
+            } catch (InterruptedException success) {
+            } catch (Throwable fail) { threadUnexpectedException(fail); }
+        }
+
+        try {
+            a.get(0L, SECONDS);
+            shouldThrow();
+        } catch (TimeoutException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertTrue(a.isCompletedNormally());
+        assertFalse(a.isCompletedAbnormally());
+        assertNull(a.getException());
+        assertSame(expected, a.getRawResult());
+        assertSame(expected, a.join());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+        try {
+            assertSame(expected, a.get());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+        try {
+            assertSame(expected, a.get(5L, SECONDS));
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    /**
+     * Waits for the task to complete, and checks that when it does,
+     * it will have an Integer result equals to the given int.
+     */
+    void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
+        Integer r = a.join();
+        assertEquals(expected, (int) r);
+        checkCompletedNormally(a, r);
+    }
+
+    /**
+     * Like checkCompletesNormally, but verifies that the task has
+     * already completed.
+     */
+    void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
+        Integer r = a.getRawResult();
+        assertEquals(expected, (int) r);
+        checkCompletedNormally(a, r);
+    }
+
+    void checkCancelled(RecursiveTask a) {
+        assertTrue(a.isDone());
+        assertTrue(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertTrue(a.getException() instanceof CancellationException);
+        assertNull(a.getRawResult());
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (CancellationException success) {
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    void checkCompletedAbnormally(RecursiveTask a, Throwable t) {
+        assertTrue(a.isDone());
+        assertFalse(a.isCancelled());
+        assertFalse(a.isCompletedNormally());
+        assertTrue(a.isCompletedAbnormally());
+        assertSame(t.getClass(), a.getException().getClass());
+        assertNull(a.getRawResult());
+        assertFalse(a.cancel(false));
+        assertFalse(a.cancel(true));
+
+        try {
+            a.join();
+            shouldThrow();
+        } catch (Throwable expected) {
+            assertSame(t.getClass(), expected.getClass());
+        }
+
+        try {
+            a.get();
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+
+        try {
+            a.get(5L, SECONDS);
+            shouldThrow();
+        } catch (ExecutionException success) {
+            assertSame(t.getClass(), success.getCause().getClass());
+        } catch (Throwable fail) { threadUnexpectedException(fail); }
+    }
+
+    public static final class FJException extends RuntimeException {
+        public FJException() { super(); }
+    }
+
+    // An invalid return value for Fib
+    static final Integer NoResult = Integer.valueOf(-17);
+
+    // A simple recursive task for testing
+    final class FibTask extends CheckedRecursiveTask<Integer> {
+        final int number;
+        FibTask(int n) { number = n; }
+        public Integer realCompute() {
+            int n = number;
+            if (n <= 1)
+                return n;
+            FibTask f1 = new FibTask(n - 1);
+            f1.fork();
+            return (new FibTask(n - 2)).compute() + f1.join();
+        }
+
+        public void publicSetRawResult(Integer result) {
+            setRawResult(result);
+        }
+    }
+
+    // A recursive action failing in base case
+    final class FailingFibTask extends RecursiveTask<Integer> {
+        final int number;
+        int result;
+        FailingFibTask(int n) { number = n; }
+        public Integer compute() {
+            int n = number;
+            if (n <= 1)
+                throw new FJException();
+            FailingFibTask f1 = new FailingFibTask(n - 1);
+            f1.fork();
+            return (new FibTask(n - 2)).compute() + f1.join();
+        }
+    }
+
+    /**
+     * invoke returns value when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks. getRawResult of a completed non-null task
+     * returns value;
+     */
+    public void testInvoke() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                Integer r = f.invoke();
+                assertEquals(21, (int) r);
+                checkCompletedNormally(f, r);
+                return r;
+            }};
+        assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes normally.
+     * isCompletedAbnormally and isCancelled return false for normally
+     * completed tasks
+     */
+    public void testQuietlyInvoke() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                f.quietlyInvoke();
+                checkCompletedNormally(f, 21);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * join of a forked task returns when task completes
+     */
+    public void testForkJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                Integer r = f.join();
+                assertEquals(21, (int) r);
+                checkCompletedNormally(f, r);
+                return r;
+            }};
+        assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * get of a forked task returns when task completes
+     */
+    public void testForkGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                Integer r = f.get();
+                assertEquals(21, (int) r);
+                checkCompletedNormally(f, r);
+                return r;
+            }};
+        assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * timed get of a forked task returns when task completes
+     */
+    public void testForkTimedGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                Integer r = f.get(5L, SECONDS);
+                assertEquals(21, (int) r);
+                checkCompletedNormally(f, r);
+                return r;
+            }};
+        assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes
+     */
+    public void testForkQuietlyJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                Integer r = f.getRawResult();
+                assertEquals(21, (int) r);
+                checkCompletedNormally(f, r);
+                return r;
+            }};
+        assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * helpQuiesce returns when tasks are complete.
+     * getQueuedTaskCount returns 0 when quiescent
+     */
+    public void testForkHelpQuiesce() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                helpQuiesce();
+                while (!f.isDone()) // wait out race
+                    ;
+                assertEquals(0, getQueuedTaskCount());
+                checkCompletedNormally(f, 21);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invoke task throws exception when task completes abnormally
+     */
+    public void testAbnormalInvoke() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                try {
+                    f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * quietlyInvoke task returns when task completes abnormally
+     */
+    public void testAbnormalQuietlyInvoke() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                f.quietlyInvoke();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * join of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.join();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FailingFibTask f = new FailingFibTask(8);
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.get();
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * timed get of a forked task throws exception when task completes abnormally
+     */
+    public void testAbnormalForkTimedGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FailingFibTask f = new FailingFibTask(8);
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (ExecutionException success) {
+                    Throwable cause = success.getCause();
+                    assertTrue(cause instanceof FJException);
+                    checkCompletedAbnormally(f, cause);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task completes abnormally
+     */
+    public void testAbnormalForkQuietlyJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                assertTrue(f.getException() instanceof FJException);
+                checkCompletedAbnormally(f, f.getException());
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invoke task throws exception when task cancelled
+     */
+    public void testCancelledInvoke() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertTrue(f.cancel(true));
+                try {
+                    Integer r = f.invoke();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * join of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.join();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FibTask f = new FibTask(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.get();
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * timed get of a forked task throws exception when task cancelled
+     */
+    public void testCancelledForkTimedGet() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() throws Exception {
+                FibTask f = new FibTask(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                try {
+                    Integer r = f.get(5L, SECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {
+                    checkCancelled(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * quietlyJoin of a forked task returns when task cancelled
+     */
+    public void testCancelledForkQuietlyJoin() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                assertTrue(f.cancel(true));
+                assertSame(f, f.fork());
+                f.quietlyJoin();
+                checkCancelled(f);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * getPool of executing task returns its pool
+     */
+    public void testGetPool() {
+        final ForkJoinPool mainPool = mainPool();
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                assertSame(mainPool, getPool());
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool, a));
+    }
+
+    /**
+     * getPool of non-FJ task returns null
+     */
+    public void testGetPool2() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                assertNull(getPool());
+                return NoResult;
+            }};
+        assertSame(NoResult, a.invoke());
+    }
+
+    /**
+     * inForkJoinPool of executing task returns true
+     */
+    public void testInForkJoinPool() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                assertTrue(inForkJoinPool());
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * inForkJoinPool of non-FJ task returns false
+     */
+    public void testInForkJoinPool2() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                assertFalse(inForkJoinPool());
+                return NoResult;
+            }};
+        assertSame(NoResult, a.invoke());
+    }
+
+    /**
+     * The value set by setRawResult is returned by getRawResult
+     */
+    public void testSetRawResult() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                setRawResult(NoResult);
+                assertSame(NoResult, getRawResult());
+                return NoResult;
+            }
+        };
+        assertSame(NoResult, a.invoke());
+    }
+
+    /**
+     * A reinitialized normally completed task may be re-invoked
+     */
+    public void testReinitialize() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    Integer r = f.invoke();
+                    assertEquals(21, (int) r);
+                    checkCompletedNormally(f, r);
+                    f.reinitialize();
+                    f.publicSetRawResult(null);
+                    checkNotDone(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * A reinitialized abnormally completed task may be re-invoked
+     */
+    public void testReinitializeAbnormal() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                checkNotDone(f);
+
+                for (int i = 0; i < 3; i++) {
+                    try {
+                        f.invoke();
+                        shouldThrow();
+                    } catch (FJException success) {
+                        checkCompletedAbnormally(f, success);
+                    }
+                    f.reinitialize();
+                    checkNotDone(f);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invoke task throws exception after invoking completeExceptionally
+     */
+    public void testCompleteExceptionally() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                f.completeExceptionally(new FJException());
+                try {
+                    Integer r = f.invoke();
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invoke task suppresses execution invoking complete
+     */
+    public void testComplete() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                f.complete(NoResult);
+                Integer r = f.invoke();
+                assertSame(NoResult, r);
+                checkCompletedNormally(f, NoResult);
+                return r;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(t1, t2) invokes all task arguments
+     */
+    public void testInvokeAll2() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FibTask g = new FibTask(9);
+                invokeAll(f, g);
+                checkCompletedNormally(f, 21);
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument invokes task
+     */
+    public void testInvokeAll1() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                invokeAll(f);
+                checkCompletedNormally(f, 21);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument invokes tasks
+     */
+    public void testInvokeAll3() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FibTask g = new FibTask(9);
+                FibTask h = new FibTask(7);
+                invokeAll(f, g, h);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f, 21);
+                checkCompletedNormally(g, 34);
+                checkCompletedNormally(h, 13);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(collection) invokes all tasks in the collection
+     */
+    public void testInvokeAllCollection() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FibTask g = new FibTask(9);
+                FibTask h = new FibTask(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                invokeAll(set);
+                assertTrue(f.isDone());
+                assertTrue(g.isDone());
+                assertTrue(h.isDone());
+                checkCompletedNormally(f, 21);
+                checkCompletedNormally(g, 34);
+                checkCompletedNormally(h, 13);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(tasks) with any null task throws NPE
+     */
+    public void testInvokeAllNPE() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FibTask g = new FibTask(9);
+                FibTask h = null;
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (NullPointerException success) {}
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(t1, t2) throw exception if any task does
+     */
+    public void testAbnormalInvokeAll2() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FailingFibTask g = new FailingFibTask(9);
+                try {
+                    invokeAll(f, g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(tasks) with 1 argument throws exception if task does
+     */
+    public void testAbnormalInvokeAll1() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask g = new FailingFibTask(9);
+                try {
+                    invokeAll(g);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(tasks) with > 2 argument throws exception if any task does
+     */
+    public void testAbnormalInvokeAll3() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask f = new FibTask(8);
+                FailingFibTask g = new FailingFibTask(9);
+                FibTask h = new FibTask(7);
+                try {
+                    invokeAll(f, g, h);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(g, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * invokeAll(collection) throws exception if any task does
+     */
+    public void testAbnormalInvokeAllCollection() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FailingFibTask f = new FailingFibTask(8);
+                FibTask g = new FibTask(9);
+                FibTask h = new FibTask(7);
+                HashSet set = new HashSet();
+                set.add(f);
+                set.add(g);
+                set.add(h);
+                try {
+                    invokeAll(set);
+                    shouldThrow();
+                } catch (FJException success) {
+                    checkCompletedAbnormally(f, success);
+                }
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(mainPool(), a));
+    }
+
+    /**
+     * tryUnfork returns true for most recent unexecuted task,
+     * and suppresses execution
+     */
+    public void testTryUnfork() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertTrue(f.tryUnfork());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+    }
+
+    /**
+     * getSurplusQueuedTaskCount returns > 0 when
+     * there are more tasks than threads
+     */
+    public void testGetSurplusQueuedTaskCount() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask h = new FibTask(7);
+                assertSame(h, h.fork());
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertTrue(getSurplusQueuedTaskCount() > 0);
+                helpQuiesce();
+                assertEquals(0, getSurplusQueuedTaskCount());
+                checkCompletedNormally(f, 21);
+                checkCompletedNormally(g, 34);
+                checkCompletedNormally(h, 13);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+    }
+
+    /**
+     * peekNextLocalTask returns most recent unexecuted task.
+     */
+    public void testPeekNextLocalTask() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(f, peekNextLocalTask());
+                checkCompletesNormally(f, 21);
+                helpQuiesce();
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+    }
+
+    /**
+     * pollNextLocalTask returns most recent unexecuted task
+     * without executing it
+     */
+    public void testPollNextLocalTask() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollNextLocalTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it
+     */
+    public void testPollTask() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(f, pollTask());
+                helpQuiesce();
+                checkNotDone(f);
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
+    }
+
+    /**
+     * peekNextLocalTask returns least recent unexecuted task in async mode
+     */
+    public void testPeekNextLocalTaskAsync() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(g, peekNextLocalTask());
+                assertEquals(21, (int) f.join());
+                helpQuiesce();
+                checkCompletedNormally(f, 21);
+                checkCompletedNormally(g, 34);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+    }
+
+    /**
+     * pollNextLocalTask returns least recent unexecuted task without
+     * executing it, in async mode
+     */
+    public void testPollNextLocalTaskAsync() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollNextLocalTask());
+                helpQuiesce();
+                checkCompletedNormally(f, 21);
+                checkNotDone(g);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+    }
+
+    /**
+     * pollTask returns an unexecuted task without executing it, in
+     * async mode
+     */
+    public void testPollTaskAsync() {
+        RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
+            public Integer realCompute() {
+                FibTask g = new FibTask(9);
+                assertSame(g, g.fork());
+                FibTask f = new FibTask(8);
+                assertSame(f, f.fork());
+                assertSame(g, pollTask());
+                helpQuiesce();
+                checkCompletedNormally(f, 21);
+                checkNotDone(g);
+                return NoResult;
+            }};
+        assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ReentrantLockTest.java b/ojluni/src/test/java/util/concurrent/tck/ReentrantLockTest.java
new file mode 100644
index 0000000..2e518d3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ReentrantLockTest.java
@@ -0,0 +1,1164 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.CyclicBarrier;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ReentrantLockTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ReentrantLockTest.class);
+    }
+
+    /**
+     * A checked runnable calling lockInterruptibly
+     */
+    class InterruptibleLockRunnable extends CheckedRunnable {
+        final ReentrantLock lock;
+        InterruptibleLockRunnable(ReentrantLock lock) { this.lock = lock; }
+        public void realRun() throws InterruptedException {
+            lock.lockInterruptibly();
+        }
+    }
+
+    /**
+     * A checked runnable calling lockInterruptibly that expects to be
+     * interrupted
+     */
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+        final ReentrantLock lock;
+        InterruptedLockRunnable(ReentrantLock lock) { this.lock = lock; }
+        public void realRun() throws InterruptedException {
+            lock.lockInterruptibly();
+        }
+    }
+
+    /**
+     * Subclass to expose protected methods
+     */
+    static class PublicReentrantLock extends ReentrantLock {
+        PublicReentrantLock() { super(); }
+        PublicReentrantLock(boolean fair) { super(fair); }
+        public Thread getOwner() {
+            return super.getOwner();
+        }
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
+        }
+        public Collection<Thread> getWaitingThreads(Condition c) {
+            return super.getWaitingThreads(c);
+        }
+    }
+
+    /**
+     * Releases write lock, checking that it had a hold count of 1.
+     */
+    void releaseLock(PublicReentrantLock lock) {
+        assertLockedByMoi(lock);
+        lock.unlock();
+        assertFalse(lock.isHeldByCurrentThread());
+        assertNotLocked(lock);
+    }
+
+    /**
+     * Spin-waits until lock.hasQueuedThread(t) becomes true.
+     */
+    void waitForQueuedThread(PublicReentrantLock lock, Thread t) {
+        long startTime = System.nanoTime();
+        while (!lock.hasQueuedThread(t)) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+        assertTrue(t.isAlive());
+        assertNotSame(t, lock.getOwner());
+    }
+
+    /**
+     * Checks that lock is not locked.
+     */
+    void assertNotLocked(PublicReentrantLock lock) {
+        assertFalse(lock.isLocked());
+        assertFalse(lock.isHeldByCurrentThread());
+        assertNull(lock.getOwner());
+        assertEquals(0, lock.getHoldCount());
+    }
+
+    /**
+     * Checks that lock is locked by the given thread.
+     */
+    void assertLockedBy(PublicReentrantLock lock, Thread t) {
+        assertTrue(lock.isLocked());
+        assertSame(t, lock.getOwner());
+        assertEquals(t == Thread.currentThread(),
+                     lock.isHeldByCurrentThread());
+        assertEquals(t == Thread.currentThread(),
+                     lock.getHoldCount() > 0);
+    }
+
+    /**
+     * Checks that lock is locked by the current thread.
+     */
+    void assertLockedByMoi(PublicReentrantLock lock) {
+        assertLockedBy(lock, Thread.currentThread());
+    }
+
+    /**
+     * Checks that condition c has no waiters.
+     */
+    void assertHasNoWaiters(PublicReentrantLock lock, Condition c) {
+        assertHasWaiters(lock, c, new Thread[] {});
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads.
+     */
+    void assertHasWaiters(PublicReentrantLock lock, Condition c,
+                          Thread... threads) {
+        lock.lock();
+        assertEquals(threads.length > 0, lock.hasWaiters(c));
+        assertEquals(threads.length, lock.getWaitQueueLength(c));
+        assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
+        assertEquals(threads.length, lock.getWaitingThreads(c).size());
+        assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
+                     new HashSet<Thread>(Arrays.asList(threads)));
+        lock.unlock();
+    }
+
+    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
+
+    /**
+     * Awaits condition "indefinitely" using the specified AwaitMethod.
+     */
+    void await(Condition c, AwaitMethod awaitMethod)
+            throws InterruptedException {
+        long timeoutMillis = 2 * LONG_DELAY_MS;
+        switch (awaitMethod) {
+        case await:
+            c.await();
+            break;
+        case awaitTimed:
+            assertTrue(c.await(timeoutMillis, MILLISECONDS));
+            break;
+        case awaitNanos:
+            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining > timeoutNanos / 2);
+            assertTrue(nanosRemaining <= timeoutNanos);
+            break;
+        case awaitUntil:
+            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+            break;
+        default:
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Constructor sets given fairness, and is in unlocked state
+     */
+    public void testConstructor() {
+        PublicReentrantLock lock;
+
+        lock = new PublicReentrantLock();
+        assertFalse(lock.isFair());
+        assertNotLocked(lock);
+
+        lock = new PublicReentrantLock(true);
+        assertTrue(lock.isFair());
+        assertNotLocked(lock);
+
+        lock = new PublicReentrantLock(false);
+        assertFalse(lock.isFair());
+        assertNotLocked(lock);
+    }
+
+    /**
+     * locking an unlocked lock succeeds
+     */
+    public void testLock()      { testLock(false); }
+    public void testLock_fair() { testLock(true); }
+    public void testLock(boolean fair) {
+        PublicReentrantLock lock = new PublicReentrantLock(fair);
+        lock.lock();
+        assertLockedByMoi(lock);
+        releaseLock(lock);
+    }
+
+    /**
+     * Unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testUnlock_IMSE()      { testUnlock_IMSE(false); }
+    public void testUnlock_IMSE_fair() { testUnlock_IMSE(true); }
+    public void testUnlock_IMSE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        try {
+            lock.unlock();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * tryLock on an unlocked lock succeeds
+     */
+    public void testTryLock()      { testTryLock(false); }
+    public void testTryLock_fair() { testTryLock(true); }
+    public void testTryLock(boolean fair) {
+        PublicReentrantLock lock = new PublicReentrantLock(fair);
+        assertTrue(lock.tryLock());
+        assertLockedByMoi(lock);
+        assertTrue(lock.tryLock());
+        assertLockedByMoi(lock);
+        lock.unlock();
+        releaseLock(lock);
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
+    public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+    public void testHasQueuedThreads(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertFalse(lock.hasQueuedThreads());
+        lock.lock();
+        assertFalse(lock.hasQueuedThreads());
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.hasQueuedThreads());
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(lock.hasQueuedThreads());
+        lock.unlock();
+        awaitTermination(t2);
+        assertFalse(lock.hasQueuedThreads());
+    }
+
+    /**
+     * getQueueLength reports number of waiting threads
+     */
+    public void testGetQueueLength()      { testGetQueueLength(false); }
+    public void testGetQueueLength_fair() { testGetQueueLength(true); }
+    public void testGetQueueLength(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertEquals(0, lock.getQueueLength());
+        lock.lock();
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertEquals(1, lock.getQueueLength());
+        lock.unlock();
+        awaitTermination(t2);
+        assertEquals(0, lock.getQueueLength());
+    }
+
+    /**
+     * hasQueuedThread(null) throws NPE
+     */
+    public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
+    public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
+    public void testHasQueuedThreadNPE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        try {
+            lock.hasQueuedThread(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasQueuedThread reports whether a thread is queued
+     */
+    public void testHasQueuedThread()      { testHasQueuedThread(false); }
+    public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
+    public void testHasQueuedThread(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertFalse(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        lock.lock();
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        lock.unlock();
+        awaitTermination(t2);
+        assertFalse(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+    }
+
+    /**
+     * getQueuedThreads includes waiting threads
+     */
+    public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
+    public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+    public void testGetQueuedThreads(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.lock();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertEquals(1, lock.getQueuedThreads().size());
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertEquals(2, lock.getQueuedThreads().size());
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        assertEquals(1, lock.getQueuedThreads().size());
+        lock.unlock();
+        awaitTermination(t2);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+    }
+
+    /**
+     * timed tryLock is interruptible
+     */
+    public void testTryLock_Interruptible()      { testTryLock_Interruptible(false); }
+    public void testTryLock_Interruptible_fair() { testTryLock_Interruptible(true); }
+    public void testTryLock_Interruptible(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        lock.lock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseLock(lock);
+    }
+
+    /**
+     * tryLock on a locked lock fails
+     */
+    public void testTryLockWhenLocked()      { testTryLockWhenLocked(false); }
+    public void testTryLockWhenLocked_fair() { testTryLockWhenLocked(true); }
+    public void testTryLockWhenLocked(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        lock.lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(lock.tryLock());
+            }});
+
+        awaitTermination(t);
+        releaseLock(lock);
+    }
+
+    /**
+     * Timed tryLock on a locked lock times out
+     */
+    public void testTryLock_Timeout()      { testTryLock_Timeout(false); }
+    public void testTryLock_Timeout_fair() { testTryLock_Timeout(true); }
+    public void testTryLock_Timeout(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final long timeoutMillis = timeoutMillis();
+        lock.lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertFalse(lock.tryLock(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            }});
+
+        awaitTermination(t);
+        releaseLock(lock);
+    }
+
+    /**
+     * getHoldCount returns number of recursive holds
+     */
+    public void testGetHoldCount()      { testGetHoldCount(false); }
+    public void testGetHoldCount_fair() { testGetHoldCount(true); }
+    public void testGetHoldCount(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        for (int i = 1; i <= SIZE; i++) {
+            lock.lock();
+            assertEquals(i, lock.getHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.unlock();
+            assertEquals(i - 1, lock.getHoldCount());
+        }
+    }
+
+    /**
+     * isLocked is true when locked and false when not
+     */
+    public void testIsLocked()      { testIsLocked(false); }
+    public void testIsLocked_fair() { testIsLocked(true); }
+    public void testIsLocked(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        try {
+            assertFalse(lock.isLocked());
+            lock.lock();
+            assertTrue(lock.isLocked());
+            lock.lock();
+            assertTrue(lock.isLocked());
+            lock.unlock();
+            assertTrue(lock.isLocked());
+            lock.unlock();
+            assertFalse(lock.isLocked());
+            final CyclicBarrier barrier = new CyclicBarrier(2);
+            Thread t = newStartedThread(new CheckedRunnable() {
+                    public void realRun() throws Exception {
+                        lock.lock();
+                        assertTrue(lock.isLocked());
+                        barrier.await();
+                        barrier.await();
+                        lock.unlock();
+                    }});
+
+            barrier.await();
+            assertTrue(lock.isLocked());
+            barrier.await();
+            awaitTermination(t);
+            assertFalse(lock.isLocked());
+        } catch (Exception fail) { threadUnexpectedException(fail); }
+    }
+
+    /**
+     * lockInterruptibly succeeds when unlocked, else is interruptible
+     */
+    public void testLockInterruptibly()      { testLockInterruptibly(false); }
+    public void testLockInterruptibly_fair() { testLockInterruptibly(true); }
+    public void testLockInterruptibly(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        try {
+            lock.lockInterruptibly();
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertLockedByMoi(lock);
+        Thread t = newStartedThread(new InterruptedLockRunnable(lock));
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        assertTrue(lock.isLocked());
+        assertTrue(lock.isHeldByCurrentThread());
+        awaitTermination(t);
+        releaseLock(lock);
+    }
+
+    /**
+     * Calling await without holding lock throws IllegalMonitorStateException
+     */
+    public void testAwait_IMSE()      { testAwait_IMSE(false); }
+    public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
+    public void testAwait_IMSE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+            long startTime = System.nanoTime();
+            try {
+                await(c, awaitMethod);
+                shouldThrow();
+            } catch (IllegalMonitorStateException success) {
+            } catch (InterruptedException e) { threadUnexpectedException(e); }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * Calling signal without holding lock throws IllegalMonitorStateException
+     */
+    public void testSignal_IMSE()      { testSignal_IMSE(false); }
+    public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
+    public void testSignal_IMSE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        try {
+            c.signal();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * awaitNanos without a signal times out
+     */
+    public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
+    public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
+    public void testAwaitNanos_Timeout(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final long timeoutMillis = timeoutMillis();
+        final long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+        lock.lock();
+        final long startTime = System.nanoTime();
+        try {
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining <= 0);
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        lock.unlock();
+    }
+
+    /**
+     * timed await without a signal times out
+     */
+    public void testAwait_Timeout()      { testAwait_Timeout(false); }
+    public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
+    public void testAwait_Timeout(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final long timeoutMillis = timeoutMillis();
+        lock.lock();
+        final long startTime = System.nanoTime();
+        try {
+            assertFalse(c.await(timeoutMillis, MILLISECONDS));
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        lock.unlock();
+    }
+
+    /**
+     * awaitUntil without a signal times out
+     */
+    public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
+    public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
+    public void testAwaitUntil_Timeout(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        lock.lock();
+        // We shouldn't assume that nanoTime and currentTimeMillis
+        // use the same time source, so don't use nanoTime here.
+        final java.util.Date delayedDate = delayedDate(timeoutMillis());
+        try {
+            assertFalse(c.awaitUntil(delayedDate));
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
+        lock.unlock();
+    }
+
+    /**
+     * await returns when signalled
+     */
+    public void testAwait()      { testAwait(false); }
+    public void testAwait_fair() { testAwait(true); }
+    public void testAwait(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch locked = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                locked.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        await(locked);
+        lock.lock();
+        assertHasWaiters(lock, c, t);
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertTrue(t.isAlive());
+        lock.unlock();
+        awaitTermination(t);
+    }
+
+    /**
+     * hasWaiters throws NPE if null
+     */
+    public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
+    public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
+    public void testHasWaitersNPE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        try {
+            lock.hasWaiters(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws NPE if null
+     */
+    public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
+    public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
+    public void testGetWaitQueueLengthNPE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        try {
+            lock.getWaitQueueLength(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws NPE if null
+     */
+    public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
+    public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
+    public void testGetWaitingThreadsNPE(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        try {
+            lock.getWaitingThreads(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalArgumentException if not owned
+     */
+    public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
+    public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
+    public void testHasWaitersIAE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final ReentrantLock lock2 = new ReentrantLock(fair);
+        try {
+            lock2.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalMonitorStateException if not locked
+     */
+    public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
+    public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
+    public void testHasWaitersIMSE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        try {
+            lock.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
+    public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
+    public void testGetWaitQueueLengthIAE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final ReentrantLock lock2 = new ReentrantLock(fair);
+        try {
+            lock2.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalMonitorStateException if not locked
+     */
+    public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
+    public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
+    public void testGetWaitQueueLengthIMSE(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        try {
+            lock.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
+    public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
+    public void testGetWaitingThreadsIAE(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final PublicReentrantLock lock2 = new PublicReentrantLock(fair);
+        try {
+            lock2.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws IllegalMonitorStateException if not locked
+     */
+    public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
+    public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
+    public void testGetWaitingThreadsIMSE(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        try {
+            lock.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * hasWaiters returns true when a thread is waiting, else false
+     */
+    public void testHasWaiters()      { testHasWaiters(false); }
+    public void testHasWaiters_fair() { testHasWaiters(true); }
+    public void testHasWaiters(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch pleaseSignal = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertHasNoWaiters(lock, c);
+                assertFalse(lock.hasWaiters(c));
+                pleaseSignal.countDown();
+                c.await();
+                assertHasNoWaiters(lock, c);
+                assertFalse(lock.hasWaiters(c));
+                lock.unlock();
+            }});
+
+        await(pleaseSignal);
+        lock.lock();
+        assertHasWaiters(lock, c, t);
+        assertTrue(lock.hasWaiters(c));
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertFalse(lock.hasWaiters(c));
+        lock.unlock();
+        awaitTermination(t);
+        assertHasNoWaiters(lock, c);
+    }
+
+    /**
+     * getWaitQueueLength returns number of waiting threads
+     */
+    public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
+    public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
+    public void testGetWaitQueueLength(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch locked1 = new CountDownLatch(1);
+        final CountDownLatch locked2 = new CountDownLatch(1);
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertFalse(lock.hasWaiters(c));
+                assertEquals(0, lock.getWaitQueueLength(c));
+                locked1.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertTrue(lock.hasWaiters(c));
+                assertEquals(1, lock.getWaitQueueLength(c));
+                locked2.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        lock.lock();
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.unlock();
+
+        t1.start();
+        await(locked1);
+
+        lock.lock();
+        assertHasWaiters(lock, c, t1);
+        assertEquals(1, lock.getWaitQueueLength(c));
+        lock.unlock();
+
+        t2.start();
+        await(locked2);
+
+        lock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        assertEquals(2, lock.getWaitQueueLength(c));
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.unlock();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+
+        assertHasNoWaiters(lock, c);
+    }
+
+    /**
+     * getWaitingThreads returns only and all waiting threads
+     */
+    public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
+    public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
+    public void testGetWaitingThreads(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch locked1 = new CountDownLatch(1);
+        final CountDownLatch locked2 = new CountDownLatch(1);
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertTrue(lock.getWaitingThreads(c).isEmpty());
+                locked1.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertFalse(lock.getWaitingThreads(c).isEmpty());
+                locked2.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        lock.lock();
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.unlock();
+
+        t1.start();
+        await(locked1);
+
+        lock.lock();
+        assertHasWaiters(lock, c, t1);
+        assertTrue(lock.getWaitingThreads(c).contains(t1));
+        assertFalse(lock.getWaitingThreads(c).contains(t2));
+        assertEquals(1, lock.getWaitingThreads(c).size());
+        lock.unlock();
+
+        t2.start();
+        await(locked2);
+
+        lock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        assertTrue(lock.getWaitingThreads(c).contains(t1));
+        assertTrue(lock.getWaitingThreads(c).contains(t2));
+        assertEquals(2, lock.getWaitingThreads(c).size());
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.unlock();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+
+        assertHasNoWaiters(lock, c);
+    }
+
+    /**
+     * awaitUninterruptibly is uninterruptible
+     */
+    public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
+    public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
+    public void testAwaitUninterruptibly(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                // Interrupt before awaitUninterruptibly
+                lock.lock();
+                pleaseInterrupt.countDown();
+                Thread.currentThread().interrupt();
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                lock.unlock();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                // Interrupt during awaitUninterruptibly
+                lock.lock();
+                pleaseInterrupt.countDown();
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                lock.unlock();
+            }});
+
+        await(pleaseInterrupt);
+        lock.lock();
+        lock.unlock();
+        t2.interrupt();
+
+        assertThreadStaysAlive(t1);
+        assertTrue(t2.isAlive());
+
+        lock.lock();
+        c.signalAll();
+        lock.unlock();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil is interruptible
+     */
+    public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
+    public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
+    public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
+    public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
+    public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
+        final PublicReentrantLock lock =
+            new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertLockedByMoi(lock);
+                assertHasNoWaiters(lock, c);
+                pleaseInterrupt.countDown();
+                try {
+                    await(c, awaitMethod);
+                } finally {
+                    assertLockedByMoi(lock);
+                    assertHasNoWaiters(lock, c);
+                    lock.unlock();
+                    assertFalse(Thread.interrupted());
+                }
+            }});
+
+        await(pleaseInterrupt);
+        assertHasWaiters(lock, c, t);
+        t.interrupt();
+        awaitTermination(t);
+        assertNotLocked(lock);
+    }
+
+    /**
+     * signalAll wakes up all threads
+     */
+    public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
+    public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
+    public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
+    public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
+    public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch pleaseSignal = new CountDownLatch(2);
+        class Awaiter extends CheckedRunnable {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                pleaseSignal.countDown();
+                await(c, awaitMethod);
+                lock.unlock();
+            }
+        }
+
+        Thread t1 = newStartedThread(new Awaiter());
+        Thread t2 = newStartedThread(new Awaiter());
+
+        await(pleaseSignal);
+        lock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * signal wakes up waiting threads in FIFO order
+     */
+    public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
+    public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
+    public void testSignalWakesFifo(boolean fair) {
+        final PublicReentrantLock lock =
+            new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch locked1 = new CountDownLatch(1);
+        final CountDownLatch locked2 = new CountDownLatch(1);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                locked1.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        await(locked1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                locked2.countDown();
+                c.await();
+                lock.unlock();
+            }});
+
+        await(locked2);
+
+        lock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        assertFalse(lock.hasQueuedThreads());
+        c.signal();
+        assertHasWaiters(lock, c, t2);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        lock.unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * await after multiple reentrant locking preserves lock count
+     */
+    public void testAwaitLockCount()      { testAwaitLockCount(false); }
+    public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
+    public void testAwaitLockCount(boolean fair) {
+        final PublicReentrantLock lock = new PublicReentrantLock(fair);
+        final Condition c = lock.newCondition();
+        final CountDownLatch pleaseSignal = new CountDownLatch(2);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                assertLockedByMoi(lock);
+                assertEquals(1, lock.getHoldCount());
+                pleaseSignal.countDown();
+                c.await();
+                assertLockedByMoi(lock);
+                assertEquals(1, lock.getHoldCount());
+                lock.unlock();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.lock();
+                lock.lock();
+                assertLockedByMoi(lock);
+                assertEquals(2, lock.getHoldCount());
+                pleaseSignal.countDown();
+                c.await();
+                assertLockedByMoi(lock);
+                assertEquals(2, lock.getHoldCount());
+                lock.unlock();
+                lock.unlock();
+            }});
+
+        await(pleaseSignal);
+        lock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        assertEquals(1, lock.getHoldCount());
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A serialized lock deserializes as unlocked
+     */
+    public void testSerialization()      { testSerialization(false); }
+    public void testSerialization_fair() { testSerialization(true); }
+    public void testSerialization(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        lock.lock();
+
+        ReentrantLock clone = serialClone(lock);
+        assertEquals(lock.isFair(), clone.isFair());
+        assertTrue(lock.isLocked());
+        assertFalse(clone.isLocked());
+        assertEquals(1, lock.getHoldCount());
+        assertEquals(0, clone.getHoldCount());
+        clone.lock();
+        clone.lock();
+        assertTrue(clone.isLocked());
+        assertEquals(2, clone.getHoldCount());
+        assertEquals(1, lock.getHoldCount());
+        clone.unlock();
+        clone.unlock();
+        assertTrue(lock.isLocked());
+        assertFalse(clone.isLocked());
+    }
+
+    /**
+     * toString indicates current lock state
+     */
+    public void testToString()      { testToString(false); }
+    public void testToString_fair() { testToString(true); }
+    public void testToString(boolean fair) {
+        final ReentrantLock lock = new ReentrantLock(fair);
+        assertTrue(lock.toString().contains("Unlocked"));
+        lock.lock();
+        assertTrue(lock.toString().contains("Locked by"));
+        lock.unlock();
+        assertTrue(lock.toString().contains("Unlocked"));
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ReentrantReadWriteLockTest.java b/ojluni/src/test/java/util/concurrent/tck/ReentrantReadWriteLockTest.java
new file mode 100644
index 0000000..dd2f4f3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ReentrantReadWriteLockTest.java
@@ -0,0 +1,1712 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ReentrantReadWriteLockTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ReentrantReadWriteLockTest.class);
+    }
+
+    /**
+     * A runnable calling lockInterruptibly
+     */
+    class InterruptibleLockRunnable extends CheckedRunnable {
+        final ReentrantReadWriteLock lock;
+        InterruptibleLockRunnable(ReentrantReadWriteLock l) { lock = l; }
+        public void realRun() throws InterruptedException {
+            lock.writeLock().lockInterruptibly();
+        }
+    }
+
+    /**
+     * A runnable calling lockInterruptibly that expects to be
+     * interrupted
+     */
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+        final ReentrantReadWriteLock lock;
+        InterruptedLockRunnable(ReentrantReadWriteLock l) { lock = l; }
+        public void realRun() throws InterruptedException {
+            lock.writeLock().lockInterruptibly();
+        }
+    }
+
+    /**
+     * Subclass to expose protected methods
+     */
+    static class PublicReentrantReadWriteLock extends ReentrantReadWriteLock {
+        PublicReentrantReadWriteLock() { super(); }
+        PublicReentrantReadWriteLock(boolean fair) { super(fair); }
+        public Thread getOwner() {
+            return super.getOwner();
+        }
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
+        }
+        public Collection<Thread> getWaitingThreads(Condition c) {
+            return super.getWaitingThreads(c);
+        }
+    }
+
+    /**
+     * Releases write lock, checking that it had a hold count of 1.
+     */
+    void releaseWriteLock(PublicReentrantReadWriteLock lock) {
+        ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
+        assertWriteLockedByMoi(lock);
+        assertEquals(1, lock.getWriteHoldCount());
+        writeLock.unlock();
+        assertNotWriteLocked(lock);
+    }
+
+    /**
+     * Spin-waits until lock.hasQueuedThread(t) becomes true.
+     */
+    void waitForQueuedThread(PublicReentrantReadWriteLock lock, Thread t) {
+        long startTime = System.nanoTime();
+        while (!lock.hasQueuedThread(t)) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+        assertTrue(t.isAlive());
+        assertNotSame(t, lock.getOwner());
+    }
+
+    /**
+     * Checks that lock is not write-locked.
+     */
+    void assertNotWriteLocked(PublicReentrantReadWriteLock lock) {
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.isWriteLockedByCurrentThread());
+        assertFalse(lock.writeLock().isHeldByCurrentThread());
+        assertEquals(0, lock.getWriteHoldCount());
+        assertEquals(0, lock.writeLock().getHoldCount());
+        assertNull(lock.getOwner());
+    }
+
+    /**
+     * Checks that lock is write-locked by the given thread.
+     */
+    void assertWriteLockedBy(PublicReentrantReadWriteLock lock, Thread t) {
+        assertTrue(lock.isWriteLocked());
+        assertSame(t, lock.getOwner());
+        assertEquals(t == Thread.currentThread(),
+                     lock.isWriteLockedByCurrentThread());
+        assertEquals(t == Thread.currentThread(),
+                     lock.writeLock().isHeldByCurrentThread());
+        assertEquals(t == Thread.currentThread(),
+                     lock.getWriteHoldCount() > 0);
+        assertEquals(t == Thread.currentThread(),
+                     lock.writeLock().getHoldCount() > 0);
+        assertEquals(0, lock.getReadLockCount());
+    }
+
+    /**
+     * Checks that lock is write-locked by the current thread.
+     */
+    void assertWriteLockedByMoi(PublicReentrantReadWriteLock lock) {
+        assertWriteLockedBy(lock, Thread.currentThread());
+    }
+
+    /**
+     * Checks that condition c has no waiters.
+     */
+    void assertHasNoWaiters(PublicReentrantReadWriteLock lock, Condition c) {
+        assertHasWaiters(lock, c, new Thread[] {});
+    }
+
+    /**
+     * Checks that condition c has exactly the given waiter threads.
+     */
+    void assertHasWaiters(PublicReentrantReadWriteLock lock, Condition c,
+                          Thread... threads) {
+        lock.writeLock().lock();
+        assertEquals(threads.length > 0, lock.hasWaiters(c));
+        assertEquals(threads.length, lock.getWaitQueueLength(c));
+        assertEquals(threads.length == 0, lock.getWaitingThreads(c).isEmpty());
+        assertEquals(threads.length, lock.getWaitingThreads(c).size());
+        assertEquals(new HashSet<Thread>(lock.getWaitingThreads(c)),
+                     new HashSet<Thread>(Arrays.asList(threads)));
+        lock.writeLock().unlock();
+    }
+
+    enum AwaitMethod { await, awaitTimed, awaitNanos, awaitUntil }
+
+    /**
+     * Awaits condition "indefinitely" using the specified AwaitMethod.
+     */
+    void await(Condition c, AwaitMethod awaitMethod)
+            throws InterruptedException {
+        long timeoutMillis = 2 * LONG_DELAY_MS;
+        switch (awaitMethod) {
+        case await:
+            c.await();
+            break;
+        case awaitTimed:
+            assertTrue(c.await(timeoutMillis, MILLISECONDS));
+            break;
+        case awaitNanos:
+            long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining > timeoutNanos / 2);
+            assertTrue(nanosRemaining <= timeoutNanos);
+            break;
+        case awaitUntil:
+            assertTrue(c.awaitUntil(delayedDate(timeoutMillis)));
+            break;
+        default:
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Constructor sets given fairness, and is in unlocked state
+     */
+    public void testConstructor() {
+        PublicReentrantReadWriteLock lock;
+
+        lock = new PublicReentrantReadWriteLock();
+        assertFalse(lock.isFair());
+        assertNotWriteLocked(lock);
+        assertEquals(0, lock.getReadLockCount());
+
+        lock = new PublicReentrantReadWriteLock(true);
+        assertTrue(lock.isFair());
+        assertNotWriteLocked(lock);
+        assertEquals(0, lock.getReadLockCount());
+
+        lock = new PublicReentrantReadWriteLock(false);
+        assertFalse(lock.isFair());
+        assertNotWriteLocked(lock);
+        assertEquals(0, lock.getReadLockCount());
+    }
+
+    /**
+     * write-locking and read-locking an unlocked lock succeed
+     */
+    public void testLock()      { testLock(false); }
+    public void testLock_fair() { testLock(true); }
+    public void testLock(boolean fair) {
+        PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        assertNotWriteLocked(lock);
+        lock.writeLock().lock();
+        assertWriteLockedByMoi(lock);
+        lock.writeLock().unlock();
+        assertNotWriteLocked(lock);
+        assertEquals(0, lock.getReadLockCount());
+        lock.readLock().lock();
+        assertNotWriteLocked(lock);
+        assertEquals(1, lock.getReadLockCount());
+        lock.readLock().unlock();
+        assertNotWriteLocked(lock);
+        assertEquals(0, lock.getReadLockCount());
+    }
+
+    /**
+     * getWriteHoldCount returns number of recursive holds
+     */
+    public void testGetWriteHoldCount()      { testGetWriteHoldCount(false); }
+    public void testGetWriteHoldCount_fair() { testGetWriteHoldCount(true); }
+    public void testGetWriteHoldCount(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        for (int i = 1; i <= SIZE; i++) {
+            lock.writeLock().lock();
+            assertEquals(i,lock.getWriteHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.writeLock().unlock();
+            assertEquals(i - 1,lock.getWriteHoldCount());
+        }
+    }
+
+    /**
+     * writelock.getHoldCount returns number of recursive holds
+     */
+    public void testGetHoldCount()      { testGetHoldCount(false); }
+    public void testGetHoldCount_fair() { testGetHoldCount(true); }
+    public void testGetHoldCount(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        for (int i = 1; i <= SIZE; i++) {
+            lock.writeLock().lock();
+            assertEquals(i,lock.writeLock().getHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.writeLock().unlock();
+            assertEquals(i - 1,lock.writeLock().getHoldCount());
+        }
+    }
+
+    /**
+     * getReadHoldCount returns number of recursive holds
+     */
+    public void testGetReadHoldCount()      { testGetReadHoldCount(false); }
+    public void testGetReadHoldCount_fair() { testGetReadHoldCount(true); }
+    public void testGetReadHoldCount(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        for (int i = 1; i <= SIZE; i++) {
+            lock.readLock().lock();
+            assertEquals(i,lock.getReadHoldCount());
+        }
+        for (int i = SIZE; i > 0; i--) {
+            lock.readLock().unlock();
+            assertEquals(i - 1,lock.getReadHoldCount());
+        }
+    }
+
+    /**
+     * write-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testWriteUnlock_IMSE()      { testWriteUnlock_IMSE(false); }
+    public void testWriteUnlock_IMSE_fair() { testWriteUnlock_IMSE(true); }
+    public void testWriteUnlock_IMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        try {
+            lock.writeLock().unlock();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * read-unlocking an unlocked lock throws IllegalMonitorStateException
+     */
+    public void testReadUnlock_IMSE()      { testReadUnlock_IMSE(false); }
+    public void testReadUnlock_IMSE_fair() { testReadUnlock_IMSE(true); }
+    public void testReadUnlock_IMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        try {
+            lock.readLock().unlock();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * write-lockInterruptibly is interruptible
+     */
+    public void testWriteLockInterruptibly_Interruptible()      { testWriteLockInterruptibly_Interruptible(false); }
+    public void testWriteLockInterruptibly_Interruptible_fair() { testWriteLockInterruptibly_Interruptible(true); }
+    public void testWriteLockInterruptibly_Interruptible(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lockInterruptibly();
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * timed write-tryLock is interruptible
+     */
+    public void testWriteTryLock_Interruptible()      { testWriteTryLock_Interruptible(false); }
+    public void testWriteTryLock_Interruptible_fair() { testWriteTryLock_Interruptible(true); }
+    public void testWriteTryLock_Interruptible(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * read-lockInterruptibly is interruptible
+     */
+    public void testReadLockInterruptibly_Interruptible()      { testReadLockInterruptibly_Interruptible(false); }
+    public void testReadLockInterruptibly_Interruptible_fair() { testReadLockInterruptibly_Interruptible(true); }
+    public void testReadLockInterruptibly_Interruptible(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().lockInterruptibly();
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * timed read-tryLock is interruptible
+     */
+    public void testReadTryLock_Interruptible()      { testReadTryLock_Interruptible(false); }
+    public void testReadTryLock_Interruptible_fair() { testReadTryLock_Interruptible(true); }
+    public void testReadTryLock_Interruptible(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().tryLock(2 * LONG_DELAY_MS, MILLISECONDS);
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * write-tryLock on an unlocked lock succeeds
+     */
+    public void testWriteTryLock()      { testWriteTryLock(false); }
+    public void testWriteTryLock_fair() { testWriteTryLock(true); }
+    public void testWriteTryLock(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        assertTrue(lock.writeLock().tryLock());
+        assertWriteLockedByMoi(lock);
+        assertTrue(lock.writeLock().tryLock());
+        assertWriteLockedByMoi(lock);
+        lock.writeLock().unlock();
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * write-tryLock fails if locked
+     */
+    public void testWriteTryLockWhenLocked()      { testWriteTryLockWhenLocked(false); }
+    public void testWriteTryLockWhenLocked_fair() { testWriteTryLockWhenLocked(true); }
+    public void testWriteTryLockWhenLocked(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(lock.writeLock().tryLock());
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * read-tryLock fails if locked
+     */
+    public void testReadTryLockWhenLocked()      { testReadTryLockWhenLocked(false); }
+    public void testReadTryLockWhenLocked_fair() { testReadTryLockWhenLocked(true); }
+    public void testReadTryLockWhenLocked(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(lock.readLock().tryLock());
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * Multiple threads can hold a read lock when not write-locked
+     */
+    public void testMultipleReadLocks()      { testMultipleReadLocks(false); }
+    public void testMultipleReadLocks_fair() { testMultipleReadLocks(true); }
+    public void testMultipleReadLocks(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                assertTrue(lock.readLock().tryLock());
+                lock.readLock().unlock();
+                assertTrue(lock.readLock().tryLock(LONG_DELAY_MS, MILLISECONDS));
+                lock.readLock().unlock();
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+
+        awaitTermination(t);
+        lock.readLock().unlock();
+    }
+
+    /**
+     * A writelock succeeds only after a reading thread unlocks
+     */
+    public void testWriteAfterReadLock()      { testWriteAfterReadLock(false); }
+    public void testWriteAfterReadLock_fair() { testWriteAfterReadLock(true); }
+    public void testWriteAfterReadLock(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(1, lock.getReadLockCount());
+                lock.writeLock().lock();
+                assertEquals(0, lock.getReadLockCount());
+                lock.writeLock().unlock();
+            }});
+        waitForQueuedThread(lock, t);
+        assertNotWriteLocked(lock);
+        assertEquals(1, lock.getReadLockCount());
+        lock.readLock().unlock();
+        assertEquals(0, lock.getReadLockCount());
+        awaitTermination(t);
+        assertNotWriteLocked(lock);
+    }
+
+    /**
+     * A writelock succeeds only after reading threads unlock
+     */
+    public void testWriteAfterMultipleReadLocks()      { testWriteAfterMultipleReadLocks(false); }
+    public void testWriteAfterMultipleReadLocks_fair() { testWriteAfterMultipleReadLocks(true); }
+    public void testWriteAfterMultipleReadLocks(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+        lock.readLock().lock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                assertEquals(3, lock.getReadLockCount());
+                lock.readLock().unlock();
+            }});
+        awaitTermination(t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(2, lock.getReadLockCount());
+                lock.writeLock().lock();
+                assertEquals(0, lock.getReadLockCount());
+                lock.writeLock().unlock();
+            }});
+        waitForQueuedThread(lock, t2);
+        assertNotWriteLocked(lock);
+        assertEquals(2, lock.getReadLockCount());
+        lock.readLock().unlock();
+        lock.readLock().unlock();
+        assertEquals(0, lock.getReadLockCount());
+        awaitTermination(t2);
+        assertNotWriteLocked(lock);
+    }
+
+    /**
+     * A thread that tries to acquire a fair read lock (non-reentrantly)
+     * will block if there is a waiting writer thread
+     */
+    public void testReaderWriterReaderFairFifo() {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(true);
+        final AtomicBoolean t1GotLock = new AtomicBoolean(false);
+
+        lock.readLock().lock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(1, lock.getReadLockCount());
+                lock.writeLock().lock();
+                assertEquals(0, lock.getReadLockCount());
+                t1GotLock.set(true);
+                lock.writeLock().unlock();
+            }});
+        waitForQueuedThread(lock, t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(1, lock.getReadLockCount());
+                lock.readLock().lock();
+                assertEquals(1, lock.getReadLockCount());
+                assertTrue(t1GotLock.get());
+                lock.readLock().unlock();
+            }});
+        waitForQueuedThread(lock, t2);
+        assertTrue(t1.isAlive());
+        assertNotWriteLocked(lock);
+        assertEquals(1, lock.getReadLockCount());
+        lock.readLock().unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertNotWriteLocked(lock);
+    }
+
+    /**
+     * Readlocks succeed only after a writing thread unlocks
+     */
+    public void testReadAfterWriteLock()      { testReadAfterWriteLock(false); }
+    public void testReadAfterWriteLock_fair() { testReadAfterWriteLock(true); }
+    public void testReadAfterWriteLock(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+
+        waitForQueuedThread(lock, t1);
+        waitForQueuedThread(lock, t2);
+        releaseWriteLock(lock);
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Read trylock succeeds if write locked by current thread
+     */
+    public void testReadHoldingWriteLock()      { testReadHoldingWriteLock(false); }
+    public void testReadHoldingWriteLock_fair() { testReadHoldingWriteLock(true); }
+    public void testReadHoldingWriteLock(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        assertTrue(lock.readLock().tryLock());
+        lock.readLock().unlock();
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * Read trylock succeeds (barging) even in the presence of waiting
+     * readers and/or writers
+     */
+    public void testReadTryLockBarging()      { testReadTryLockBarging(false); }
+    public void testReadTryLockBarging_fair() { testReadTryLockBarging(true); }
+    public void testReadTryLockBarging(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+
+        waitForQueuedThread(lock, t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+
+        if (fair)
+            waitForQueuedThread(lock, t2);
+
+        Thread t3 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().tryLock();
+                lock.readLock().unlock();
+            }});
+
+        assertTrue(lock.getReadLockCount() > 0);
+        awaitTermination(t3);
+        assertTrue(t1.isAlive());
+        if (fair) assertTrue(t2.isAlive());
+        lock.readLock().unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for readlock
+     */
+    public void testReadHoldingWriteLock2()      { testReadHoldingWriteLock2(false); }
+    public void testReadHoldingWriteLock2_fair() { testReadHoldingWriteLock2(true); }
+    public void testReadHoldingWriteLock2(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.readLock().lock();
+                lock.readLock().unlock();
+            }});
+
+        waitForQueuedThread(lock, t1);
+        waitForQueuedThread(lock, t2);
+        assertWriteLockedByMoi(lock);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        releaseWriteLock(lock);
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Read lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testReadHoldingWriteLock3()      { testReadHoldingWriteLock3(false); }
+    public void testReadHoldingWriteLock3_fair() { testReadHoldingWriteLock3(true); }
+    public void testReadHoldingWriteLock3(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        lock.readLock().lock();
+        lock.readLock().unlock();
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+
+        waitForQueuedThread(lock, t1);
+        waitForQueuedThread(lock, t2);
+        assertWriteLockedByMoi(lock);
+        lock.readLock().lock();
+        lock.readLock().unlock();
+        assertWriteLockedByMoi(lock);
+        lock.writeLock().unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Write lock succeeds if write locked by current thread even if
+     * other threads are waiting for writelock
+     */
+    public void testWriteHoldingWriteLock4()      { testWriteHoldingWriteLock4(false); }
+    public void testWriteHoldingWriteLock4_fair() { testWriteHoldingWriteLock4(true); }
+    public void testWriteHoldingWriteLock4(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        lock.writeLock().lock();
+        lock.writeLock().unlock();
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                lock.writeLock().lock();
+                lock.writeLock().unlock();
+            }});
+
+        waitForQueuedThread(lock, t1);
+        waitForQueuedThread(lock, t2);
+        assertWriteLockedByMoi(lock);
+        assertEquals(1, lock.getWriteHoldCount());
+        lock.writeLock().lock();
+        assertWriteLockedByMoi(lock);
+        assertEquals(2, lock.getWriteHoldCount());
+        lock.writeLock().unlock();
+        assertWriteLockedByMoi(lock);
+        assertEquals(1, lock.getWriteHoldCount());
+        lock.writeLock().unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * Read tryLock succeeds if readlocked but not writelocked
+     */
+    public void testTryLockWhenReadLocked()      { testTryLockWhenReadLocked(false); }
+    public void testTryLockWhenReadLocked_fair() { testTryLockWhenReadLocked(true); }
+    public void testTryLockWhenReadLocked(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertTrue(lock.readLock().tryLock());
+                lock.readLock().unlock();
+            }});
+
+        awaitTermination(t);
+        lock.readLock().unlock();
+    }
+
+    /**
+     * write tryLock fails when readlocked
+     */
+    public void testWriteTryLockWhenReadLocked()      { testWriteTryLockWhenReadLocked(false); }
+    public void testWriteTryLockWhenReadLocked_fair() { testWriteTryLockWhenReadLocked(true); }
+    public void testWriteTryLockWhenReadLocked(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.readLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertFalse(lock.writeLock().tryLock());
+            }});
+
+        awaitTermination(t);
+        lock.readLock().unlock();
+    }
+
+    /**
+     * write timed tryLock times out if locked
+     */
+    public void testWriteTryLock_Timeout()      { testWriteTryLock_Timeout(false); }
+    public void testWriteTryLock_Timeout_fair() { testWriteTryLock_Timeout(true); }
+    public void testWriteTryLock_Timeout(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final long timeoutMillis = timeoutMillis();
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertFalse(lock.writeLock().tryLock(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            }});
+
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * read timed tryLock times out if write-locked
+     */
+    public void testReadTryLock_Timeout()      { testReadTryLock_Timeout(false); }
+    public void testReadTryLock_Timeout_fair() { testReadTryLock_Timeout(true); }
+    public void testReadTryLock_Timeout(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                long timeoutMillis = timeoutMillis();
+                assertFalse(lock.readLock().tryLock(timeoutMillis, MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            }});
+
+        awaitTermination(t);
+        assertTrue(lock.writeLock().isHeldByCurrentThread());
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * write lockInterruptibly succeeds if unlocked, else is interruptible
+     */
+    public void testWriteLockInterruptibly()      { testWriteLockInterruptibly(false); }
+    public void testWriteLockInterruptibly_fair() { testWriteLockInterruptibly(true); }
+    public void testWriteLockInterruptibly(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        try {
+            lock.writeLock().lockInterruptibly();
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lockInterruptibly();
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        assertTrue(lock.writeLock().isHeldByCurrentThread());
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * read lockInterruptibly succeeds if lock free else is interruptible
+     */
+    public void testReadLockInterruptibly()      { testReadLockInterruptibly(false); }
+    public void testReadLockInterruptibly_fair() { testReadLockInterruptibly(true); }
+    public void testReadLockInterruptibly(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        try {
+            lock.readLock().lockInterruptibly();
+            lock.readLock().unlock();
+            lock.writeLock().lockInterruptibly();
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.readLock().lockInterruptibly();
+            }});
+
+        waitForQueuedThread(lock, t);
+        t.interrupt();
+        awaitTermination(t);
+        releaseWriteLock(lock);
+    }
+
+    /**
+     * Calling await without holding lock throws IllegalMonitorStateException
+     */
+    public void testAwait_IMSE()      { testAwait_IMSE(false); }
+    public void testAwait_IMSE_fair() { testAwait_IMSE(true); }
+    public void testAwait_IMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        for (AwaitMethod awaitMethod : AwaitMethod.values()) {
+            long startTime = System.nanoTime();
+            try {
+                await(c, awaitMethod);
+                shouldThrow();
+            } catch (IllegalMonitorStateException success) {
+            } catch (InterruptedException fail) {
+                threadUnexpectedException(fail);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * Calling signal without holding lock throws IllegalMonitorStateException
+     */
+    public void testSignal_IMSE()      { testSignal_IMSE(false); }
+    public void testSignal_IMSE_fair() { testSignal_IMSE(true); }
+    public void testSignal_IMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        try {
+            c.signal();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * Calling signalAll without holding lock throws IllegalMonitorStateException
+     */
+    public void testSignalAll_IMSE()      { testSignalAll_IMSE(false); }
+    public void testSignalAll_IMSE_fair() { testSignalAll_IMSE(true); }
+    public void testSignalAll_IMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        try {
+            c.signalAll();
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * awaitNanos without a signal times out
+     */
+    public void testAwaitNanos_Timeout()      { testAwaitNanos_Timeout(false); }
+    public void testAwaitNanos_Timeout_fair() { testAwaitNanos_Timeout(true); }
+    public void testAwaitNanos_Timeout(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final long timeoutMillis = timeoutMillis();
+        lock.writeLock().lock();
+        final long startTime = System.nanoTime();
+        final long timeoutNanos = MILLISECONDS.toNanos(timeoutMillis);
+        try {
+            long nanosRemaining = c.awaitNanos(timeoutNanos);
+            assertTrue(nanosRemaining <= 0);
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * timed await without a signal times out
+     */
+    public void testAwait_Timeout()      { testAwait_Timeout(false); }
+    public void testAwait_Timeout_fair() { testAwait_Timeout(true); }
+    public void testAwait_Timeout(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final long timeoutMillis = timeoutMillis();
+        lock.writeLock().lock();
+        final long startTime = System.nanoTime();
+        try {
+            assertFalse(c.await(timeoutMillis, MILLISECONDS));
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * awaitUntil without a signal times out
+     */
+    public void testAwaitUntil_Timeout()      { testAwaitUntil_Timeout(false); }
+    public void testAwaitUntil_Timeout_fair() { testAwaitUntil_Timeout(true); }
+    public void testAwaitUntil_Timeout(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        lock.writeLock().lock();
+        // We shouldn't assume that nanoTime and currentTimeMillis
+        // use the same time source, so don't use nanoTime here.
+        final java.util.Date delayedDate = delayedDate(timeoutMillis());
+        try {
+            assertFalse(c.awaitUntil(delayedDate));
+        } catch (InterruptedException fail) { threadUnexpectedException(fail); }
+        assertTrue(new java.util.Date().getTime() >= delayedDate.getTime());
+        lock.writeLock().unlock();
+    }
+
+    /**
+     * await returns when signalled
+     */
+    public void testAwait()      { testAwait(false); }
+    public void testAwait_fair() { testAwait(true); }
+    public void testAwait(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                locked.countDown();
+                c.await();
+                lock.writeLock().unlock();
+            }});
+
+        await(locked);
+        lock.writeLock().lock();
+        assertHasWaiters(lock, c, t);
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertTrue(t.isAlive());
+        lock.writeLock().unlock();
+        awaitTermination(t);
+    }
+
+    /**
+     * awaitUninterruptibly is uninterruptible
+     */
+    public void testAwaitUninterruptibly()      { testAwaitUninterruptibly(false); }
+    public void testAwaitUninterruptibly_fair() { testAwaitUninterruptibly(true); }
+    public void testAwaitUninterruptibly(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(2);
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                // Interrupt before awaitUninterruptibly
+                lock.writeLock().lock();
+                pleaseInterrupt.countDown();
+                Thread.currentThread().interrupt();
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                lock.writeLock().unlock();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                // Interrupt during awaitUninterruptibly
+                lock.writeLock().lock();
+                pleaseInterrupt.countDown();
+                c.awaitUninterruptibly();
+                assertTrue(Thread.interrupted());
+                lock.writeLock().unlock();
+            }});
+
+        await(pleaseInterrupt);
+        lock.writeLock().lock();
+        lock.writeLock().unlock();
+        t2.interrupt();
+
+        assertThreadStaysAlive(t1);
+        assertTrue(t2.isAlive());
+
+        lock.writeLock().lock();
+        c.signalAll();
+        lock.writeLock().unlock();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * await/awaitNanos/awaitUntil is interruptible
+     */
+    public void testInterruptible_await()           { testInterruptible(false, AwaitMethod.await); }
+    public void testInterruptible_await_fair()      { testInterruptible(true,  AwaitMethod.await); }
+    public void testInterruptible_awaitTimed()      { testInterruptible(false, AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitTimed_fair() { testInterruptible(true,  AwaitMethod.awaitTimed); }
+    public void testInterruptible_awaitNanos()      { testInterruptible(false, AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitNanos_fair() { testInterruptible(true,  AwaitMethod.awaitNanos); }
+    public void testInterruptible_awaitUntil()      { testInterruptible(false, AwaitMethod.awaitUntil); }
+    public void testInterruptible_awaitUntil_fair() { testInterruptible(true,  AwaitMethod.awaitUntil); }
+    public void testInterruptible(boolean fair, final AwaitMethod awaitMethod) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertWriteLockedByMoi(lock);
+                assertHasNoWaiters(lock, c);
+                locked.countDown();
+                try {
+                    await(c, awaitMethod);
+                } finally {
+                    assertWriteLockedByMoi(lock);
+                    assertHasNoWaiters(lock, c);
+                    lock.writeLock().unlock();
+                    assertFalse(Thread.interrupted());
+                }
+            }});
+
+        await(locked);
+        assertHasWaiters(lock, c, t);
+        t.interrupt();
+        awaitTermination(t);
+        assertNotWriteLocked(lock);
+    }
+
+    /**
+     * signalAll wakes up all threads
+     */
+    public void testSignalAll_await()           { testSignalAll(false, AwaitMethod.await); }
+    public void testSignalAll_await_fair()      { testSignalAll(true,  AwaitMethod.await); }
+    public void testSignalAll_awaitTimed()      { testSignalAll(false, AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitTimed_fair() { testSignalAll(true,  AwaitMethod.awaitTimed); }
+    public void testSignalAll_awaitNanos()      { testSignalAll(false, AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitNanos_fair() { testSignalAll(true,  AwaitMethod.awaitNanos); }
+    public void testSignalAll_awaitUntil()      { testSignalAll(false, AwaitMethod.awaitUntil); }
+    public void testSignalAll_awaitUntil_fair() { testSignalAll(true,  AwaitMethod.awaitUntil); }
+    public void testSignalAll(boolean fair, final AwaitMethod awaitMethod) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(2);
+        final Lock writeLock = lock.writeLock();
+        class Awaiter extends CheckedRunnable {
+            public void realRun() throws InterruptedException {
+                writeLock.lock();
+                locked.countDown();
+                await(c, awaitMethod);
+                writeLock.unlock();
+            }
+        }
+
+        Thread t1 = newStartedThread(new Awaiter());
+        Thread t2 = newStartedThread(new Awaiter());
+
+        await(locked);
+        writeLock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        writeLock.unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * signal wakes up waiting threads in FIFO order
+     */
+    public void testSignalWakesFifo()      { testSignalWakesFifo(false); }
+    public void testSignalWakesFifo_fair() { testSignalWakesFifo(true); }
+    public void testSignalWakesFifo(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked1 = new CountDownLatch(1);
+        final CountDownLatch locked2 = new CountDownLatch(1);
+        final Lock writeLock = lock.writeLock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                writeLock.lock();
+                locked1.countDown();
+                c.await();
+                writeLock.unlock();
+            }});
+
+        await(locked1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                writeLock.lock();
+                locked2.countDown();
+                c.await();
+                writeLock.unlock();
+            }});
+
+        await(locked2);
+
+        writeLock.lock();
+        assertHasWaiters(lock, c, t1, t2);
+        assertFalse(lock.hasQueuedThreads());
+        c.signal();
+        assertHasWaiters(lock, c, t2);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        writeLock.unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * await after multiple reentrant locking preserves lock count
+     */
+    public void testAwaitLockCount()      { testAwaitLockCount(false); }
+    public void testAwaitLockCount_fair() { testAwaitLockCount(true); }
+    public void testAwaitLockCount(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(2);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertWriteLockedByMoi(lock);
+                assertEquals(1, lock.writeLock().getHoldCount());
+                locked.countDown();
+                c.await();
+                assertWriteLockedByMoi(lock);
+                assertEquals(1, lock.writeLock().getHoldCount());
+                lock.writeLock().unlock();
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                lock.writeLock().lock();
+                assertWriteLockedByMoi(lock);
+                assertEquals(2, lock.writeLock().getHoldCount());
+                locked.countDown();
+                c.await();
+                assertWriteLockedByMoi(lock);
+                assertEquals(2, lock.writeLock().getHoldCount());
+                lock.writeLock().unlock();
+                lock.writeLock().unlock();
+            }});
+
+        await(locked);
+        lock.writeLock().lock();
+        assertHasWaiters(lock, c, t1, t2);
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.writeLock().unlock();
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * A serialized lock deserializes as unlocked
+     */
+    public void testSerialization()      { testSerialization(false); }
+    public void testSerialization_fair() { testSerialization(true); }
+    public void testSerialization(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        lock.writeLock().lock();
+        lock.readLock().lock();
+
+        ReentrantReadWriteLock clone = serialClone(lock);
+        assertEquals(lock.isFair(), clone.isFair());
+        assertTrue(lock.isWriteLocked());
+        assertFalse(clone.isWriteLocked());
+        assertEquals(1, lock.getReadLockCount());
+        assertEquals(0, clone.getReadLockCount());
+        clone.writeLock().lock();
+        clone.readLock().lock();
+        assertTrue(clone.isWriteLocked());
+        assertEquals(1, clone.getReadLockCount());
+        clone.readLock().unlock();
+        clone.writeLock().unlock();
+        assertFalse(clone.isWriteLocked());
+        assertEquals(1, lock.getReadLockCount());
+        assertEquals(0, clone.getReadLockCount());
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
+    public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+    public void testHasQueuedThreads(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertFalse(lock.hasQueuedThreads());
+        lock.writeLock().lock();
+        assertFalse(lock.hasQueuedThreads());
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.hasQueuedThreads());
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(lock.hasQueuedThreads());
+        lock.writeLock().unlock();
+        awaitTermination(t2);
+        assertFalse(lock.hasQueuedThreads());
+    }
+
+    /**
+     * hasQueuedThread(null) throws NPE
+     */
+    public void testHasQueuedThreadNPE()      { testHasQueuedThreadNPE(false); }
+    public void testHasQueuedThreadNPE_fair() { testHasQueuedThreadNPE(true); }
+    public void testHasQueuedThreadNPE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        try {
+            lock.hasQueuedThread(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasQueuedThread reports whether a thread is queued
+     */
+    public void testHasQueuedThread()      { testHasQueuedThread(false); }
+    public void testHasQueuedThread_fair() { testHasQueuedThread(true); }
+    public void testHasQueuedThread(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertFalse(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        lock.writeLock().lock();
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(lock.hasQueuedThread(t1));
+        assertTrue(lock.hasQueuedThread(t2));
+        lock.writeLock().unlock();
+        awaitTermination(t2);
+        assertFalse(lock.hasQueuedThread(t1));
+        assertFalse(lock.hasQueuedThread(t2));
+    }
+
+    /**
+     * getQueueLength reports number of waiting threads
+     */
+    public void testGetQueueLength()      { testGetQueueLength(false); }
+    public void testGetQueueLength_fair() { testGetQueueLength(true); }
+    public void testGetQueueLength(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertEquals(0, lock.getQueueLength());
+        lock.writeLock().lock();
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertEquals(1, lock.getQueueLength());
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertEquals(1, lock.getQueueLength());
+        lock.writeLock().unlock();
+        awaitTermination(t2);
+        assertEquals(0, lock.getQueueLength());
+    }
+
+    /**
+     * getQueuedThreads includes waiting threads
+     */
+    public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
+    public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+    public void testGetQueuedThreads(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        Thread t1 = new Thread(new InterruptedLockRunnable(lock));
+        Thread t2 = new Thread(new InterruptibleLockRunnable(lock));
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.writeLock().lock();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        t1.start();
+        waitForQueuedThread(lock, t1);
+        assertEquals(1, lock.getQueuedThreads().size());
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        t2.start();
+        waitForQueuedThread(lock, t2);
+        assertEquals(2, lock.getQueuedThreads().size());
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        assertEquals(1, lock.getQueuedThreads().size());
+        lock.writeLock().unlock();
+        awaitTermination(t2);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+    }
+
+    /**
+     * hasWaiters throws NPE if null
+     */
+    public void testHasWaitersNPE()      { testHasWaitersNPE(false); }
+    public void testHasWaitersNPE_fair() { testHasWaitersNPE(true); }
+    public void testHasWaitersNPE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        try {
+            lock.hasWaiters(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws NPE if null
+     */
+    public void testGetWaitQueueLengthNPE()      { testGetWaitQueueLengthNPE(false); }
+    public void testGetWaitQueueLengthNPE_fair() { testGetWaitQueueLengthNPE(true); }
+    public void testGetWaitQueueLengthNPE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        try {
+            lock.getWaitQueueLength(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws NPE if null
+     */
+    public void testGetWaitingThreadsNPE()      { testGetWaitingThreadsNPE(false); }
+    public void testGetWaitingThreadsNPE_fair() { testGetWaitingThreadsNPE(true); }
+    public void testGetWaitingThreadsNPE(boolean fair) {
+        final PublicReentrantReadWriteLock lock = new PublicReentrantReadWriteLock(fair);
+        try {
+            lock.getWaitingThreads(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalArgumentException if not owned
+     */
+    public void testHasWaitersIAE()      { testHasWaitersIAE(false); }
+    public void testHasWaitersIAE_fair() { testHasWaitersIAE(true); }
+    public void testHasWaitersIAE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
+        try {
+            lock2.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * hasWaiters throws IllegalMonitorStateException if not locked
+     */
+    public void testHasWaitersIMSE()      { testHasWaitersIMSE(false); }
+    public void testHasWaitersIMSE_fair() { testHasWaitersIMSE(true); }
+    public void testHasWaitersIMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        try {
+            lock.hasWaiters(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitQueueLengthIAE()      { testGetWaitQueueLengthIAE(false); }
+    public void testGetWaitQueueLengthIAE_fair() { testGetWaitQueueLengthIAE(true); }
+    public void testGetWaitQueueLengthIAE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final ReentrantReadWriteLock lock2 = new ReentrantReadWriteLock(fair);
+        try {
+            lock2.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitQueueLength throws IllegalMonitorStateException if not locked
+     */
+    public void testGetWaitQueueLengthIMSE()      { testGetWaitQueueLengthIMSE(false); }
+    public void testGetWaitQueueLengthIMSE_fair() { testGetWaitQueueLengthIMSE(true); }
+    public void testGetWaitQueueLengthIMSE(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        try {
+            lock.getWaitQueueLength(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws IllegalArgumentException if not owned
+     */
+    public void testGetWaitingThreadsIAE()      { testGetWaitingThreadsIAE(false); }
+    public void testGetWaitingThreadsIAE_fair() { testGetWaitingThreadsIAE(true); }
+    public void testGetWaitingThreadsIAE(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final PublicReentrantReadWriteLock lock2 =
+            new PublicReentrantReadWriteLock(fair);
+        try {
+            lock2.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * getWaitingThreads throws IllegalMonitorStateException if not locked
+     */
+    public void testGetWaitingThreadsIMSE()      { testGetWaitingThreadsIMSE(false); }
+    public void testGetWaitingThreadsIMSE_fair() { testGetWaitingThreadsIMSE(true); }
+    public void testGetWaitingThreadsIMSE(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        try {
+            lock.getWaitingThreads(c);
+            shouldThrow();
+        } catch (IllegalMonitorStateException success) {}
+    }
+
+    /**
+     * hasWaiters returns true when a thread is waiting, else false
+     */
+    public void testHasWaiters()      { testHasWaiters(false); }
+    public void testHasWaiters_fair() { testHasWaiters(true); }
+    public void testHasWaiters(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertHasNoWaiters(lock, c);
+                assertFalse(lock.hasWaiters(c));
+                locked.countDown();
+                c.await();
+                assertHasNoWaiters(lock, c);
+                assertFalse(lock.hasWaiters(c));
+                lock.writeLock().unlock();
+            }});
+
+        await(locked);
+        lock.writeLock().lock();
+        assertHasWaiters(lock, c, t);
+        assertTrue(lock.hasWaiters(c));
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertFalse(lock.hasWaiters(c));
+        lock.writeLock().unlock();
+        awaitTermination(t);
+        assertHasNoWaiters(lock, c);
+    }
+
+    /**
+     * getWaitQueueLength returns number of waiting threads
+     */
+    public void testGetWaitQueueLength()      { testGetWaitQueueLength(false); }
+    public void testGetWaitQueueLength_fair() { testGetWaitQueueLength(true); }
+    public void testGetWaitQueueLength(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertEquals(0, lock.getWaitQueueLength(c));
+                locked.countDown();
+                c.await();
+                lock.writeLock().unlock();
+            }});
+
+        await(locked);
+        lock.writeLock().lock();
+        assertHasWaiters(lock, c, t);
+        assertEquals(1, lock.getWaitQueueLength(c));
+        c.signal();
+        assertHasNoWaiters(lock, c);
+        assertEquals(0, lock.getWaitQueueLength(c));
+        lock.writeLock().unlock();
+        awaitTermination(t);
+    }
+
+    /**
+     * getWaitingThreads returns only and all waiting threads
+     */
+    public void testGetWaitingThreads()      { testGetWaitingThreads(false); }
+    public void testGetWaitingThreads_fair() { testGetWaitingThreads(true); }
+    public void testGetWaitingThreads(boolean fair) {
+        final PublicReentrantReadWriteLock lock =
+            new PublicReentrantReadWriteLock(fair);
+        final Condition c = lock.writeLock().newCondition();
+        final CountDownLatch locked1 = new CountDownLatch(1);
+        final CountDownLatch locked2 = new CountDownLatch(1);
+        Thread t1 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertTrue(lock.getWaitingThreads(c).isEmpty());
+                locked1.countDown();
+                c.await();
+                lock.writeLock().unlock();
+            }});
+
+        Thread t2 = new Thread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLock().lock();
+                assertFalse(lock.getWaitingThreads(c).isEmpty());
+                locked2.countDown();
+                c.await();
+                lock.writeLock().unlock();
+            }});
+
+        lock.writeLock().lock();
+        assertTrue(lock.getWaitingThreads(c).isEmpty());
+        lock.writeLock().unlock();
+
+        t1.start();
+        await(locked1);
+        t2.start();
+        await(locked2);
+
+        lock.writeLock().lock();
+        assertTrue(lock.hasWaiters(c));
+        assertTrue(lock.getWaitingThreads(c).contains(t1));
+        assertTrue(lock.getWaitingThreads(c).contains(t2));
+        assertEquals(2, lock.getWaitingThreads(c).size());
+        c.signalAll();
+        assertHasNoWaiters(lock, c);
+        lock.writeLock().unlock();
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+
+        assertHasNoWaiters(lock, c);
+    }
+
+    /**
+     * toString indicates current lock state
+     */
+    public void testToString()      { testToString(false); }
+    public void testToString_fair() { testToString(true); }
+    public void testToString(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        assertTrue(lock.toString().contains("Write locks = 0"));
+        assertTrue(lock.toString().contains("Read locks = 0"));
+        lock.writeLock().lock();
+        assertTrue(lock.toString().contains("Write locks = 1"));
+        assertTrue(lock.toString().contains("Read locks = 0"));
+        lock.writeLock().lock();
+        assertTrue(lock.toString().contains("Write locks = 2"));
+        assertTrue(lock.toString().contains("Read locks = 0"));
+        lock.writeLock().unlock();
+        lock.writeLock().unlock();
+        lock.readLock().lock();
+        assertTrue(lock.toString().contains("Write locks = 0"));
+        assertTrue(lock.toString().contains("Read locks = 1"));
+        lock.readLock().lock();
+        assertTrue(lock.toString().contains("Write locks = 0"));
+        assertTrue(lock.toString().contains("Read locks = 2"));
+    }
+
+    /**
+     * readLock.toString indicates current lock state
+     */
+    public void testReadLockToString()      { testReadLockToString(false); }
+    public void testReadLockToString_fair() { testReadLockToString(true); }
+    public void testReadLockToString(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        assertTrue(lock.readLock().toString().contains("Read locks = 0"));
+        lock.readLock().lock();
+        assertTrue(lock.readLock().toString().contains("Read locks = 1"));
+        lock.readLock().lock();
+        assertTrue(lock.readLock().toString().contains("Read locks = 2"));
+        lock.readLock().unlock();
+        assertTrue(lock.readLock().toString().contains("Read locks = 1"));
+        lock.readLock().unlock();
+        assertTrue(lock.readLock().toString().contains("Read locks = 0"));
+    }
+
+    /**
+     * writeLock.toString indicates current lock state
+     */
+    public void testWriteLockToString()      { testWriteLockToString(false); }
+    public void testWriteLockToString_fair() { testWriteLockToString(true); }
+    public void testWriteLockToString(boolean fair) {
+        final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(fair);
+        assertTrue(lock.writeLock().toString().contains("Unlocked"));
+        lock.writeLock().lock();
+        assertTrue(lock.writeLock().toString().contains("Locked by"));
+        lock.writeLock().unlock();
+        assertTrue(lock.writeLock().toString().contains("Unlocked"));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java b/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java
new file mode 100644
index 0000000..d0e4182
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java
@@ -0,0 +1,1312 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Delayed;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.RunnableScheduledFuture;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ScheduledExecutorSubclassTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ScheduledExecutorSubclassTest.class);
+    }
+
+    static class CustomTask<V> implements RunnableScheduledFuture<V> {
+        private final RunnableScheduledFuture<V> task;
+        volatile boolean ran;
+        CustomTask(RunnableScheduledFuture<V> task) { this.task = task; }
+        public boolean isPeriodic() { return task.isPeriodic(); }
+        public void run() {
+            ran = true;
+            task.run();
+        }
+        public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
+        public int compareTo(Delayed t) {
+            return task.compareTo(((CustomTask)t).task);
+        }
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            return task.cancel(mayInterruptIfRunning);
+        }
+        public boolean isCancelled() { return task.isCancelled(); }
+        public boolean isDone() { return task.isDone(); }
+        public V get() throws InterruptedException, ExecutionException {
+            V v = task.get();
+            assertTrue(ran);
+            return v;
+        }
+        public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+            V v = task.get(time, unit);
+            assertTrue(ran);
+            return v;
+        }
+    }
+
+    public class CustomExecutor extends ScheduledThreadPoolExecutor {
+
+        protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
+            return new CustomTask<V>(task);
+        }
+
+        protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
+            return new CustomTask<V>(task);
+        }
+        CustomExecutor(int corePoolSize) { super(corePoolSize); }
+        CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
+            super(corePoolSize, handler);
+        }
+
+        CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
+            super(corePoolSize, threadFactory);
+        }
+        CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
+                       RejectedExecutionHandler handler) {
+            super(corePoolSize, threadFactory, handler);
+        }
+
+    }
+
+    /**
+     * execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
+            p.execute(task);
+            await(done);
+        }
+    }
+
+    /**
+     * delayed schedule of callable successfully executes after delay
+     */
+    public void testSchedule1() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final long startTime = System.nanoTime();
+            Callable task = new CheckedCallable<Boolean>() {
+                public Boolean realCall() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                    return Boolean.TRUE;
+                }};
+            Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+            assertSame(Boolean.TRUE, f.get());
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * delayed schedule of runnable successfully executes after delay
+     */
+    public void testSchedule3() throws Exception {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+            await(done);
+            assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * scheduleAtFixedRate executes runnable after given initial delay
+     */
+    public void testSchedule4() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            ScheduledFuture f =
+                p.scheduleAtFixedRate(task, timeoutMillis(),
+                                      LONG_DELAY_MS, MILLISECONDS);
+            await(done);
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            f.cancel(true);
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay executes runnable after given initial delay
+     */
+    public void testSchedule5() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            ScheduledFuture f =
+                p.scheduleWithFixedDelay(task, timeoutMillis(),
+                                         LONG_DELAY_MS, MILLISECONDS);
+            await(done);
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            f.cancel(true);
+        }
+    }
+
+    static class RunnableCounter implements Runnable {
+        AtomicInteger count = new AtomicInteger(0);
+        public void run() { count.getAndIncrement(); }
+    }
+
+    /**
+     * scheduleAtFixedRate executes series of tasks at given rate.
+     * Eventually, it must hold that:
+     *   cycles - 1 <= elapsedMillis/delay < cycles
+     */
+    public void testFixedRateSequence() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
+                final long startTime = System.nanoTime();
+                final int cycles = 8;
+                final CountDownLatch done = new CountDownLatch(cycles);
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() { done.countDown(); }};
+                final ScheduledFuture periodicTask =
+                    p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (elapsedMillis <= cycles * delay)
+                    return;
+                // else retry with longer delay
+            }
+            fail("unexpected execution rate");
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay executes series of tasks with given period.
+     * Eventually, it must hold that each task starts at least delay and at
+     * most 2 * delay after the termination of the previous task.
+     */
+    public void testFixedDelaySequence() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
+                final long startTime = System.nanoTime();
+                final AtomicLong previous = new AtomicLong(startTime);
+                final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+                final int cycles = 8;
+                final CountDownLatch done = new CountDownLatch(cycles);
+                final int d = delay;
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() {
+                        long now = System.nanoTime();
+                        long elapsedMillis
+                            = NANOSECONDS.toMillis(now - previous.get());
+                        if (done.getCount() == cycles) { // first execution
+                            if (elapsedMillis >= d)
+                                tryLongerDelay.set(true);
+                        } else {
+                            assertTrue(elapsedMillis >= d);
+                            if (elapsedMillis >= 2 * d)
+                                tryLongerDelay.set(true);
+                        }
+                        previous.set(now);
+                        done.countDown();
+                    }};
+                final ScheduledFuture periodicTask =
+                    p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (!tryLongerDelay.get())
+                    return;
+                // else retry with longer delay
+            }
+            fail("unexpected execution rate");
+        }
+    }
+
+    /**
+     * execute(null) throws NPE
+     */
+    public void testExecuteNull() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * schedule(null) throws NPE
+     */
+    public void testScheduleNull() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                TrackedCallable callable = null;
+                Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * execute throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule1_RejectedExecutionException() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpRunnable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * schedule throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule2_RejectedExecutionException() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * schedule callable throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule3_RejectedExecutionException() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * scheduleAtFixedRate throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleAtFixedRate1_RejectedExecutionException() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleAtFixedRate(new NoOpRunnable(),
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleWithFixedDelay1_RejectedExecutionException() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleWithFixedDelay(new NoOpRunnable(),
+                                         MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * getActiveCount increases but doesn't overestimate, when a
+     * thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getActiveCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getActiveCount());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getActiveCount());
+        }
+    }
+
+    /**
+     * getCompletedTaskCount increases, but doesn't overestimate,
+     * when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        final ThreadPoolExecutor p = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(0, p.getCompletedTaskCount());
+                    threadProceed.await();
+                    threadDone.countDown();
+                }});
+            await(threadStarted);
+            assertEquals(0, p.getCompletedTaskCount());
+            threadProceed.countDown();
+            threadDone.await();
+            long startTime = System.nanoTime();
+            while (p.getCompletedTaskCount() != 1) {
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    fail("timed out");
+                Thread.yield();
+            }
+        }
+    }
+
+    /**
+     * getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
+    }
+
+    /**
+     * getLargestPoolSize increases, but doesn't overestimate, when
+     * multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        final int THREADS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(THREADS);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+            assertEquals(0, p.getLargestPoolSize());
+            for (int i = 0; i < THREADS; i++)
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadsStarted.countDown();
+                        await(done);
+                        assertEquals(THREADS, p.getLargestPoolSize());
+                    }});
+            await(threadsStarted);
+            assertEquals(THREADS, p.getLargestPoolSize());
+        }
+        assertEquals(THREADS, p.getLargestPoolSize());
+    }
+
+    /**
+     * getPoolSize increases, but doesn't overestimate, when threads
+     * become active
+     */
+    public void testGetPoolSize() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getPoolSize());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getTaskCount increases, but doesn't overestimate, when tasks
+     * submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+        }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
+    }
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() {
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final CustomExecutor p = new CustomExecutor(1, threadFactory);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() {
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * isShutdown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isShutdown());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
+        }
+    }
+
+    /**
+     * isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminated());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminated());
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
+    }
+
+    /**
+     * isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                tasks[i] = p.schedule(r, 1, MILLISECONDS);
+            }
+            await(threadStarted);
+            BlockingQueue<Runnable> q = p.getQueue();
+            assertTrue(q.contains(tasks[tasks.length - 1]));
+            assertFalse(q.contains(tasks[0]));
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            for (int i = 0; i < tasks.length; i++) {
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                tasks[i] = p.schedule(r, 1, MILLISECONDS);
+            }
+            await(threadStarted);
+            BlockingQueue<Runnable> q = p.getQueue();
+            assertFalse(p.remove((Runnable)tasks[0]));
+            assertTrue(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p.remove((Runnable)tasks[4]));
+            assertFalse(p.remove((Runnable)tasks[4]));
+            assertFalse(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p.remove((Runnable)tasks[3]));
+            assertFalse(q.contains((Runnable)tasks[3]));
+        }
+    }
+
+    /**
+     * purge removes cancelled tasks from the queue
+     */
+    public void testPurge() throws InterruptedException {
+        final ScheduledFuture[] tasks = new ScheduledFuture[5];
+        final Runnable releaser = new Runnable() { public void run() {
+            for (ScheduledFuture task : tasks)
+                if (task != null) task.cancel(true); }};
+        final CustomExecutor p = new CustomExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, releaser)) {
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                                      LONG_DELAY_MS, MILLISECONDS);
+            int max = tasks.length;
+            if (tasks[4].cancel(true)) --max;
+            if (tasks[3].cancel(true)) --max;
+            // There must eventually be an interference-free point at
+            // which purge will not fail. (At worst, when queue is empty.)
+            long startTime = System.nanoTime();
+            do {
+                p.purge();
+                long count = p.getTaskCount();
+                if (count == max)
+                    return;
+            } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
+            fail("Purge failed to remove cancelled tasks");
+        }
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CustomExecutor p = new CustomExecutor(poolSize);
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow_delayedTasks() throws InterruptedException {
+        final CustomExecutor p = new CustomExecutor(1);
+        List<ScheduledFuture> tasks = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            Runnable r = new NoOpRunnable();
+            tasks.add(p.schedule(r, 9, SECONDS));
+            tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
+            tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
+        }
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
+        assertEquals(tasks.size(), queuedTasks.size());
+        for (ScheduledFuture task : tasks) {
+            assertFalse(((CustomTask)task).ran);
+            assertFalse(task.isDone());
+            assertFalse(task.isCancelled());
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+    }
+
+    /**
+     * By default, periodic tasks are cancelled at shutdown.
+     * By default, delayed tasks keep running after shutdown.
+     * Check that changing the default values work:
+     * - setExecuteExistingDelayedTasksAfterShutdownPolicy
+     * - setContinueExistingPeriodicTasksAfterShutdownPolicy
+     */
+    public void testShutdown_cancellation() throws Exception {
+        Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
+        for (Boolean policy : allBooleans)
+    {
+        final int poolSize = 2;
+        final CustomExecutor p = new CustomExecutor(poolSize);
+        final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
+        final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
+        final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
+        if (policy != null) {
+            p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
+            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
+            p.setRemoveOnCancelPolicy(policy);
+        }
+        assertEquals(effectiveDelayedPolicy,
+                     p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertEquals(effectivePeriodicPolicy,
+                     p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+        assertEquals(effectiveRemovePolicy,
+                     p.getRemoveOnCancelPolicy());
+        // Strategy: Wedge the pool with poolSize "blocker" threads
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
+        final CountDownLatch unblock = new CountDownLatch(1);
+        final CountDownLatch periodicLatch1 = new CountDownLatch(2);
+        final CountDownLatch periodicLatch2 = new CountDownLatch(2);
+        Runnable task = new CheckedRunnable() { public void realRun()
+                                                    throws InterruptedException {
+            poolBlocked.countDown();
+            assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
+            ran.getAndIncrement();
+        }};
+        List<Future<?>> blockers = new ArrayList<>();
+        List<Future<?>> periodics = new ArrayList<>();
+        List<Future<?>> delayeds = new ArrayList<>();
+        for (int i = 0; i < poolSize; i++)
+            blockers.add(p.submit(task));
+        assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+
+        periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
+                                            1, 1, MILLISECONDS));
+        periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
+                                               1, 1, MILLISECONDS));
+        delayeds.add(p.schedule(task, 1, MILLISECONDS));
+
+        assertTrue(p.getQueue().containsAll(periodics));
+        assertTrue(p.getQueue().containsAll(delayeds));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p.isShutdown());
+        assertFalse(p.isTerminated());
+        for (Future<?> periodic : periodics) {
+            assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
+            assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
+        }
+        for (Future<?> delayed : delayeds) {
+            assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
+            assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
+        }
+        if (testImplementationDetails) {
+            assertEquals(effectivePeriodicPolicy,
+                         p.getQueue().containsAll(periodics));
+            assertEquals(effectiveDelayedPolicy,
+                         p.getQueue().containsAll(delayeds));
+        }
+        // Release all pool threads
+        unblock.countDown();
+
+        for (Future<?> delayed : delayeds) {
+            if (effectiveDelayedPolicy) {
+                assertNull(delayed.get());
+            }
+        }
+        if (effectivePeriodicPolicy) {
+            assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
+            for (Future<?> periodic : periodics) {
+                assertTrue(periodic.cancel(false));
+                assertTrue(periodic.isCancelled());
+                assertTrue(periodic.isDone());
+            }
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
+    }}
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        final ExecutorService e = new CustomExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p = new CustomExecutor(2);
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorTest.java b/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorTest.java
new file mode 100644
index 0000000..7f85917
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ScheduledExecutorTest.java
@@ -0,0 +1,1284 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ScheduledExecutorTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ScheduledExecutorTest.class);
+    }
+
+    /**
+     * execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
+            p.execute(task);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * delayed schedule of callable successfully executes after delay
+     */
+    public void testSchedule1() throws Exception {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Callable task = new CheckedCallable<Boolean>() {
+                public Boolean realCall() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                    return Boolean.TRUE;
+                }};
+            Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+            assertSame(Boolean.TRUE, f.get());
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            assertTrue(done.await(0L, MILLISECONDS));
+        }
+    }
+
+    /**
+     * delayed schedule of runnable successfully executes after delay
+     */
+    public void testSchedule3() throws Exception {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
+            await(done);
+            assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+        }
+    }
+
+    /**
+     * scheduleAtFixedRate executes runnable after given initial delay
+     */
+    public void testSchedule4() throws Exception {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            ScheduledFuture f =
+                p.scheduleAtFixedRate(task, timeoutMillis(),
+                                      LONG_DELAY_MS, MILLISECONDS);
+            await(done);
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            f.cancel(true);
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay executes runnable after given initial delay
+     */
+    public void testSchedule5() throws Exception {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final long startTime = System.nanoTime();
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable task = new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                    assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                }};
+            ScheduledFuture f =
+                p.scheduleWithFixedDelay(task, timeoutMillis(),
+                                         LONG_DELAY_MS, MILLISECONDS);
+            await(done);
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            f.cancel(true);
+        }
+    }
+
+    static class RunnableCounter implements Runnable {
+        AtomicInteger count = new AtomicInteger(0);
+        public void run() { count.getAndIncrement(); }
+    }
+
+    /**
+     * scheduleAtFixedRate executes series of tasks at given rate.
+     * Eventually, it must hold that:
+     *   cycles - 1 <= elapsedMillis/delay < cycles
+     */
+    public void testFixedRateSequence() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
+                final long startTime = System.nanoTime();
+                final int cycles = 8;
+                final CountDownLatch done = new CountDownLatch(cycles);
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() { done.countDown(); }};
+                final ScheduledFuture periodicTask =
+                    p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (elapsedMillis <= cycles * delay)
+                    return;
+                // else retry with longer delay
+            }
+            fail("unexpected execution rate");
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay executes series of tasks with given period.
+     * Eventually, it must hold that each task starts at least delay and at
+     * most 2 * delay after the termination of the previous task.
+     */
+    public void testFixedDelaySequence() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
+                final long startTime = System.nanoTime();
+                final AtomicLong previous = new AtomicLong(startTime);
+                final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
+                final int cycles = 8;
+                final CountDownLatch done = new CountDownLatch(cycles);
+                final int d = delay;
+                final Runnable task = new CheckedRunnable() {
+                    public void realRun() {
+                        long now = System.nanoTime();
+                        long elapsedMillis
+                            = NANOSECONDS.toMillis(now - previous.get());
+                        if (done.getCount() == cycles) { // first execution
+                            if (elapsedMillis >= d)
+                                tryLongerDelay.set(true);
+                        } else {
+                            assertTrue(elapsedMillis >= d);
+                            if (elapsedMillis >= 2 * d)
+                                tryLongerDelay.set(true);
+                        }
+                        previous.set(now);
+                        done.countDown();
+                    }};
+                final ScheduledFuture periodicTask =
+                    p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
+                final int totalDelayMillis = (cycles - 1) * delay;
+                await(done, totalDelayMillis + cycles * LONG_DELAY_MS);
+                periodicTask.cancel(true);
+                final long elapsedMillis = millisElapsedSince(startTime);
+                assertTrue(elapsedMillis >= totalDelayMillis);
+                if (!tryLongerDelay.get())
+                    return;
+                // else retry with longer delay
+            }
+            fail("unexpected execution rate");
+        }
+    }
+
+    /**
+     * execute(null) throws NPE
+     */
+    public void testExecuteNull() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * schedule(null) throws NPE
+     */
+    public void testScheduleNull() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                TrackedCallable callable = null;
+                Future f = p.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * execute throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule1_RejectedExecutionException() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpRunnable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * schedule throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule2_RejectedExecutionException() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * schedule callable throws RejectedExecutionException if shutdown
+     */
+    public void testSchedule3_RejectedExecutionException() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.schedule(new NoOpCallable(),
+                           MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * scheduleAtFixedRate throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleAtFixedRate(new NoOpRunnable(),
+                                      MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
+     */
+    public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                p.scheduleWithFixedDelay(new NoOpRunnable(),
+                                         MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (RejectedExecutionException success) {
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * getActiveCount increases but doesn't overestimate, when a
+     * thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getActiveCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getActiveCount());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getActiveCount());
+        }
+    }
+
+    /**
+     * getCompletedTaskCount increases, but doesn't overestimate,
+     * when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(0, p.getCompletedTaskCount());
+                    threadProceed.await();
+                    threadDone.countDown();
+                }});
+            await(threadStarted);
+            assertEquals(0, p.getCompletedTaskCount());
+            threadProceed.countDown();
+            threadDone.await();
+            long startTime = System.nanoTime();
+            while (p.getCompletedTaskCount() != 1) {
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    fail("timed out");
+                Thread.yield();
+            }
+        }
+    }
+
+    /**
+     * getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() throws InterruptedException {
+        ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
+    }
+
+    /**
+     * getLargestPoolSize increases, but doesn't overestimate, when
+     * multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        final int THREADS = 3;
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(THREADS);
+        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+        final CountDownLatch done = new CountDownLatch(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getLargestPoolSize());
+            for (int i = 0; i < THREADS; i++)
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadsStarted.countDown();
+                        await(done);
+                        assertEquals(THREADS, p.getLargestPoolSize());
+                    }});
+            await(threadsStarted);
+            assertEquals(THREADS, p.getLargestPoolSize());
+        }
+        assertEquals(THREADS, p.getLargestPoolSize());
+    }
+
+    /**
+     * getPoolSize increases, but doesn't overestimate, when threads
+     * become active
+     */
+    public void testGetPoolSize() throws InterruptedException {
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getPoolSize());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getTaskCount increases, but doesn't overestimate, when tasks
+     * submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+        }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
+    }
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() throws InterruptedException {
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ScheduledThreadPoolExecutor p =
+            new ScheduledThreadPoolExecutor(1, threadFactory);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() throws InterruptedException {
+        ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * isShutdown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        assertFalse(p.isShutdown());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.shutdown();
+                assertTrue(p.isShutdown());
+            } catch (SecurityException ok) {}
+        }
+    }
+
+    /**
+     * isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminated());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminated());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
+    }
+
+    /**
+     * isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                tasks[i] = p.schedule(r, 1, MILLISECONDS);
+            }
+            await(threadStarted);
+            BlockingQueue<Runnable> q = p.getQueue();
+            assertTrue(q.contains(tasks[tasks.length - 1]));
+            assertFalse(q.contains(tasks[0]));
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            ScheduledFuture[] tasks = new ScheduledFuture[5];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            for (int i = 0; i < tasks.length; i++) {
+                Runnable r = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                tasks[i] = p.schedule(r, 1, MILLISECONDS);
+            }
+            await(threadStarted);
+            BlockingQueue<Runnable> q = p.getQueue();
+            assertFalse(p.remove((Runnable)tasks[0]));
+            assertTrue(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p.remove((Runnable)tasks[4]));
+            assertFalse(p.remove((Runnable)tasks[4]));
+            assertFalse(q.contains((Runnable)tasks[4]));
+            assertTrue(q.contains((Runnable)tasks[3]));
+            assertTrue(p.remove((Runnable)tasks[3]));
+            assertFalse(q.contains((Runnable)tasks[3]));
+        }
+    }
+
+    /**
+     * purge eventually removes cancelled tasks from the queue
+     */
+    public void testPurge() throws InterruptedException {
+        final ScheduledFuture[] tasks = new ScheduledFuture[5];
+        final Runnable releaser = new Runnable() { public void run() {
+            for (ScheduledFuture task : tasks)
+                if (task != null) task.cancel(true); }};
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p, releaser)) {
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                                      LONG_DELAY_MS, MILLISECONDS);
+            int max = tasks.length;
+            if (tasks[4].cancel(true)) --max;
+            if (tasks[3].cancel(true)) --max;
+            // There must eventually be an interference-free point at
+            // which purge will not fail. (At worst, when queue is empty.)
+            long startTime = System.nanoTime();
+            do {
+                p.purge();
+                long count = p.getTaskCount();
+                if (count == max)
+                    return;
+            } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
+            fail("Purge failed to remove cancelled tasks");
+        }
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final ScheduledThreadPoolExecutor p =
+            new ScheduledThreadPoolExecutor(poolSize);
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow_delayedTasks() throws InterruptedException {
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        List<ScheduledFuture> tasks = new ArrayList<>();
+        for (int i = 0; i < 3; i++) {
+            Runnable r = new NoOpRunnable();
+            tasks.add(p.schedule(r, 9, SECONDS));
+            tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
+            tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
+        }
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        if (testImplementationDetails)
+            assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
+        assertEquals(tasks.size(), queuedTasks.size());
+        for (ScheduledFuture task : tasks) {
+            assertFalse(task.isDone());
+            assertFalse(task.isCancelled());
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+    }
+
+    /**
+     * By default, periodic tasks are cancelled at shutdown.
+     * By default, delayed tasks keep running after shutdown.
+     * Check that changing the default values work:
+     * - setExecuteExistingDelayedTasksAfterShutdownPolicy
+     * - setContinueExistingPeriodicTasksAfterShutdownPolicy
+     */
+    public void testShutdown_cancellation() throws Exception {
+        Boolean[] allBooleans = { null, Boolean.FALSE, Boolean.TRUE };
+        for (Boolean policy : allBooleans)
+    {
+        final int poolSize = 2;
+        final ScheduledThreadPoolExecutor p
+            = new ScheduledThreadPoolExecutor(poolSize);
+        final boolean effectiveDelayedPolicy = (policy != Boolean.FALSE);
+        final boolean effectivePeriodicPolicy = (policy == Boolean.TRUE);
+        final boolean effectiveRemovePolicy = (policy == Boolean.TRUE);
+        if (policy != null) {
+            p.setExecuteExistingDelayedTasksAfterShutdownPolicy(policy);
+            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(policy);
+            p.setRemoveOnCancelPolicy(policy);
+        }
+        assertEquals(effectiveDelayedPolicy,
+                     p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
+        assertEquals(effectivePeriodicPolicy,
+                     p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
+        assertEquals(effectiveRemovePolicy,
+                     p.getRemoveOnCancelPolicy());
+        // Strategy: Wedge the pool with poolSize "blocker" threads
+        final AtomicInteger ran = new AtomicInteger(0);
+        final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
+        final CountDownLatch unblock = new CountDownLatch(1);
+        final CountDownLatch periodicLatch1 = new CountDownLatch(2);
+        final CountDownLatch periodicLatch2 = new CountDownLatch(2);
+        Runnable task = new CheckedRunnable() { public void realRun()
+                                                    throws InterruptedException {
+            poolBlocked.countDown();
+            assertTrue(unblock.await(LONG_DELAY_MS, MILLISECONDS));
+            ran.getAndIncrement();
+        }};
+        List<Future<?>> blockers = new ArrayList<>();
+        List<Future<?>> periodics = new ArrayList<>();
+        List<Future<?>> delayeds = new ArrayList<>();
+        for (int i = 0; i < poolSize; i++)
+            blockers.add(p.submit(task));
+        assertTrue(poolBlocked.await(LONG_DELAY_MS, MILLISECONDS));
+
+        periodics.add(p.scheduleAtFixedRate(countDowner(periodicLatch1),
+                                            1, 1, MILLISECONDS));
+        periodics.add(p.scheduleWithFixedDelay(countDowner(periodicLatch2),
+                                               1, 1, MILLISECONDS));
+        delayeds.add(p.schedule(task, 1, MILLISECONDS));
+
+        assertTrue(p.getQueue().containsAll(periodics));
+        assertTrue(p.getQueue().containsAll(delayeds));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        assertTrue(p.isShutdown());
+        assertFalse(p.isTerminated());
+        for (Future<?> periodic : periodics) {
+            assertTrue(effectivePeriodicPolicy ^ periodic.isCancelled());
+            assertTrue(effectivePeriodicPolicy ^ periodic.isDone());
+        }
+        for (Future<?> delayed : delayeds) {
+            assertTrue(effectiveDelayedPolicy ^ delayed.isCancelled());
+            assertTrue(effectiveDelayedPolicy ^ delayed.isDone());
+        }
+        if (testImplementationDetails) {
+            assertEquals(effectivePeriodicPolicy,
+                         p.getQueue().containsAll(periodics));
+            assertEquals(effectiveDelayedPolicy,
+                         p.getQueue().containsAll(delayeds));
+        }
+        // Release all pool threads
+        unblock.countDown();
+
+        for (Future<?> delayed : delayeds) {
+            if (effectiveDelayedPolicy) {
+                assertNull(delayed.get());
+            }
+        }
+        if (effectivePeriodicPolicy) {
+            assertTrue(periodicLatch1.await(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(periodicLatch2.await(LONG_DELAY_MS, MILLISECONDS));
+            for (Future<?> periodic : periodics) {
+                assertTrue(periodic.cancel(false));
+                assertTrue(periodic.isCancelled());
+                assertTrue(periodic.isDone());
+            }
+        }
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(2 + (effectiveDelayedPolicy ? 1 : 0), ran.get());
+    }}
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        final ExecutorService e = new ScheduledThreadPoolExecutor(2);
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p = new ScheduledThreadPoolExecutor(2);
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
+        }
+    }
+
+    /**
+     * A fixed delay task with overflowing period should not prevent a
+     * one-shot task from executing.
+     * https://bugs.openjdk.java.net/browse/JDK-8051859
+     */
+    public void testScheduleWithFixedDelay_overflow() throws Exception {
+        final CountDownLatch delayedDone = new CountDownLatch(1);
+        final CountDownLatch immediateDone = new CountDownLatch(1);
+        final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final Runnable immediate = new Runnable() { public void run() {
+                immediateDone.countDown();
+            }};
+            final Runnable delayed = new Runnable() { public void run() {
+                delayedDone.countDown();
+                p.submit(immediate);
+            }};
+            p.scheduleWithFixedDelay(delayed, 0L, Long.MAX_VALUE, SECONDS);
+            await(delayedDone);
+            await(immediateDone);
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/SemaphoreTest.java b/ojluni/src/test/java/util/concurrent/tck/SemaphoreTest.java
new file mode 100644
index 0000000..3c0321f
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/SemaphoreTest.java
@@ -0,0 +1,670 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class SemaphoreTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(SemaphoreTest.class);
+    }
+
+    /**
+     * Subclass to expose protected methods
+     */
+    static class PublicSemaphore extends Semaphore {
+        PublicSemaphore(int permits) { super(permits); }
+        PublicSemaphore(int permits, boolean fair) { super(permits, fair); }
+        public Collection<Thread> getQueuedThreads() {
+            return super.getQueuedThreads();
+        }
+        public boolean hasQueuedThread(Thread t) {
+            return super.getQueuedThreads().contains(t);
+        }
+        public void reducePermits(int reduction) {
+            super.reducePermits(reduction);
+        }
+    }
+
+    /**
+     * A runnable calling acquire
+     */
+    class InterruptibleLockRunnable extends CheckedRunnable {
+        final Semaphore lock;
+        InterruptibleLockRunnable(Semaphore s) { lock = s; }
+        public void realRun() {
+            try {
+                lock.acquire();
+            }
+            catch (InterruptedException ignored) {}
+        }
+    }
+
+    /**
+     * A runnable calling acquire that expects to be interrupted
+     */
+    class InterruptedLockRunnable extends CheckedInterruptedRunnable {
+        final Semaphore lock;
+        InterruptedLockRunnable(Semaphore s) { lock = s; }
+        public void realRun() throws InterruptedException {
+            lock.acquire();
+        }
+    }
+
+    /**
+     * Spin-waits until s.hasQueuedThread(t) becomes true.
+     */
+    void waitForQueuedThread(PublicSemaphore s, Thread t) {
+        long startTime = System.nanoTime();
+        while (!s.hasQueuedThread(t)) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+        assertTrue(s.hasQueuedThreads());
+        assertTrue(t.isAlive());
+    }
+
+    /**
+     * Spin-waits until s.hasQueuedThreads() becomes true.
+     */
+    void waitForQueuedThreads(Semaphore s) {
+        long startTime = System.nanoTime();
+        while (!s.hasQueuedThreads()) {
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                throw new AssertionFailedError("timed out");
+            Thread.yield();
+        }
+    }
+
+    enum AcquireMethod {
+        acquire() {
+            void acquire(Semaphore s) throws InterruptedException {
+                s.acquire();
+            }
+        },
+        acquireN() {
+            void acquire(Semaphore s, int permits) throws InterruptedException {
+                s.acquire(permits);
+            }
+        },
+        acquireUninterruptibly() {
+            void acquire(Semaphore s) {
+                s.acquireUninterruptibly();
+            }
+        },
+        acquireUninterruptiblyN() {
+            void acquire(Semaphore s, int permits) {
+                s.acquireUninterruptibly(permits);
+            }
+        },
+        tryAcquire() {
+            void acquire(Semaphore s) {
+                assertTrue(s.tryAcquire());
+            }
+        },
+        tryAcquireN() {
+            void acquire(Semaphore s, int permits) {
+                assertTrue(s.tryAcquire(permits));
+            }
+        },
+        tryAcquireTimed() {
+            void acquire(Semaphore s) throws InterruptedException {
+                assertTrue(s.tryAcquire(2 * LONG_DELAY_MS, MILLISECONDS));
+            }
+        },
+        tryAcquireTimedN {
+            void acquire(Semaphore s, int permits) throws InterruptedException {
+                assertTrue(s.tryAcquire(permits, 2 * LONG_DELAY_MS, MILLISECONDS));
+            }
+        };
+
+        // Intentionally meta-circular
+
+        /** Acquires 1 permit. */
+        void acquire(Semaphore s) throws InterruptedException {
+            acquire(s, 1);
+        }
+        /** Acquires the given number of permits. */
+        void acquire(Semaphore s, int permits) throws InterruptedException {
+            for (int i = 0; i < permits; i++)
+                acquire(s);
+        }
+    }
+
+    /**
+     * Zero, negative, and positive initial values are allowed in constructor
+     */
+    public void testConstructor()      { testConstructor(false); }
+    public void testConstructor_fair() { testConstructor(true); }
+    public void testConstructor(boolean fair) {
+        for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
+            Semaphore s = new Semaphore(permits, fair);
+            assertEquals(permits, s.availablePermits());
+            assertEquals(fair, s.isFair());
+        }
+    }
+
+    /**
+     * Constructor without fairness argument behaves as nonfair
+     */
+    public void testConstructorDefaultsToNonFair() {
+        for (int permits : new int[] { -42, -1, 0, 1, 42 }) {
+            Semaphore s = new Semaphore(permits);
+            assertEquals(permits, s.availablePermits());
+            assertFalse(s.isFair());
+        }
+    }
+
+    /**
+     * tryAcquire succeeds when sufficient permits, else fails
+     */
+    public void testTryAcquireInSameThread()      { testTryAcquireInSameThread(false); }
+    public void testTryAcquireInSameThread_fair() { testTryAcquireInSameThread(true); }
+    public void testTryAcquireInSameThread(boolean fair) {
+        Semaphore s = new Semaphore(2, fair);
+        assertEquals(2, s.availablePermits());
+        assertTrue(s.tryAcquire());
+        assertTrue(s.tryAcquire());
+        assertEquals(0, s.availablePermits());
+        assertFalse(s.tryAcquire());
+        assertFalse(s.tryAcquire());
+        assertEquals(0, s.availablePermits());
+    }
+
+    /**
+     * timed tryAcquire times out
+     */
+    public void testTryAcquire_timeout()      { testTryAcquire_timeout(false); }
+    public void testTryAcquire_timeout_fair() { testTryAcquire_timeout(true); }
+    public void testTryAcquire_timeout(boolean fair) {
+        Semaphore s = new Semaphore(0, fair);
+        long startTime = System.nanoTime();
+        try { assertFalse(s.tryAcquire(timeoutMillis(), MILLISECONDS)); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+    }
+
+    /**
+     * timed tryAcquire(N) times out
+     */
+    public void testTryAcquireN_timeout()      { testTryAcquireN_timeout(false); }
+    public void testTryAcquireN_timeout_fair() { testTryAcquireN_timeout(true); }
+    public void testTryAcquireN_timeout(boolean fair) {
+        Semaphore s = new Semaphore(2, fair);
+        long startTime = System.nanoTime();
+        try { assertFalse(s.tryAcquire(3, timeoutMillis(), MILLISECONDS)); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+    }
+
+    /**
+     * acquire(), acquire(N), timed tryAcquired, timed tryAcquire(N)
+     * are interruptible
+     */
+    public void testInterruptible_acquire()               { testInterruptible(false, AcquireMethod.acquire); }
+    public void testInterruptible_acquire_fair()          { testInterruptible(true,  AcquireMethod.acquire); }
+    public void testInterruptible_acquireN()              { testInterruptible(false, AcquireMethod.acquireN); }
+    public void testInterruptible_acquireN_fair()         { testInterruptible(true,  AcquireMethod.acquireN); }
+    public void testInterruptible_tryAcquireTimed()       { testInterruptible(false, AcquireMethod.tryAcquireTimed); }
+    public void testInterruptible_tryAcquireTimed_fair()  { testInterruptible(true,  AcquireMethod.tryAcquireTimed); }
+    public void testInterruptible_tryAcquireTimedN()      { testInterruptible(false, AcquireMethod.tryAcquireTimedN); }
+    public void testInterruptible_tryAcquireTimedN_fair() { testInterruptible(true,  AcquireMethod.tryAcquireTimedN); }
+    public void testInterruptible(boolean fair, final AcquireMethod acquirer) {
+        final PublicSemaphore s = new PublicSemaphore(0, fair);
+        final Semaphore pleaseInterrupt = new Semaphore(0, fair);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                // Interrupt before acquire
+                Thread.currentThread().interrupt();
+                try {
+                    acquirer.acquire(s);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+
+                // Interrupt during acquire
+                try {
+                    acquirer.acquire(s);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+
+                // Interrupt before acquire(N)
+                Thread.currentThread().interrupt();
+                try {
+                    acquirer.acquire(s, 3);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+
+                pleaseInterrupt.release();
+
+                // Interrupt during acquire(N)
+                try {
+                    acquirer.acquire(s, 3);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        waitForQueuedThread(s, t);
+        t.interrupt();
+        await(pleaseInterrupt);
+        waitForQueuedThread(s, t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * acquireUninterruptibly(), acquireUninterruptibly(N) are
+     * uninterruptible
+     */
+    public void testUninterruptible_acquireUninterruptibly()       { testUninterruptible(false, AcquireMethod.acquireUninterruptibly); }
+    public void testUninterruptible_acquireUninterruptibly_fair()  { testUninterruptible(true,  AcquireMethod.acquireUninterruptibly); }
+    public void testUninterruptible_acquireUninterruptiblyN()      { testUninterruptible(false, AcquireMethod.acquireUninterruptiblyN); }
+    public void testUninterruptible_acquireUninterruptiblyN_fair() { testUninterruptible(true,  AcquireMethod.acquireUninterruptiblyN); }
+    public void testUninterruptible(boolean fair, final AcquireMethod acquirer) {
+        final PublicSemaphore s = new PublicSemaphore(0, fair);
+        final Semaphore pleaseInterrupt = new Semaphore(-1, fair);
+
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                // Interrupt before acquire
+                pleaseInterrupt.release();
+                Thread.currentThread().interrupt();
+                acquirer.acquire(s);
+                assertTrue(Thread.interrupted());
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                // Interrupt during acquire
+                pleaseInterrupt.release();
+                acquirer.acquire(s);
+                assertTrue(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        waitForQueuedThread(s, t1);
+        waitForQueuedThread(s, t2);
+        t2.interrupt();
+
+        assertThreadStaysAlive(t1);
+        assertTrue(t2.isAlive());
+
+        s.release(2);
+
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * hasQueuedThreads reports whether there are waiting threads
+     */
+    public void testHasQueuedThreads()      { testHasQueuedThreads(false); }
+    public void testHasQueuedThreads_fair() { testHasQueuedThreads(true); }
+    public void testHasQueuedThreads(boolean fair) {
+        final PublicSemaphore lock = new PublicSemaphore(1, fair);
+        assertFalse(lock.hasQueuedThreads());
+        lock.acquireUninterruptibly();
+        Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.hasQueuedThreads());
+        Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.hasQueuedThreads());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertTrue(lock.hasQueuedThreads());
+        lock.release();
+        awaitTermination(t2);
+        assertFalse(lock.hasQueuedThreads());
+    }
+
+    /**
+     * getQueueLength reports number of waiting threads
+     */
+    public void testGetQueueLength()      { testGetQueueLength(false); }
+    public void testGetQueueLength_fair() { testGetQueueLength(true); }
+    public void testGetQueueLength(boolean fair) {
+        final PublicSemaphore lock = new PublicSemaphore(1, fair);
+        assertEquals(0, lock.getQueueLength());
+        lock.acquireUninterruptibly();
+        Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+        waitForQueuedThread(lock, t1);
+        assertEquals(1, lock.getQueueLength());
+        Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+        waitForQueuedThread(lock, t2);
+        assertEquals(2, lock.getQueueLength());
+        t1.interrupt();
+        awaitTermination(t1);
+        assertEquals(1, lock.getQueueLength());
+        lock.release();
+        awaitTermination(t2);
+        assertEquals(0, lock.getQueueLength());
+    }
+
+    /**
+     * getQueuedThreads includes waiting threads
+     */
+    public void testGetQueuedThreads()      { testGetQueuedThreads(false); }
+    public void testGetQueuedThreads_fair() { testGetQueuedThreads(true); }
+    public void testGetQueuedThreads(boolean fair) {
+        final PublicSemaphore lock = new PublicSemaphore(1, fair);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        lock.acquireUninterruptibly();
+        assertTrue(lock.getQueuedThreads().isEmpty());
+        Thread t1 = newStartedThread(new InterruptedLockRunnable(lock));
+        waitForQueuedThread(lock, t1);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        Thread t2 = newStartedThread(new InterruptibleLockRunnable(lock));
+        waitForQueuedThread(lock, t2);
+        assertTrue(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        t1.interrupt();
+        awaitTermination(t1);
+        assertFalse(lock.getQueuedThreads().contains(t1));
+        assertTrue(lock.getQueuedThreads().contains(t2));
+        lock.release();
+        awaitTermination(t2);
+        assertTrue(lock.getQueuedThreads().isEmpty());
+    }
+
+    /**
+     * drainPermits reports and removes given number of permits
+     */
+    public void testDrainPermits()      { testDrainPermits(false); }
+    public void testDrainPermits_fair() { testDrainPermits(true); }
+    public void testDrainPermits(boolean fair) {
+        Semaphore s = new Semaphore(0, fair);
+        assertEquals(0, s.availablePermits());
+        assertEquals(0, s.drainPermits());
+        s.release(10);
+        assertEquals(10, s.availablePermits());
+        assertEquals(10, s.drainPermits());
+        assertEquals(0, s.availablePermits());
+        assertEquals(0, s.drainPermits());
+    }
+
+    /**
+     * release(-N) throws IllegalArgumentException
+     */
+    public void testReleaseIAE()      { testReleaseIAE(false); }
+    public void testReleaseIAE_fair() { testReleaseIAE(true); }
+    public void testReleaseIAE(boolean fair) {
+        Semaphore s = new Semaphore(10, fair);
+        try {
+            s.release(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * reducePermits(-N) throws IllegalArgumentException
+     */
+    public void testReducePermitsIAE()      { testReducePermitsIAE(false); }
+    public void testReducePermitsIAE_fair() { testReducePermitsIAE(true); }
+    public void testReducePermitsIAE(boolean fair) {
+        PublicSemaphore s = new PublicSemaphore(10, fair);
+        try {
+            s.reducePermits(-1);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * reducePermits reduces number of permits
+     */
+    public void testReducePermits()      { testReducePermits(false); }
+    public void testReducePermits_fair() { testReducePermits(true); }
+    public void testReducePermits(boolean fair) {
+        PublicSemaphore s = new PublicSemaphore(10, fair);
+        assertEquals(10, s.availablePermits());
+        s.reducePermits(0);
+        assertEquals(10, s.availablePermits());
+        s.reducePermits(1);
+        assertEquals(9, s.availablePermits());
+        s.reducePermits(10);
+        assertEquals(-1, s.availablePermits());
+        s.reducePermits(10);
+        assertEquals(-11, s.availablePermits());
+        s.reducePermits(0);
+        assertEquals(-11, s.availablePermits());
+    }
+
+    /**
+     * a reserialized semaphore has same number of permits and
+     * fairness, but no queued threads
+     */
+    public void testSerialization()      { testSerialization(false); }
+    public void testSerialization_fair() { testSerialization(true); }
+    public void testSerialization(boolean fair) {
+        try {
+            Semaphore s = new Semaphore(3, fair);
+            s.acquire();
+            s.acquire();
+            s.release();
+
+            Semaphore clone = serialClone(s);
+            assertEquals(fair, s.isFair());
+            assertEquals(fair, clone.isFair());
+            assertEquals(2, s.availablePermits());
+            assertEquals(2, clone.availablePermits());
+            clone.acquire();
+            clone.acquire();
+            clone.release();
+            assertEquals(2, s.availablePermits());
+            assertEquals(1, clone.availablePermits());
+            assertFalse(s.hasQueuedThreads());
+            assertFalse(clone.hasQueuedThreads());
+        } catch (InterruptedException e) { threadUnexpectedException(e); }
+
+        {
+            PublicSemaphore s = new PublicSemaphore(0, fair);
+            Thread t = newStartedThread(new InterruptibleLockRunnable(s));
+            // waitForQueuedThreads(s); // suffers from "flicker", so ...
+            waitForQueuedThread(s, t);  // ... we use this instead
+            PublicSemaphore clone = serialClone(s);
+            assertEquals(fair, s.isFair());
+            assertEquals(fair, clone.isFair());
+            assertEquals(0, s.availablePermits());
+            assertEquals(0, clone.availablePermits());
+            assertTrue(s.hasQueuedThreads());
+            assertFalse(clone.hasQueuedThreads());
+            s.release();
+            awaitTermination(t);
+            assertFalse(s.hasQueuedThreads());
+            assertFalse(clone.hasQueuedThreads());
+        }
+    }
+
+    /**
+     * tryAcquire(n) succeeds when sufficient permits, else fails
+     */
+    public void testTryAcquireNInSameThread()      { testTryAcquireNInSameThread(false); }
+    public void testTryAcquireNInSameThread_fair() { testTryAcquireNInSameThread(true); }
+    public void testTryAcquireNInSameThread(boolean fair) {
+        Semaphore s = new Semaphore(2, fair);
+        assertEquals(2, s.availablePermits());
+        assertFalse(s.tryAcquire(3));
+        assertEquals(2, s.availablePermits());
+        assertTrue(s.tryAcquire(2));
+        assertEquals(0, s.availablePermits());
+        assertFalse(s.tryAcquire(1));
+        assertFalse(s.tryAcquire(2));
+        assertEquals(0, s.availablePermits());
+    }
+
+    /**
+     * acquire succeeds if permits available
+     */
+    public void testReleaseAcquireSameThread_acquire()       { testReleaseAcquireSameThread(false, AcquireMethod.acquire); }
+    public void testReleaseAcquireSameThread_acquire_fair()  { testReleaseAcquireSameThread(true, AcquireMethod.acquire); }
+    public void testReleaseAcquireSameThread_acquireN()      { testReleaseAcquireSameThread(false, AcquireMethod.acquireN); }
+    public void testReleaseAcquireSameThread_acquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireN); }
+    public void testReleaseAcquireSameThread_acquireUninterruptibly()       { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireSameThread_acquireUninterruptibly_fair()  { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireSameThread_acquireUninterruptiblyN()      { testReleaseAcquireSameThread(false, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireSameThread_acquireUninterruptiblyN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireSameThread_tryAcquire()       { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquire); }
+    public void testReleaseAcquireSameThread_tryAcquire_fair()  { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquire); }
+    public void testReleaseAcquireSameThread_tryAcquireN()      { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireN); }
+    public void testReleaseAcquireSameThread_tryAcquireN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireN); }
+    public void testReleaseAcquireSameThread_tryAcquireTimed()       { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimed); }
+    public void testReleaseAcquireSameThread_tryAcquireTimed_fair()  { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimed); }
+    public void testReleaseAcquireSameThread_tryAcquireTimedN()      { testReleaseAcquireSameThread(false, AcquireMethod.tryAcquireTimedN); }
+    public void testReleaseAcquireSameThread_tryAcquireTimedN_fair() { testReleaseAcquireSameThread(true, AcquireMethod.tryAcquireTimedN); }
+    public void testReleaseAcquireSameThread(boolean fair,
+                                             final AcquireMethod acquirer) {
+        Semaphore s = new Semaphore(1, fair);
+        for (int i = 1; i < 6; i++) {
+            s.release(i);
+            assertEquals(1 + i, s.availablePermits());
+            try {
+                acquirer.acquire(s, i);
+            } catch (InterruptedException e) { threadUnexpectedException(e); }
+            assertEquals(1, s.availablePermits());
+        }
+    }
+
+    /**
+     * release in one thread enables acquire in another thread
+     */
+    public void testReleaseAcquireDifferentThreads_acquire()       { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquire); }
+    public void testReleaseAcquireDifferentThreads_acquire_fair()  { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquire); }
+    public void testReleaseAcquireDifferentThreads_acquireN()      { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireN); }
+    public void testReleaseAcquireDifferentThreads_acquireN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireN); }
+    public void testReleaseAcquireDifferentThreads_acquireUninterruptibly()       { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireDifferentThreads_acquireUninterruptibly_fair()  { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN()      { testReleaseAcquireDifferentThreads(false, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireDifferentThreads_acquireUninterruptiblyN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.acquireUninterruptibly); }
+    public void testReleaseAcquireDifferentThreads_tryAcquireTimed()       { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimed); }
+    public void testReleaseAcquireDifferentThreads_tryAcquireTimed_fair()  { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimed); }
+    public void testReleaseAcquireDifferentThreads_tryAcquireTimedN()      { testReleaseAcquireDifferentThreads(false, AcquireMethod.tryAcquireTimedN); }
+    public void testReleaseAcquireDifferentThreads_tryAcquireTimedN_fair() { testReleaseAcquireDifferentThreads(true, AcquireMethod.tryAcquireTimedN); }
+    public void testReleaseAcquireDifferentThreads(boolean fair,
+                                                   final AcquireMethod acquirer) {
+        final Semaphore s = new Semaphore(0, fair);
+        final int rounds = 4;
+        long startTime = System.nanoTime();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                for (int i = 0; i < rounds; i++) {
+                    assertFalse(s.hasQueuedThreads());
+                    if (i % 2 == 0)
+                        acquirer.acquire(s);
+                    else
+                        acquirer.acquire(s, 3);
+                }}});
+
+        for (int i = 0; i < rounds; i++) {
+            while (! (s.availablePermits() == 0 && s.hasQueuedThreads()))
+                Thread.yield();
+            assertTrue(t.isAlive());
+            if (i % 2 == 0)
+                s.release();
+            else
+                s.release(3);
+        }
+        awaitTermination(t);
+        assertEquals(0, s.availablePermits());
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+    }
+
+    /**
+     * fair locks are strictly FIFO
+     */
+    public void testFairLocksFifo() {
+        final PublicSemaphore s = new PublicSemaphore(1, true);
+        final CountDownLatch pleaseRelease = new CountDownLatch(1);
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                // Will block; permits are available, but not three
+                s.acquire(3);
+            }});
+
+        waitForQueuedThread(s, t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                // Will fail, even though 1 permit is available
+                assertFalse(s.tryAcquire(0L, MILLISECONDS));
+                assertFalse(s.tryAcquire(1, 0L, MILLISECONDS));
+
+                // untimed tryAcquire will barge and succeed
+                assertTrue(s.tryAcquire());
+                s.release(2);
+                assertTrue(s.tryAcquire(2));
+                s.release();
+
+                pleaseRelease.countDown();
+                // Will queue up behind t1, even though 1 permit is available
+                s.acquire();
+            }});
+
+        await(pleaseRelease);
+        waitForQueuedThread(s, t2);
+        s.release(2);
+        awaitTermination(t1);
+        assertTrue(t2.isAlive());
+        s.release();
+        awaitTermination(t2);
+    }
+
+    /**
+     * toString indicates current number of permits
+     */
+    public void testToString()      { testToString(false); }
+    public void testToString_fair() { testToString(true); }
+    public void testToString(boolean fair) {
+        PublicSemaphore s = new PublicSemaphore(0, fair);
+        assertTrue(s.toString().contains("Permits = 0"));
+        s.release();
+        assertTrue(s.toString().contains("Permits = 1"));
+        s.release(2);
+        assertTrue(s.toString().contains("Permits = 3"));
+        s.reducePermits(5);
+        assertTrue(s.toString().contains("Permits = -2"));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/SplittableRandomTest.java b/ojluni/src/test/java/util/concurrent/tck/SplittableRandomTest.java
new file mode 100644
index 0000000..99c4bde
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/SplittableRandomTest.java
@@ -0,0 +1,556 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.SplittableRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class SplittableRandomTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(SplittableRandomTest.class);
+    }
+
+    /*
+     * Testing coverage notes:
+     *
+     * 1. Many of the test methods are adapted from ThreadLocalRandomTest.
+     *
+     * 2. These tests do not check for random number generator quality.
+     * But we check for minimal API compliance by requiring that
+     * repeated calls to nextX methods, up to NCALLS tries, produce at
+     * least two distinct results. (In some possible universe, a
+     * "correct" implementation might fail, but the odds are vastly
+     * less than that of encountering a hardware failure while running
+     * the test.) For bounded nextX methods, we sample various
+     * intervals across multiples of primes. In other tests, we repeat
+     * under REPS different values.
+     */
+
+    // max numbers of calls to detect getting stuck on one value
+    static final int NCALLS = 10000;
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 26);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 40);
+
+    // Number of replications for other checks
+    static final int REPS =
+        Integer.getInteger("SplittableRandomTest.reps", 4);
+
+    /**
+     * Repeated calls to nextInt produce at least two distinct results
+     */
+    public void testNextInt() {
+        SplittableRandom sr = new SplittableRandom();
+        int f = sr.nextInt();
+        int i = 0;
+        while (i < NCALLS && sr.nextInt() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextLong produce at least two distinct results
+     */
+    public void testNextLong() {
+        SplittableRandom sr = new SplittableRandom();
+        long f = sr.nextLong();
+        int i = 0;
+        while (i < NCALLS && sr.nextLong() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextDouble produce at least two distinct results
+     */
+    public void testNextDouble() {
+        SplittableRandom sr = new SplittableRandom();
+        double f = sr.nextDouble();
+        int i = 0;
+        while (i < NCALLS && sr.nextDouble() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Two SplittableRandoms created with the same seed produce the
+     * same values for nextLong.
+     */
+    public void testSeedConstructor() {
+        for (long seed = 2; seed < MAX_LONG_BOUND; seed += 15485863) {
+            SplittableRandom sr1 = new SplittableRandom(seed);
+            SplittableRandom sr2 = new SplittableRandom(seed);
+            for (int i = 0; i < REPS; ++i)
+                assertEquals(sr1.nextLong(), sr2.nextLong());
+        }
+    }
+
+    /**
+     * A SplittableRandom produced by split() of a default-constructed
+     * SplittableRandom generates a different sequence
+     */
+    public void testSplit1() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int reps = 0; reps < REPS; ++reps) {
+            SplittableRandom sc = sr.split();
+            int i = 0;
+            while (i < NCALLS && sr.nextLong() == sc.nextLong())
+                ++i;
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * A SplittableRandom produced by split() of a seeded-constructed
+     * SplittableRandom generates a different sequence
+     */
+    public void testSplit2() {
+        SplittableRandom sr = new SplittableRandom(12345);
+        for (int reps = 0; reps < REPS; ++reps) {
+            SplittableRandom sc = sr.split();
+            int i = 0;
+            while (i < NCALLS && sr.nextLong() == sc.nextLong())
+                ++i;
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(non-positive) throws IllegalArgumentException
+     */
+    public void testNextIntBoundNonPositive() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextInt(-17),
+            () -> sr.nextInt(0),
+            () -> sr.nextInt(Integer.MIN_VALUE),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * nextInt(least >= bound) throws IllegalArgumentException
+     */
+    public void testNextIntBadBounds() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextInt(17, 2),
+            () -> sr.nextInt(-42, -42),
+            () -> sr.nextInt(Integer.MAX_VALUE, Integer.MIN_VALUE),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * nextInt(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int i = 0; i < 2; i++) assertEquals(0, sr.nextInt(1));
+        // sample bound space across prime number increments
+        for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+            int f = sr.nextInt(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            int j;
+            while (i < NCALLS &&
+                   (j = sr.nextInt(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+                int f = sr.nextInt(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                int j;
+                while (i < NCALLS &&
+                       (j = sr.nextInt(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextLong(non-positive) throws IllegalArgumentException
+     */
+    public void testNextLongBoundNonPositive() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextLong(-17L),
+            () -> sr.nextLong(0L),
+            () -> sr.nextLong(Long.MIN_VALUE),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * nextLong(least >= bound) throws IllegalArgumentException
+     */
+    public void testNextLongBadBounds() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextLong(17L, 2L),
+            () -> sr.nextLong(-42L, -42L),
+            () -> sr.nextLong(Long.MAX_VALUE, Long.MIN_VALUE),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * nextLong(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded() {
+        SplittableRandom sr = new SplittableRandom();
+        for (int i = 0; i < 2; i++) assertEquals(0L, sr.nextLong(1L));
+        for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+            long f = sr.nextLong(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            long j;
+            while (i < NCALLS &&
+                   (j = sr.nextLong(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextLong(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                long f = sr.nextLong(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                long j;
+                while (i < NCALLS &&
+                       (j = sr.nextLong(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextDouble(non-positive) throws IllegalArgumentException
+     */
+    public void testNextDoubleBoundNonPositive() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextDouble(-17.0d),
+            () -> sr.nextDouble(0.0d),
+            () -> sr.nextDouble(-Double.MIN_VALUE),
+            () -> sr.nextDouble(Double.NEGATIVE_INFINITY),
+            () -> sr.nextDouble(Double.NaN),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * nextDouble(! (least < bound)) throws IllegalArgumentException
+     */
+    public void testNextDoubleBadBounds() {
+        SplittableRandom sr = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> sr.nextDouble(17.0d, 2.0d),
+            () -> sr.nextDouble(-42.0d, -42.0d),
+            () -> sr.nextDouble(Double.MAX_VALUE, Double.MIN_VALUE),
+            () -> sr.nextDouble(Double.NaN, 0.0d),
+            () -> sr.nextDouble(0.0d, Double.NaN),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    // TODO: Test infinite bounds!
+    //() -> sr.nextDouble(Double.NEGATIVE_INFINITY, 0.0d),
+    //() -> sr.nextDouble(0.0d, Double.POSITIVE_INFINITY),
+
+    /**
+     * nextDouble(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextDoubleBounded2() {
+        SplittableRandom sr = new SplittableRandom();
+        for (double least = 0.0001; least < 1.0e20; least *= 8) {
+            for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+                double f = sr.nextDouble(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                double j;
+                while (i < NCALLS &&
+                       (j = sr.nextDouble(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamSize() {
+        SplittableRandom r = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> { java.util.stream.IntStream x = r.ints(-1L); },
+            () -> { java.util.stream.IntStream x = r.ints(-1L, 2, 3); },
+            () -> { java.util.stream.LongStream x = r.longs(-1L); },
+            () -> { java.util.stream.LongStream x = r.longs(-1L, -1L, 1L); },
+            () -> { java.util.stream.DoubleStream x = r.doubles(-1L); },
+            () -> { java.util.stream.DoubleStream x = r.doubles(-1L, .5, .6); },
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * Invoking bounded ints, long, doubles, with illegal bounds throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamBounds() {
+        SplittableRandom r = new SplittableRandom();
+        Runnable[] throwingActions = {
+            () -> { java.util.stream.IntStream x = r.ints(2, 1); },
+            () -> { java.util.stream.IntStream x = r.ints(10, 42, 42); },
+            () -> { java.util.stream.LongStream x = r.longs(-1L, -1L); },
+            () -> { java.util.stream.LongStream x = r.longs(10, 1L, -2L); },
+            () -> { java.util.stream.DoubleStream x = r.doubles(0.0, 0.0); },
+            () -> { java.util.stream.DoubleStream x = r.doubles(10, .5, .4); },
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * A parallel sized stream of ints generates the given number of values
+     */
+    public void testIntsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.ints(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of longs generates the given number of values
+     */
+    public void testLongsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.longs(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of doubles generates the given number of values
+     */
+    public void testDoublesCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.doubles(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded ints is within bounds
+     */
+    public void testBoundedInts() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 12345L;
+        for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+                final int lo = least, hi = bound;
+                r.ints(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded longs is within bounds
+     */
+    public void testBoundedLongs() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 123L;
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                final long lo = least, hi = bound;
+                r.longs(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded doubles is within bounds
+     */
+    public void testBoundedDoubles() {
+        AtomicInteger fails = new AtomicInteger(0);
+        SplittableRandom r = new SplittableRandom();
+        long size = 456;
+        for (double least = 0.00011; least < 1.0e20; least *= 9) {
+            for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+                final double lo = least, hi = bound;
+                r.doubles(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * A parallel unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.ints().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A parallel unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.longs().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A parallel unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCount() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.doubles().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.ints().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.longs().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCountSeq() {
+        LongAdder counter = new LongAdder();
+        SplittableRandom r = new SplittableRandom();
+        long size = 100;
+        r.doubles().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/StampedLockTest.java b/ojluni/src/test/java/util/concurrent/tck/StampedLockTest.java
new file mode 100644
index 0000000..5ca2410
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/StampedLockTest.java
@@ -0,0 +1,1210 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz
+ * 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 test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.StampedLock;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class StampedLockTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(StampedLockTest.class);
+    }
+
+    /**
+     * Releases write lock, checking isWriteLocked before and after
+     */
+    void releaseWriteLock(StampedLock lock, long stamp) {
+        assertTrue(lock.isWriteLocked());
+        assertValid(lock, stamp);
+        lock.unlockWrite(stamp);
+        assertFalse(lock.isWriteLocked());
+        assertFalse(lock.validate(stamp));
+    }
+
+    /**
+     * Releases read lock, checking isReadLocked before and after
+     */
+    void releaseReadLock(StampedLock lock, long stamp) {
+        assertTrue(lock.isReadLocked());
+        assertValid(lock, stamp);
+        lock.unlockRead(stamp);
+        assertFalse(lock.isReadLocked());
+        assertTrue(lock.validate(stamp));
+    }
+
+    long assertNonZero(long v) {
+        assertTrue(v != 0L);
+        return v;
+    }
+
+    long assertValid(StampedLock lock, long stamp) {
+        assertTrue(stamp != 0L);
+        assertTrue(lock.validate(stamp));
+        return stamp;
+    }
+
+    void assertUnlocked(StampedLock lock) {
+        assertFalse(lock.isReadLocked());
+        assertFalse(lock.isWriteLocked());
+        assertEquals(0, lock.getReadLockCount());
+        assertValid(lock, lock.tryOptimisticRead());
+    }
+
+    List<Action> lockLockers(Lock lock) {
+        List<Action> lockers = new ArrayList<>();
+        lockers.add(() -> lock.lock());
+        lockers.add(() -> lock.lockInterruptibly());
+        lockers.add(() -> lock.tryLock());
+        lockers.add(() -> lock.tryLock(Long.MIN_VALUE, DAYS));
+        lockers.add(() -> lock.tryLock(0L, DAYS));
+        lockers.add(() -> lock.tryLock(Long.MAX_VALUE, DAYS));
+        return lockers;
+    }
+
+    List<Function<StampedLock, Long>> readLockers() {
+        List<Function<StampedLock, Long>> readLockers = new ArrayList<>();
+        readLockers.add(sl -> sl.readLock());
+        readLockers.add(sl -> sl.tryReadLock());
+        readLockers.add(sl -> readLockInterruptiblyUninterrupted(sl));
+        readLockers.add(sl -> tryReadLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
+        readLockers.add(sl -> tryReadLockUninterrupted(sl, 0L, DAYS));
+        readLockers.add(sl -> sl.tryConvertToReadLock(sl.tryOptimisticRead()));
+        return readLockers;
+    }
+
+    List<BiConsumer<StampedLock, Long>> readUnlockers() {
+        List<BiConsumer<StampedLock, Long>> readUnlockers = new ArrayList<>();
+        readUnlockers.add((sl, stamp) -> sl.unlockRead(stamp));
+        readUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockRead()));
+        readUnlockers.add((sl, stamp) -> sl.asReadLock().unlock());
+        readUnlockers.add((sl, stamp) -> sl.unlock(stamp));
+        readUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
+        return readUnlockers;
+    }
+
+    List<Function<StampedLock, Long>> writeLockers() {
+        List<Function<StampedLock, Long>> writeLockers = new ArrayList<>();
+        writeLockers.add(sl -> sl.writeLock());
+        writeLockers.add(sl -> sl.tryWriteLock());
+        writeLockers.add(sl -> writeLockInterruptiblyUninterrupted(sl));
+        writeLockers.add(sl -> tryWriteLockUninterrupted(sl, Long.MIN_VALUE, DAYS));
+        writeLockers.add(sl -> tryWriteLockUninterrupted(sl, 0L, DAYS));
+        writeLockers.add(sl -> sl.tryConvertToWriteLock(sl.tryOptimisticRead()));
+        return writeLockers;
+    }
+
+    List<BiConsumer<StampedLock, Long>> writeUnlockers() {
+        List<BiConsumer<StampedLock, Long>> writeUnlockers = new ArrayList<>();
+        writeUnlockers.add((sl, stamp) -> sl.unlockWrite(stamp));
+        writeUnlockers.add((sl, stamp) -> assertTrue(sl.tryUnlockWrite()));
+        writeUnlockers.add((sl, stamp) -> sl.asWriteLock().unlock());
+        writeUnlockers.add((sl, stamp) -> sl.unlock(stamp));
+        writeUnlockers.add((sl, stamp) -> assertValid(sl, sl.tryConvertToOptimisticRead(stamp)));
+        return writeUnlockers;
+    }
+
+    /**
+     * Constructed StampedLock is in unlocked state
+     */
+    public void testConstructor() {
+        assertUnlocked(new StampedLock());
+    }
+
+    /**
+     * write-locking, then unlocking, an unlocked lock succeed
+     */
+    public void testWriteLock_lockUnlock() {
+        StampedLock lock = new StampedLock();
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers())
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            assertFalse(lock.isWriteLocked());
+            assertFalse(lock.isReadLocked());
+            assertEquals(0, lock.getReadLockCount());
+
+            long s = writeLocker.apply(lock);
+            assertValid(lock, s);
+            assertTrue(lock.isWriteLocked());
+            assertFalse(lock.isReadLocked());
+            assertEquals(0, lock.getReadLockCount());
+            writeUnlocker.accept(lock, s);
+            assertUnlocked(lock);
+        }
+    }
+
+    /**
+     * read-locking, then unlocking, an unlocked lock succeed
+     */
+    public void testReadLock_lockUnlock() {
+        StampedLock lock = new StampedLock();
+
+        for (Function<StampedLock, Long> readLocker : readLockers())
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            long s = 42;
+            for (int i = 0; i < 2; i++) {
+                s = assertValid(lock, readLocker.apply(lock));
+                assertFalse(lock.isWriteLocked());
+                assertTrue(lock.isReadLocked());
+                assertEquals(i + 1, lock.getReadLockCount());
+            }
+            for (int i = 0; i < 2; i++) {
+                assertFalse(lock.isWriteLocked());
+                assertTrue(lock.isReadLocked());
+                assertEquals(2 - i, lock.getReadLockCount());
+                readUnlocker.accept(lock, s);
+            }
+            assertUnlocked(lock);
+        }
+    }
+
+    /**
+     * tryUnlockWrite fails if not write locked
+     */
+    public void testTryUnlockWrite_failure() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.tryUnlockWrite());
+
+        for (Function<StampedLock, Long> readLocker : readLockers())
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            long s = assertValid(lock, readLocker.apply(lock));
+            assertFalse(lock.tryUnlockWrite());
+            assertTrue(lock.isReadLocked());
+            readUnlocker.accept(lock, s);
+            assertUnlocked(lock);
+        }
+    }
+
+    /**
+     * tryUnlockRead fails if not read locked
+     */
+    public void testTryUnlockRead_failure() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.tryUnlockRead());
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers())
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            long s = writeLocker.apply(lock);
+            assertFalse(lock.tryUnlockRead());
+            assertTrue(lock.isWriteLocked());
+            writeUnlocker.accept(lock, s);
+            assertUnlocked(lock);
+        }
+    }
+
+    /**
+     * validate(0L) fails
+     */
+    public void testValidate0() {
+        StampedLock lock = new StampedLock();
+        assertFalse(lock.validate(0L));
+    }
+
+    /**
+     * A stamp obtained from a successful lock operation validates while the lock is held
+     */
+    public void testValidate() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+
+        for (Function<StampedLock, Long> readLocker : readLockers())
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            long s = assertNonZero(readLocker.apply(lock));
+            assertTrue(lock.validate(s));
+            readUnlocker.accept(lock, s);
+        }
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers())
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            long s = assertNonZero(writeLocker.apply(lock));
+            assertTrue(lock.validate(s));
+            writeUnlocker.accept(lock, s);
+        }
+    }
+
+    /**
+     * A stamp obtained from an unsuccessful lock operation does not validate
+     */
+    public void testValidate2() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s = assertNonZero(lock.writeLock());
+        assertTrue(lock.validate(s));
+        assertFalse(lock.validate(lock.tryWriteLock()));
+        assertFalse(lock.validate(lock.tryWriteLock(0L, SECONDS)));
+        assertFalse(lock.validate(lock.tryReadLock()));
+        assertFalse(lock.validate(lock.tryReadLock(0L, SECONDS)));
+        assertFalse(lock.validate(lock.tryOptimisticRead()));
+        lock.unlockWrite(s);
+    }
+
+    void assertThrowInterruptedExceptionWhenPreInterrupted(Action[] actions) {
+        for (Action action : actions) {
+            Thread.currentThread().interrupt();
+            try {
+                action.run();
+                shouldThrow();
+            }
+            catch (InterruptedException success) {}
+            catch (Throwable fail) { threadUnexpectedException(fail); }
+            assertFalse(Thread.interrupted());
+        }
+    }
+
+    /**
+     * interruptible operations throw InterruptedException when pre-interrupted
+     */
+    public void testInterruptibleOperationsThrowInterruptedExceptionWhenPreInterrupted() {
+        final StampedLock lock = new StampedLock();
+
+        Action[] interruptibleLockActions = {
+            () -> lock.writeLockInterruptibly(),
+            () -> lock.tryWriteLock(Long.MIN_VALUE, DAYS),
+            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
+            () -> lock.readLockInterruptibly(),
+            () -> lock.tryReadLock(Long.MIN_VALUE, DAYS),
+            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
+            () -> lock.asWriteLock().lockInterruptibly(),
+            () -> lock.asWriteLock().tryLock(0L, DAYS),
+            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
+            () -> lock.asReadLock().lockInterruptibly(),
+            () -> lock.asReadLock().tryLock(0L, DAYS),
+            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
+        };
+        shuffle(interruptibleLockActions);
+
+        assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
+        {
+            long s = lock.writeLock();
+            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
+            lock.unlockWrite(s);
+        }
+        {
+            long s = lock.readLock();
+            assertThrowInterruptedExceptionWhenPreInterrupted(interruptibleLockActions);
+            lock.unlockRead(s);
+        }
+    }
+
+    void assertThrowInterruptedExceptionWhenInterrupted(Action[] actions) {
+        int n = actions.length;
+        Future<?>[] futures = new Future<?>[n];
+        CountDownLatch threadsStarted = new CountDownLatch(n);
+        CountDownLatch done = new CountDownLatch(n);
+
+        for (int i = 0; i < n; i++) {
+            Action action = actions[i];
+            futures[i] = cachedThreadPool.submit(new CheckedRunnable() {
+                public void realRun() throws Throwable {
+                    threadsStarted.countDown();
+                    try {
+                        action.run();
+                        shouldThrow();
+                    }
+                    catch (InterruptedException success) {}
+                    catch (Throwable fail) { threadUnexpectedException(fail); }
+                    assertFalse(Thread.interrupted());
+                    done.countDown();
+                }});
+        }
+
+        await(threadsStarted);
+        assertEquals(n, done.getCount());
+        for (Future<?> future : futures) // Interrupt all the tasks
+            future.cancel(true);
+        await(done);
+    }
+
+    /**
+     * interruptible operations throw InterruptedException when write locked and interrupted
+     */
+    public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+
+        Action[] interruptibleLockBlockingActions = {
+            () -> lock.writeLockInterruptibly(),
+            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
+            () -> lock.readLockInterruptibly(),
+            () -> lock.tryReadLock(Long.MAX_VALUE, DAYS),
+            () -> lock.asWriteLock().lockInterruptibly(),
+            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
+            () -> lock.asReadLock().lockInterruptibly(),
+            () -> lock.asReadLock().tryLock(Long.MAX_VALUE, DAYS),
+        };
+        shuffle(interruptibleLockBlockingActions);
+
+        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
+    }
+
+    /**
+     * interruptible operations throw InterruptedException when read locked and interrupted
+     */
+    public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+
+        Action[] interruptibleLockBlockingActions = {
+            () -> lock.writeLockInterruptibly(),
+            () -> lock.tryWriteLock(Long.MAX_VALUE, DAYS),
+            () -> lock.asWriteLock().lockInterruptibly(),
+            () -> lock.asWriteLock().tryLock(Long.MAX_VALUE, DAYS),
+        };
+        shuffle(interruptibleLockBlockingActions);
+
+        assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions);
+    }
+
+    /**
+     * Non-interruptible operations ignore and preserve interrupt status
+     */
+    public void testNonInterruptibleOperationsIgnoreInterrupts() {
+        final StampedLock lock = new StampedLock();
+        Thread.currentThread().interrupt();
+
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            long s = assertValid(lock, lock.readLock());
+            readUnlocker.accept(lock, s);
+            s = assertValid(lock, lock.tryReadLock());
+            readUnlocker.accept(lock, s);
+        }
+
+        lock.asReadLock().lock();
+        lock.asReadLock().unlock();
+
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            long s = assertValid(lock, lock.writeLock());
+            writeUnlocker.accept(lock, s);
+            s = assertValid(lock, lock.tryWriteLock());
+            writeUnlocker.accept(lock, s);
+        }
+
+        lock.asWriteLock().lock();
+        lock.asWriteLock().unlock();
+
+        assertTrue(Thread.interrupted());
+    }
+
+    /**
+     * tryWriteLock on an unlocked lock succeeds
+     */
+    public void testTryWriteLock() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.tryWriteLock();
+        assertTrue(s != 0L);
+        assertTrue(lock.isWriteLocked());
+        assertEquals(0L, lock.tryWriteLock());
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * tryWriteLock fails if locked
+     */
+    public void testTryWriteLockWhenLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(0L, lock.tryWriteLock());
+            }});
+
+        assertEquals(0L, lock.tryWriteLock());
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * tryReadLock fails if write-locked
+     */
+    public void testTryReadLockWhenLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                assertEquals(0L, lock.tryReadLock());
+            }});
+
+        assertEquals(0L, lock.tryReadLock());
+        awaitTermination(t);
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * Multiple threads can hold a read lock when not write-locked
+     */
+    public void testMultipleReadLocks() {
+        final StampedLock lock = new StampedLock();
+        final long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long s2 = lock.tryReadLock();
+                assertValid(lock, s2);
+                lock.unlockRead(s2);
+                long s3 = lock.tryReadLock(LONG_DELAY_MS, MILLISECONDS);
+                assertValid(lock, s3);
+                lock.unlockRead(s3);
+                long s4 = lock.readLock();
+                assertValid(lock, s4);
+                lock.unlockRead(s4);
+                lock.asReadLock().lock();
+                lock.asReadLock().unlock();
+                lock.asReadLock().lockInterruptibly();
+                lock.asReadLock().unlock();
+                lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS);
+                lock.asReadLock().unlock();
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * writeLock() succeeds only after a reading thread unlocks
+     */
+    public void testWriteAfterReadLock() throws InterruptedException {
+        final CountDownLatch aboutToLock = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        long rs = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                aboutToLock.countDown();
+                long s = lock.writeLock();
+                assertTrue(lock.isWriteLocked());
+                assertFalse(lock.isReadLocked());
+                lock.unlockWrite(s);
+            }});
+
+        aboutToLock.await();
+        waitForThreadToEnterWaitState(t);
+        assertFalse(lock.isWriteLocked());
+        assertTrue(lock.isReadLocked());
+        lock.unlockRead(rs);
+        awaitTermination(t);
+        assertUnlocked(lock);
+    }
+
+    /**
+     * writeLock() succeeds only after reading threads unlock
+     */
+    public void testWriteAfterMultipleReadLocks() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.readLock();
+                lock.unlockRead(rs);
+            }});
+
+        awaitTermination(t1);
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long ws = lock.writeLock();
+                lock.unlockWrite(ws);
+            }});
+
+        assertTrue(lock.isReadLocked());
+        assertFalse(lock.isWriteLocked());
+        lock.unlockRead(s);
+        awaitTermination(t2);
+        assertUnlocked(lock);
+    }
+
+    /**
+     * readLock() succeed only after a writing thread unlocks
+     */
+    public void testReadAfterWriteLock() {
+        final StampedLock lock = new StampedLock();
+        final CountDownLatch threadsStarted = new CountDownLatch(2);
+        final long s = lock.writeLock();
+        final Runnable acquireReleaseReadLock = new CheckedRunnable() {
+            public void realRun() {
+                threadsStarted.countDown();
+                long rs = lock.readLock();
+                assertTrue(lock.isReadLocked());
+                assertFalse(lock.isWriteLocked());
+                lock.unlockRead(rs);
+            }};
+        Thread t1 = newStartedThread(acquireReleaseReadLock);
+        Thread t2 = newStartedThread(acquireReleaseReadLock);
+
+        await(threadsStarted);
+        waitForThreadToEnterWaitState(t1);
+        waitForThreadToEnterWaitState(t2);
+        assertTrue(lock.isWriteLocked());
+        assertFalse(lock.isReadLocked());
+        releaseWriteLock(lock, s);
+        awaitTermination(t1);
+        awaitTermination(t2);
+        assertUnlocked(lock);
+    }
+
+    /**
+     * tryReadLock succeeds if read locked but not write locked
+     */
+    public void testTryLockWhenReadLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                long rs = lock.tryReadLock();
+                assertValid(lock, rs);
+                lock.unlockRead(rs);
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * tryWriteLock fails when read locked
+     */
+    public void testTryWriteLockWhenReadLocked() {
+        final StampedLock lock = new StampedLock();
+        long s = lock.readLock();
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() {
+                threadAssertEquals(0L, lock.tryWriteLock());
+            }});
+
+        awaitTermination(t);
+        lock.unlockRead(s);
+    }
+
+    /**
+     * timed lock operations time out if lock not available
+     */
+    public void testTimedLock_Timeout() throws Exception {
+        ArrayList<Future<?>> futures = new ArrayList<>();
+
+        // Write locked
+        final StampedLock lock = new StampedLock();
+        long stamp = lock.writeLock();
+        assertEquals(0L, lock.tryReadLock(0L, DAYS));
+        assertEquals(0L, lock.tryReadLock(Long.MIN_VALUE, DAYS));
+        assertFalse(lock.asReadLock().tryLock(0L, DAYS));
+        assertFalse(lock.asReadLock().tryLock(Long.MIN_VALUE, DAYS));
+        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
+        assertEquals(0L, lock.tryWriteLock(Long.MIN_VALUE, DAYS));
+        assertFalse(lock.asWriteLock().tryLock(0L, DAYS));
+        assertFalse(lock.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
+
+        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertEquals(0L, lock.tryWriteLock(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }}));
+
+        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertEquals(0L, lock.tryReadLock(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }}));
+
+        // Read locked
+        final StampedLock lock2 = new StampedLock();
+        long stamp2 = lock2.readLock();
+        assertEquals(0L, lock2.tryWriteLock(0L, DAYS));
+        assertEquals(0L, lock2.tryWriteLock(Long.MIN_VALUE, DAYS));
+        assertFalse(lock2.asWriteLock().tryLock(0L, DAYS));
+        assertFalse(lock2.asWriteLock().tryLock(Long.MIN_VALUE, DAYS));
+
+        futures.add(cachedThreadPool.submit(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertEquals(0L, lock2.tryWriteLock(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+            }}));
+
+        for (Future<?> future : futures)
+            assertNull(future.get());
+
+        releaseWriteLock(lock, stamp);
+        releaseReadLock(lock2, stamp2);
+    }
+
+    /**
+     * writeLockInterruptibly succeeds if unlocked
+     */
+    public void testWriteLockInterruptibly() throws InterruptedException {
+        final StampedLock lock = new StampedLock();
+        long s = lock.writeLockInterruptibly();
+        assertTrue(lock.isWriteLocked());
+        releaseWriteLock(lock, s);
+    }
+
+    /**
+     * readLockInterruptibly succeeds if lock free
+     */
+    public void testReadLockInterruptibly() throws InterruptedException {
+        final StampedLock lock = new StampedLock();
+
+        long s = assertValid(lock, lock.readLockInterruptibly());
+        assertTrue(lock.isReadLocked());
+        lock.unlockRead(s);
+
+        lock.asReadLock().lockInterruptibly();
+        assertTrue(lock.isReadLocked());
+        lock.asReadLock().unlock();
+    }
+
+    /**
+     * A serialized lock deserializes as unlocked
+     */
+    public void testSerialization() {
+        StampedLock lock = new StampedLock();
+        lock.writeLock();
+        StampedLock clone = serialClone(lock);
+        assertTrue(lock.isWriteLocked());
+        assertFalse(clone.isWriteLocked());
+        long s = clone.writeLock();
+        assertTrue(clone.isWriteLocked());
+        clone.unlockWrite(s);
+        assertFalse(clone.isWriteLocked());
+    }
+
+    /**
+     * toString indicates current lock state
+     */
+    public void testToString() {
+        StampedLock lock = new StampedLock();
+        assertTrue(lock.toString().contains("Unlocked"));
+        long s = lock.writeLock();
+        assertTrue(lock.toString().contains("Write-locked"));
+        lock.unlockWrite(s);
+        s = lock.readLock();
+        assertTrue(lock.toString().contains("Read-locks"));
+    }
+
+    /**
+     * tryOptimisticRead succeeds and validates if unlocked, fails if
+     * exclusively locked
+     */
+    public void testValidateOptimistic() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+
+        assertValid(lock, lock.tryOptimisticRead());
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
+            long s = assertValid(lock, writeLocker.apply(lock));
+            assertEquals(0L, lock.tryOptimisticRead());
+            releaseWriteLock(lock, s);
+        }
+
+        for (Function<StampedLock, Long> readLocker : readLockers()) {
+            long s = assertValid(lock, readLocker.apply(lock));
+            long p = assertValid(lock, lock.tryOptimisticRead());
+            releaseReadLock(lock, s);
+            assertTrue(lock.validate(p));
+        }
+
+        assertValid(lock, lock.tryOptimisticRead());
+    }
+
+    /**
+     * tryOptimisticRead stamp does not validate if a write lock intervenes
+     */
+    public void testValidateOptimisticWriteLocked() {
+        final StampedLock lock = new StampedLock();
+        final long p = assertValid(lock, lock.tryOptimisticRead());
+        final long s = assertValid(lock, lock.writeLock());
+        assertFalse(lock.validate(p));
+        assertEquals(0L, lock.tryOptimisticRead());
+        assertTrue(lock.validate(s));
+        lock.unlockWrite(s);
+    }
+
+    /**
+     * tryOptimisticRead stamp does not validate if a write lock
+     * intervenes in another thread
+     */
+    public void testValidateOptimisticWriteLocked2()
+            throws InterruptedException {
+        final CountDownLatch locked = new CountDownLatch(1);
+        final StampedLock lock = new StampedLock();
+        final long p = assertValid(lock, lock.tryOptimisticRead());
+
+        Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                lock.writeLockInterruptibly();
+                locked.countDown();
+                lock.writeLockInterruptibly();
+            }});
+
+        locked.await();
+        assertFalse(lock.validate(p));
+        assertEquals(0L, lock.tryOptimisticRead());
+        waitForThreadToEnterWaitState(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertTrue(lock.isWriteLocked());
+    }
+
+    /**
+     * tryConvertToOptimisticRead succeeds and validates if successfully locked
+     */
+    public void testTryConvertToOptimisticRead() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p, q;
+        assertEquals(0L, lock.tryConvertToOptimisticRead(0L));
+
+        s = assertValid(lock, lock.tryOptimisticRead());
+        assertEquals(s, lock.tryConvertToOptimisticRead(s));
+        assertTrue(lock.validate(s));
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers()) {
+            s = assertValid(lock, writeLocker.apply(lock));
+            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
+            assertFalse(lock.validate(s));
+            assertTrue(lock.validate(p));
+            assertUnlocked(lock);
+        }
+
+        for (Function<StampedLock, Long> readLocker : readLockers()) {
+            s = assertValid(lock, readLocker.apply(lock));
+            q = assertValid(lock, lock.tryOptimisticRead());
+            assertEquals(q, lock.tryConvertToOptimisticRead(q));
+            assertTrue(lock.validate(q));
+            assertTrue(lock.isReadLocked());
+            p = assertValid(lock, lock.tryConvertToOptimisticRead(s));
+            assertTrue(lock.validate(p));
+            assertTrue(lock.validate(s));
+            assertUnlocked(lock);
+            assertEquals(q, lock.tryConvertToOptimisticRead(q));
+            assertTrue(lock.validate(q));
+        }
+    }
+
+    /**
+     * tryConvertToReadLock succeeds for valid stamps
+     */
+    public void testTryConvertToReadLock() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+
+        assertEquals(0L, lock.tryConvertToReadLock(0L));
+
+        s = assertValid(lock, lock.tryOptimisticRead());
+        p = assertValid(lock, lock.tryConvertToReadLock(s));
+        assertTrue(lock.isReadLocked());
+        assertEquals(1, lock.getReadLockCount());
+        assertTrue(lock.validate(s));
+        lock.unlockRead(p);
+
+        s = assertValid(lock, lock.tryOptimisticRead());
+        lock.readLock();
+        p = assertValid(lock, lock.tryConvertToReadLock(s));
+        assertTrue(lock.isReadLocked());
+        assertEquals(2, lock.getReadLockCount());
+        lock.unlockRead(p);
+        lock.unlockRead(p);
+        assertUnlocked(lock);
+
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
+                s = assertValid(lock, writeLocker.apply(lock));
+                p = assertValid(lock, lock.tryConvertToReadLock(s));
+                assertFalse(lock.validate(s));
+                assertTrue(lock.isReadLocked());
+                assertEquals(1, lock.getReadLockCount());
+                readUnlocker.accept(lock, p);
+            }
+
+            for (Function<StampedLock, Long> readLocker : readLockers()) {
+                s = assertValid(lock, readLocker.apply(lock));
+                assertEquals(s, lock.tryConvertToReadLock(s));
+                assertTrue(lock.validate(s));
+                assertTrue(lock.isReadLocked());
+                assertEquals(1, lock.getReadLockCount());
+                readUnlocker.accept(lock, s);
+            }
+        }
+    }
+
+    /**
+     * tryConvertToWriteLock succeeds if lock available; fails if multiply read locked
+     */
+    public void testTryConvertToWriteLock() throws InterruptedException {
+        StampedLock lock = new StampedLock();
+        long s, p;
+
+        assertEquals(0L, lock.tryConvertToWriteLock(0L));
+
+        assertTrue((s = lock.tryOptimisticRead()) != 0L);
+        assertTrue((p = lock.tryConvertToWriteLock(s)) != 0L);
+        assertTrue(lock.isWriteLocked());
+        lock.unlockWrite(p);
+
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            for (Function<StampedLock, Long> writeLocker : writeLockers()) {
+                s = assertValid(lock, writeLocker.apply(lock));
+                assertEquals(s, lock.tryConvertToWriteLock(s));
+                assertTrue(lock.validate(s));
+                assertTrue(lock.isWriteLocked());
+                writeUnlocker.accept(lock, s);
+            }
+
+            for (Function<StampedLock, Long> readLocker : readLockers()) {
+                s = assertValid(lock, readLocker.apply(lock));
+                p = assertValid(lock, lock.tryConvertToWriteLock(s));
+                assertFalse(lock.validate(s));
+                assertTrue(lock.validate(p));
+                assertTrue(lock.isWriteLocked());
+                writeUnlocker.accept(lock, p);
+            }
+        }
+
+        // failure if multiply read locked
+        for (Function<StampedLock, Long> readLocker : readLockers()) {
+            s = assertValid(lock, readLocker.apply(lock));
+            p = assertValid(lock, readLocker.apply(lock));
+            assertEquals(0L, lock.tryConvertToWriteLock(s));
+            assertTrue(lock.validate(s));
+            assertTrue(lock.validate(p));
+            assertEquals(2, lock.getReadLockCount());
+            lock.unlock(p);
+            lock.unlock(s);
+            assertUnlocked(lock);
+        }
+    }
+
+    /**
+     * asWriteLock can be locked and unlocked
+     */
+    public void testAsWriteLock() throws Throwable {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asWriteLock();
+        for (Action locker : lockLockers(lock)) {
+            locker.run();
+            assertTrue(sl.isWriteLocked());
+            assertFalse(sl.isReadLocked());
+            assertFalse(lock.tryLock());
+            lock.unlock();
+            assertUnlocked(sl);
+        }
+    }
+
+    /**
+     * asReadLock can be locked and unlocked
+     */
+    public void testAsReadLock() throws Throwable {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadLock();
+        for (Action locker : lockLockers(lock)) {
+            locker.run();
+            assertTrue(sl.isReadLocked());
+            assertFalse(sl.isWriteLocked());
+            assertEquals(1, sl.getReadLockCount());
+            locker.run();
+            assertTrue(sl.isReadLocked());
+            assertEquals(2, sl.getReadLockCount());
+            lock.unlock();
+            lock.unlock();
+            assertUnlocked(sl);
+        }
+    }
+
+    /**
+     * asReadWriteLock.writeLock can be locked and unlocked
+     */
+    public void testAsReadWriteLockWriteLock() throws Throwable {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadWriteLock().writeLock();
+        for (Action locker : lockLockers(lock)) {
+            locker.run();
+            assertTrue(sl.isWriteLocked());
+            assertFalse(sl.isReadLocked());
+            assertFalse(lock.tryLock());
+            lock.unlock();
+            assertUnlocked(sl);
+        }
+    }
+
+    /**
+     * asReadWriteLock.readLock can be locked and unlocked
+     */
+    public void testAsReadWriteLockReadLock() throws Throwable {
+        StampedLock sl = new StampedLock();
+        Lock lock = sl.asReadWriteLock().readLock();
+        for (Action locker : lockLockers(lock)) {
+            locker.run();
+            assertTrue(sl.isReadLocked());
+            assertFalse(sl.isWriteLocked());
+            assertEquals(1, sl.getReadLockCount());
+            locker.run();
+            assertTrue(sl.isReadLocked());
+            assertEquals(2, sl.getReadLockCount());
+            lock.unlock();
+            lock.unlock();
+            assertUnlocked(sl);
+        }
+    }
+
+    /**
+     * Lock.newCondition throws UnsupportedOperationException
+     */
+    public void testLockViewsDoNotSupportConditions() {
+        StampedLock sl = new StampedLock();
+        assertThrows(UnsupportedOperationException.class,
+                     () -> sl.asWriteLock().newCondition(),
+                     () -> sl.asReadLock().newCondition(),
+                     () -> sl.asReadWriteLock().writeLock().newCondition(),
+                     () -> sl.asReadWriteLock().readLock().newCondition());
+    }
+
+    /**
+     * Passing optimistic read stamps to unlock operations result in
+     * IllegalMonitorStateException
+     */
+    public void testCannotUnlockOptimisticReadStamps() {
+        Runnable[] actions = {
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = assertValid(sl, sl.tryOptimisticRead());
+                sl.unlockRead(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryOptimisticRead();
+                sl.unlock(stamp);
+            },
+
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryOptimisticRead();
+                sl.writeLock();
+                sl.unlock(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                sl.readLock();
+                long stamp = assertValid(sl, sl.tryOptimisticRead());
+                sl.unlockRead(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                sl.readLock();
+                long stamp = assertValid(sl, sl.tryOptimisticRead());
+                sl.unlock(stamp);
+            },
+
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
+                assertValid(sl, stamp);
+                sl.writeLock();
+                sl.unlockWrite(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
+                sl.writeLock();
+                sl.unlock(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
+                sl.readLock();
+                sl.unlockRead(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.writeLock());
+                sl.readLock();
+                sl.unlock(stamp);
+            },
+
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                assertValid(sl, stamp);
+                sl.writeLock();
+                sl.unlockWrite(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                sl.writeLock();
+                sl.unlock(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                sl.readLock();
+                sl.unlockRead(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                sl.readLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                assertValid(sl, stamp);
+                sl.readLock();
+                sl.unlockRead(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                sl.readLock();
+                sl.unlock(stamp);
+            },
+            () -> {
+                StampedLock sl = new StampedLock();
+                sl.readLock();
+                long stamp = sl.tryConvertToOptimisticRead(sl.readLock());
+                sl.readLock();
+                sl.unlock(stamp);
+            },
+        };
+
+        assertThrows(IllegalMonitorStateException.class, actions);
+    }
+
+    static long writeLockInterruptiblyUninterrupted(StampedLock sl) {
+        try { return sl.writeLockInterruptibly(); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long tryWriteLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
+        try { return sl.tryWriteLock(time, unit); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long readLockInterruptiblyUninterrupted(StampedLock sl) {
+        try { return sl.readLockInterruptibly(); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    static long tryReadLockUninterrupted(StampedLock sl, long time, TimeUnit unit) {
+        try { return sl.tryReadLock(time, unit); }
+        catch (InterruptedException ex) { throw new AssertionError(ex); }
+    }
+
+    /**
+     * Invalid stamps result in IllegalMonitorStateException
+     */
+    public void testInvalidStampsThrowIllegalMonitorStateException() {
+        final StampedLock sl = new StampedLock();
+
+        assertThrows(IllegalMonitorStateException.class,
+                     () -> sl.unlockWrite(0L),
+                     () -> sl.unlockRead(0L),
+                     () -> sl.unlock(0L));
+
+        final long optimisticStamp = sl.tryOptimisticRead();
+        final long readStamp = sl.readLock();
+        sl.unlockRead(readStamp);
+        final long writeStamp = sl.writeLock();
+        sl.unlockWrite(writeStamp);
+        assertTrue(optimisticStamp != 0L && readStamp != 0L && writeStamp != 0L);
+        final long[] noLongerValidStamps = { optimisticStamp, readStamp, writeStamp };
+        final Runnable assertNoLongerValidStampsThrow = () -> {
+            for (long noLongerValidStamp : noLongerValidStamps)
+                assertThrows(IllegalMonitorStateException.class,
+                             () -> sl.unlockWrite(noLongerValidStamp),
+                             () -> sl.unlockRead(noLongerValidStamp),
+                             () -> sl.unlock(noLongerValidStamp));
+        };
+        assertNoLongerValidStampsThrow.run();
+
+        for (Function<StampedLock, Long> readLocker : readLockers())
+        for (BiConsumer<StampedLock, Long> readUnlocker : readUnlockers()) {
+            final long stamp = readLocker.apply(sl);
+            assertValid(sl, stamp);
+            assertNoLongerValidStampsThrow.run();
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlockWrite(stamp),
+                         () -> sl.unlockRead(sl.tryOptimisticRead()),
+                         () -> sl.unlockRead(0L));
+            readUnlocker.accept(sl, stamp);
+            assertUnlocked(sl);
+            assertNoLongerValidStampsThrow.run();
+        }
+
+        for (Function<StampedLock, Long> writeLocker : writeLockers())
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            final long stamp = writeLocker.apply(sl);
+            assertValid(sl, stamp);
+            assertNoLongerValidStampsThrow.run();
+            assertThrows(IllegalMonitorStateException.class,
+                         () -> sl.unlockRead(stamp),
+                         () -> sl.unlockWrite(0L));
+            writeUnlocker.accept(sl, stamp);
+            assertUnlocked(sl);
+            assertNoLongerValidStampsThrow.run();
+        }
+    }
+
+    /**
+     * Read locks can be very deeply nested
+     */
+    public void testDeeplyNestedReadLocks() {
+        final StampedLock lock = new StampedLock();
+        final int depth = 300;
+        final long[] stamps = new long[depth];
+        final List<Function<StampedLock, Long>> readLockers = readLockers();
+        final List<BiConsumer<StampedLock, Long>> readUnlockers = readUnlockers();
+        for (int i = 0; i < depth; i++) {
+            Function<StampedLock, Long> readLocker
+                = readLockers.get(i % readLockers.size());
+            long stamp = readLocker.apply(lock);
+            assertEquals(i + 1, lock.getReadLockCount());
+            assertTrue(lock.isReadLocked());
+            stamps[i] = stamp;
+        }
+        for (int i = 0; i < depth; i++) {
+            BiConsumer<StampedLock, Long> readUnlocker
+                = readUnlockers.get(i % readUnlockers.size());
+            assertEquals(depth - i, lock.getReadLockCount());
+            assertTrue(lock.isReadLocked());
+            readUnlocker.accept(lock, stamps[depth - 1 - i]);
+        }
+        assertUnlocked(lock);
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/SynchronousQueueTest.java b/ojluni/src/test/java/util/concurrent/tck/SynchronousQueueTest.java
new file mode 100644
index 0000000..5ff8ea2
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/SynchronousQueueTest.java
@@ -0,0 +1,643 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.SynchronousQueue;
+
+import junit.framework.Test;
+
+public class SynchronousQueueTest extends JSR166TestCase {
+
+    public static class Fair extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new SynchronousQueue(true);
+        }
+    }
+
+    public static class NonFair extends BlockingQueueTest {
+        protected BlockingQueue emptyCollection() {
+            return new SynchronousQueue(false);
+        }
+    }
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return newTestSuite(SynchronousQueueTest.class,
+                            new Fair().testSuite(),
+                            new NonFair().testSuite());
+    }
+
+    /**
+     * Any SynchronousQueue is both empty and full
+     */
+    public void testEmptyFull()      { testEmptyFull(false); }
+    public void testEmptyFull_fair() { testEmptyFull(true); }
+    public void testEmptyFull(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertEquals(0, q.remainingCapacity());
+        assertFalse(q.offer(zero));
+    }
+
+    /**
+     * offer fails if no active taker
+     */
+    public void testOffer()      { testOffer(false); }
+    public void testOffer_fair() { testOffer(true); }
+    public void testOffer(boolean fair) {
+        SynchronousQueue q = new SynchronousQueue(fair);
+        assertFalse(q.offer(one));
+    }
+
+    /**
+     * add throws IllegalStateException if no active taker
+     */
+    public void testAdd()      { testAdd(false); }
+    public void testAdd_fair() { testAdd(true); }
+    public void testAdd(boolean fair) {
+        SynchronousQueue q = new SynchronousQueue(fair);
+        assertEquals(0, q.remainingCapacity());
+        try {
+            q.add(one);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * addAll(this) throws IllegalArgumentException
+     */
+    public void testAddAll_self()      { testAddAll_self(false); }
+    public void testAddAll_self_fair() { testAddAll_self(true); }
+    public void testAddAll_self(boolean fair) {
+        SynchronousQueue q = new SynchronousQueue(fair);
+        try {
+            q.addAll(q);
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * addAll throws ISE if no active taker
+     */
+    public void testAddAll_ISE()      { testAddAll_ISE(false); }
+    public void testAddAll_ISE_fair() { testAddAll_ISE(true); }
+    public void testAddAll_ISE(boolean fair) {
+        SynchronousQueue q = new SynchronousQueue(fair);
+        Integer[] ints = new Integer[1];
+        for (int i = 0; i < ints.length; i++)
+            ints[i] = i;
+        Collection<Integer> coll = Arrays.asList(ints);
+        try {
+            q.addAll(coll);
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * put blocks interruptibly if no active taker
+     */
+    public void testBlockingPut()      { testBlockingPut(false); }
+    public void testBlockingPut_fair() { testBlockingPut(true); }
+    public void testBlockingPut(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.currentThread().interrupt();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * put blocks interruptibly waiting for take
+     */
+    public void testPutWithTake()      { testPutWithTake(false); }
+    public void testPutWithTake_fair() { testPutWithTake(true); }
+    public void testPutWithTake(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CountDownLatch pleaseTake = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                pleaseTake.countDown();
+                q.put(one);
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.put(99);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseTake);
+        assertEquals(0, q.remainingCapacity());
+        try { assertSame(one, q.take()); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        assertEquals(0, q.remainingCapacity());
+    }
+
+    /**
+     * timed offer times out if elements not taken
+     */
+    public void testTimedOffer()      { testTimedOffer(false); }
+    public void testTimedOffer_fair() { testTimedOffer(true); }
+    public void testTimedOffer(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertFalse(q.offer(new Object(), timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+                pleaseInterrupt.countDown();
+                try {
+                    q.offer(new Object(), 2 * LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * poll return null if no active putter
+     */
+    public void testPoll()      { testPoll(false); }
+    public void testPoll_fair() { testPoll(true); }
+    public void testPoll(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        assertNull(q.poll());
+    }
+
+    /**
+     * timed poll with zero timeout times out if no active putter
+     */
+    public void testTimedPoll0()      { testTimedPoll0(false); }
+    public void testTimedPoll0_fair() { testTimedPoll0(true); }
+    public void testTimedPoll0(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        try { assertNull(q.poll(0, MILLISECONDS)); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+    }
+
+    /**
+     * timed poll with nonzero timeout times out if no active putter
+     */
+    public void testTimedPoll()      { testTimedPoll(false); }
+    public void testTimedPoll_fair() { testTimedPoll(true); }
+    public void testTimedPoll(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        long startTime = System.nanoTime();
+        try { assertNull(q.poll(timeoutMillis(), MILLISECONDS)); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+        assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+    }
+
+    /**
+     * timed poll before a delayed offer times out, returning null;
+     * after offer succeeds; on interruption throws
+     */
+    public void testTimedPollWithOffer()      { testTimedPollWithOffer(false); }
+    public void testTimedPollWithOffer_fair() { testTimedPollWithOffer(true); }
+    public void testTimedPollWithOffer(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CountDownLatch pleaseOffer = new CountDownLatch(1);
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                long startTime = System.nanoTime();
+                assertNull(q.poll(timeoutMillis(), MILLISECONDS));
+                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
+
+                pleaseOffer.countDown();
+                startTime = System.nanoTime();
+                assertSame(zero, q.poll(LONG_DELAY_MS, MILLISECONDS));
+
+                Thread.currentThread().interrupt();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    q.poll(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            }});
+
+        await(pleaseOffer);
+        long startTime = System.nanoTime();
+        try { assertTrue(q.offer(zero, LONG_DELAY_MS, MILLISECONDS)); }
+        catch (InterruptedException e) { threadUnexpectedException(e); }
+        assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * peek() returns null if no active putter
+     */
+    public void testPeek()      { testPeek(false); }
+    public void testPeek_fair() { testPeek(true); }
+    public void testPeek(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        assertNull(q.peek());
+    }
+
+    /**
+     * element() throws NoSuchElementException if no active putter
+     */
+    public void testElement()      { testElement(false); }
+    public void testElement_fair() { testElement(true); }
+    public void testElement(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        try {
+            q.element();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * remove() throws NoSuchElementException if no active putter
+     */
+    public void testRemove()      { testRemove(false); }
+    public void testRemove_fair() { testRemove(true); }
+    public void testRemove(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        try {
+            q.remove();
+            shouldThrow();
+        } catch (NoSuchElementException success) {}
+    }
+
+    /**
+     * contains returns false
+     */
+    public void testContains()      { testContains(false); }
+    public void testContains_fair() { testContains(true); }
+    public void testContains(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        assertFalse(q.contains(zero));
+    }
+
+    /**
+     * clear ensures isEmpty
+     */
+    public void testClear()      { testClear(false); }
+    public void testClear_fair() { testClear(true); }
+    public void testClear(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll returns false unless empty
+     */
+    public void testContainsAll()      { testContainsAll(false); }
+    public void testContainsAll_fair() { testContainsAll(true); }
+    public void testContainsAll(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Integer[] empty = new Integer[0];
+        assertTrue(q.containsAll(Arrays.asList(empty)));
+        Integer[] ints = new Integer[1]; ints[0] = zero;
+        assertFalse(q.containsAll(Arrays.asList(ints)));
+    }
+
+    /**
+     * retainAll returns false
+     */
+    public void testRetainAll()      { testRetainAll(false); }
+    public void testRetainAll_fair() { testRetainAll(true); }
+    public void testRetainAll(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Integer[] empty = new Integer[0];
+        assertFalse(q.retainAll(Arrays.asList(empty)));
+        Integer[] ints = new Integer[1]; ints[0] = zero;
+        assertFalse(q.retainAll(Arrays.asList(ints)));
+    }
+
+    /**
+     * removeAll returns false
+     */
+    public void testRemoveAll()      { testRemoveAll(false); }
+    public void testRemoveAll_fair() { testRemoveAll(true); }
+    public void testRemoveAll(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Integer[] empty = new Integer[0];
+        assertFalse(q.removeAll(Arrays.asList(empty)));
+        Integer[] ints = new Integer[1]; ints[0] = zero;
+        assertFalse(q.containsAll(Arrays.asList(ints)));
+    }
+
+    /**
+     * toArray is empty
+     */
+    public void testToArray()      { testToArray(false); }
+    public void testToArray_fair() { testToArray(true); }
+    public void testToArray(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Object[] o = q.toArray();
+        assertEquals(0, o.length);
+    }
+
+    /**
+     * toArray(Integer array) returns its argument with the first
+     * element (if present) nulled out
+     */
+    public void testToArray2()      { testToArray2(false); }
+    public void testToArray2_fair() { testToArray2(true); }
+    public void testToArray2(boolean fair) {
+        final SynchronousQueue<Integer> q = new SynchronousQueue<>(fair);
+        Integer[] a;
+
+        a = new Integer[0];
+        assertSame(a, q.toArray(a));
+
+        a = new Integer[3];
+        Arrays.fill(a, 42);
+        assertSame(a, q.toArray(a));
+        assertNull(a[0]);
+        for (int i = 1; i < a.length; i++)
+            assertEquals(42, (int) a[i]);
+    }
+
+    /**
+     * toArray(null) throws NPE
+     */
+    public void testToArray_null()      { testToArray_null(false); }
+    public void testToArray_null_fair() { testToArray_null(true); }
+    public void testToArray_null(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        try {
+            Object[] o = q.toArray(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * iterator does not traverse any elements
+     */
+    public void testIterator()      { testIterator(false); }
+    public void testIterator_fair() { testIterator(true); }
+    public void testIterator(boolean fair) {
+        assertIteratorExhausted(new SynchronousQueue(fair).iterator());
+    }
+
+    /**
+     * iterator remove throws ISE
+     */
+    public void testIteratorRemove()      { testIteratorRemove(false); }
+    public void testIteratorRemove_fair() { testIteratorRemove(true); }
+    public void testIteratorRemove(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Iterator it = q.iterator();
+        try {
+            it.remove();
+            shouldThrow();
+        } catch (IllegalStateException success) {}
+    }
+
+    /**
+     * toString returns a non-null string
+     */
+    public void testToString()      { testToString(false); }
+    public void testToString_fair() { testToString(true); }
+    public void testToString(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        String s = q.toString();
+        assertNotNull(s);
+    }
+
+    /**
+     * offer transfers elements across Executor tasks
+     */
+    public void testOfferInExecutor()      { testOfferInExecutor(false); }
+    public void testOfferInExecutor_fair() { testOfferInExecutor(true); }
+    public void testOfferInExecutor(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(q.offer(one));
+                    threadsStarted.await();
+                    assertTrue(q.offer(one, LONG_DELAY_MS, MILLISECONDS));
+                    assertEquals(0, q.remainingCapacity());
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    assertSame(one, q.take());
+                }});
+        }
+    }
+
+    /**
+     * timed poll retrieves elements across Executor threads
+     */
+    public void testPollInExecutor()      { testPollInExecutor(false); }
+    public void testPollInExecutor_fair() { testPollInExecutor(true); }
+    public void testPollInExecutor(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        final CheckedBarrier threadsStarted = new CheckedBarrier(2);
+        final ExecutorService executor = Executors.newFixedThreadPool(2);
+        try (PoolCleaner cleaner = cleaner(executor)) {
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertNull(q.poll());
+                    threadsStarted.await();
+                    assertSame(one, q.poll(LONG_DELAY_MS, MILLISECONDS));
+                    assertTrue(q.isEmpty());
+                }});
+
+            executor.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadsStarted.await();
+                    q.put(one);
+                }});
+        }
+    }
+
+    /**
+     * a deserialized serialized queue is usable
+     */
+    public void testSerialization() {
+        final SynchronousQueue x = new SynchronousQueue();
+        final SynchronousQueue y = new SynchronousQueue(false);
+        final SynchronousQueue z = new SynchronousQueue(true);
+        assertSerialEquals(x, y);
+        assertNotSerialEquals(x, z);
+        SynchronousQueue[] qs = { x, y, z };
+        for (SynchronousQueue q : qs) {
+            SynchronousQueue clone = serialClone(q);
+            assertNotSame(q, clone);
+            assertSerialEquals(q, clone);
+            assertTrue(clone.isEmpty());
+            assertEquals(0, clone.size());
+            assertEquals(0, clone.remainingCapacity());
+            assertFalse(clone.offer(zero));
+        }
+    }
+
+    /**
+     * drainTo(c) of empty queue doesn't transfer elements
+     */
+    public void testDrainTo()      { testDrainTo(false); }
+    public void testDrainTo_fair() { testDrainTo(true); }
+    public void testDrainTo(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        ArrayList l = new ArrayList();
+        q.drainTo(l);
+        assertEquals(0, q.size());
+        assertEquals(0, l.size());
+    }
+
+    /**
+     * drainTo empties queue, unblocking a waiting put.
+     */
+    public void testDrainToWithActivePut()      { testDrainToWithActivePut(false); }
+    public void testDrainToWithActivePut_fair() { testDrainToWithActivePut(true); }
+    public void testDrainToWithActivePut(boolean fair) {
+        final SynchronousQueue q = new SynchronousQueue(fair);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(one);
+            }});
+
+        ArrayList l = new ArrayList();
+        long startTime = System.nanoTime();
+        while (l.isEmpty()) {
+            q.drainTo(l);
+            if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                fail("timed out");
+            Thread.yield();
+        }
+        assertTrue(l.size() == 1);
+        assertSame(one, l.get(0));
+        awaitTermination(t);
+    }
+
+    /**
+     * drainTo(c, n) empties up to n elements of queue into c
+     */
+    public void testDrainToN() throws InterruptedException {
+        final SynchronousQueue q = new SynchronousQueue();
+        Thread t1 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(one);
+            }});
+
+        Thread t2 = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                q.put(two);
+            }});
+
+        ArrayList l = new ArrayList();
+        int drained;
+        while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
+        assertEquals(1, drained);
+        assertEquals(1, l.size());
+        while ((drained = q.drainTo(l, 1)) == 0) Thread.yield();
+        assertEquals(1, drained);
+        assertEquals(2, l.size());
+        assertTrue(l.contains(one));
+        assertTrue(l.contains(two));
+        awaitTermination(t1);
+        awaitTermination(t2);
+    }
+
+    /**
+     * remove(null), contains(null) always return false
+     */
+    public void testNeverContainsNull() {
+        Collection<?> q = new SynchronousQueue();
+        assertFalse(q.contains(null));
+        assertFalse(q.remove(null));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/SystemTest.java b/ojluni/src/test/java/util/concurrent/tck/SystemTest.java
new file mode 100644
index 0000000..fc2a05b
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/SystemTest.java
@@ -0,0 +1,97 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class SystemTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(SystemTest.class);
+    }
+
+    /**
+     * Worst case rounding for millisecs; set for 60 cycle millis clock.
+     * This value might need to be changed on JVMs with coarser
+     * System.currentTimeMillis clocks.
+     */
+    static final long MILLIS_ROUND = 17;
+
+    /**
+     * Nanos between readings of millis is no longer than millis (plus
+     * possible rounding).
+     * This shows only that nano timing not (much) worse than milli.
+     */
+    public void testNanoTime1() throws InterruptedException {
+        long m1 = System.currentTimeMillis();
+        Thread.sleep(1);
+        long n1 = System.nanoTime();
+        Thread.sleep(SHORT_DELAY_MS);
+        long n2 = System.nanoTime();
+        Thread.sleep(1);
+        long m2 = System.currentTimeMillis();
+        long millis = m2 - m1;
+        long nanos = n2 - n1;
+        assertTrue(nanos >= 0);
+        long nanosAsMillis = nanos / 1000000;
+        assertTrue(nanosAsMillis <= millis + MILLIS_ROUND);
+    }
+
+    /**
+     * Millis between readings of nanos is less than nanos, adjusting
+     * for rounding.
+     * This shows only that nano timing not (much) worse than milli.
+     */
+    public void testNanoTime2() throws InterruptedException {
+        long n1 = System.nanoTime();
+        Thread.sleep(1);
+        long m1 = System.currentTimeMillis();
+        Thread.sleep(SHORT_DELAY_MS);
+        long m2 = System.currentTimeMillis();
+        Thread.sleep(1);
+        long n2 = System.nanoTime();
+        long millis = m2 - m1;
+        long nanos = n2 - n1;
+
+        assertTrue(nanos >= 0);
+        long nanosAsMillis = nanos / 1000000;
+        assertTrue(millis <= nanosAsMillis + MILLIS_ROUND);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java
new file mode 100644
index 0000000..37ecba1
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandom8Test.java
@@ -0,0 +1,279 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.LongAdder;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadLocalRandom8Test extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ThreadLocalRandom8Test.class);
+    }
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 26);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS =
+        Integer.getInteger("ThreadLocalRandom8Test.reps", 4);
+
+    /**
+     * Invoking sized ints, long, doubles, with negative sizes throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamSize() {
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        Runnable[] throwingActions = {
+            () -> r.ints(-1L),
+            () -> r.ints(-1L, 2, 3),
+            () -> r.longs(-1L),
+            () -> r.longs(-1L, -1L, 1L),
+            () -> r.doubles(-1L),
+            () -> r.doubles(-1L, .5, .6),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * Invoking bounded ints, long, doubles, with illegal bounds throws
+     * IllegalArgumentException
+     */
+    public void testBadStreamBounds() {
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        Runnable[] throwingActions = {
+            () -> r.ints(2, 1),
+            () -> r.ints(10, 42, 42),
+            () -> r.longs(-1L, -1L),
+            () -> r.longs(10, 1L, -2L),
+            () -> r.doubles(0.0, 0.0),
+            () -> r.doubles(10, .5, .4),
+        };
+        assertThrows(IllegalArgumentException.class, throwingActions);
+    }
+
+    /**
+     * A parallel sized stream of ints generates the given number of values
+     */
+    public void testIntsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.ints(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of longs generates the given number of values
+     */
+    public void testLongsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.longs(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * A parallel sized stream of doubles generates the given number of values
+     */
+    public void testDoublesCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 0;
+        for (int reps = 0; reps < REPS; ++reps) {
+            counter.reset();
+            r.doubles(size).parallel().forEach(x -> counter.increment());
+            assertEquals(size, counter.sum());
+            size += 524959;
+        }
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded ints is within bounds
+     */
+    public void testBoundedInts() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 12345L;
+        for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) {
+                final int lo = least, hi = bound;
+                r.ints(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded longs is within bounds
+     */
+    public void testBoundedLongs() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 123L;
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                final long lo = least, hi = bound;
+                r.longs(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * Each of a parallel sized stream of bounded doubles is within bounds
+     */
+    public void testBoundedDoubles() {
+        AtomicInteger fails = new AtomicInteger(0);
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 456;
+        for (double least = 0.00011; least < 1.0e20; least *= 9) {
+            for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) {
+                final double lo = least, hi = bound;
+                r.doubles(size, lo, hi).parallel().forEach(
+                    x -> {
+                        if (x < lo || x >= hi)
+                            fails.getAndIncrement(); });
+            }
+        }
+        assertEquals(0, fails.get());
+    }
+
+    /**
+     * A parallel unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.ints().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A parallel unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.longs().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A parallel unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCount() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.doubles().limit(size).parallel().forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of ints generates at least 100 values
+     */
+    public void testUnsizedIntsCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.ints().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of longs generates at least 100 values
+     */
+    public void testUnsizedLongsCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.longs().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A sequential unsized stream of doubles generates at least 100 values
+     */
+    public void testUnsizedDoublesCountSeq() {
+        LongAdder counter = new LongAdder();
+        ThreadLocalRandom r = ThreadLocalRandom.current();
+        long size = 100;
+        r.doubles().limit(size).forEach(x -> counter.increment());
+        assertEquals(size, counter.sum());
+    }
+
+    /**
+     * A deserialized ThreadLocalRandom is always identical to
+     * ThreadLocalRandom.current()
+     */
+    public void testSerialization() {
+        assertSame(
+            ThreadLocalRandom.current(),
+            serialClone(ThreadLocalRandom.current()));
+        // In the current implementation, there is exactly one shared instance
+        if (testImplementationDetails)
+            assertSame(
+                ThreadLocalRandom.current(),
+                java.util.concurrent.CompletableFuture.supplyAsync(
+                    () -> serialClone(ThreadLocalRandom.current())).join());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandomTest.java b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandomTest.java
new file mode 100644
index 0000000..9fa46b5
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalRandomTest.java
@@ -0,0 +1,413 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicReference;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadLocalRandomTest extends JSR166TestCase {
+
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ThreadLocalRandomTest.class);
+    }
+
+    /*
+     * Testing coverage notes:
+     *
+     * We don't test randomness properties, but only that repeated
+     * calls, up to NCALLS tries, produce at least one different
+     * result.  For bounded versions, we sample various intervals
+     * across multiples of primes.
+     */
+
+    // max numbers of calls to detect getting stuck on one value
+    static final int NCALLS = 10000;
+
+    // max sampled int bound
+    static final int MAX_INT_BOUND = (1 << 28);
+
+    // max sampled long bound
+    static final long MAX_LONG_BOUND = (1L << 42);
+
+    // Number of replications for other checks
+    static final int REPS = 20;
+
+    /**
+     * setSeed throws UnsupportedOperationException
+     */
+    public void testSetSeed() {
+        try {
+            ThreadLocalRandom.current().setSeed(17);
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+    }
+
+    /**
+     * Repeated calls to next (only accessible via reflection) produce
+     * at least two distinct results, and repeated calls produce all
+     * possible values.
+     */
+    public void testNext() throws ReflectiveOperationException {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        final java.lang.reflect.Method m;
+        try {
+            m = ThreadLocalRandom.class.getDeclaredMethod(
+                    "next", new Class[] { int.class });
+            m.setAccessible(true);
+        } catch (SecurityException acceptable) {
+            // Security manager may deny access
+            return;
+        } catch (Exception ex) {
+            // jdk9 module system may deny access
+            if (ex.getClass().getSimpleName()
+                .equals("InaccessibleObjectException"))
+                return;
+            throw ex;
+        }
+
+        int i;
+        {
+            int val = new java.util.Random().nextInt(4);
+            for (i = 0; i < NCALLS; i++) {
+                int q = (int) m.invoke(rnd, new Object[] { 2 });
+                if (val == q) break;
+            }
+            assertTrue(i < NCALLS);
+        }
+
+        {
+            int r = (int) m.invoke(rnd, new Object[] { 3 });
+            for (i = 0; i < NCALLS; i++) {
+                int q = (int) m.invoke(rnd, new Object[] { 3 });
+                assertTrue(q < (1<<3));
+                if (r != q) break;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * Repeated calls to nextInt produce at least two distinct results
+     */
+    public void testNextInt() {
+        int f = ThreadLocalRandom.current().nextInt();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextInt() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextLong produce at least two distinct results
+     */
+    public void testNextLong() {
+        long f = ThreadLocalRandom.current().nextLong();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextLong() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextBoolean produce at least two distinct results
+     */
+    public void testNextBoolean() {
+        boolean f = ThreadLocalRandom.current().nextBoolean();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextBoolean() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextFloat produce at least two distinct results
+     */
+    public void testNextFloat() {
+        float f = ThreadLocalRandom.current().nextFloat();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextFloat() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextDouble produce at least two distinct results
+     */
+    public void testNextDouble() {
+        double f = ThreadLocalRandom.current().nextDouble();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextDouble() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * Repeated calls to nextGaussian produce at least two distinct results
+     */
+    public void testNextGaussian() {
+        double f = ThreadLocalRandom.current().nextGaussian();
+        int i = 0;
+        while (i < NCALLS && ThreadLocalRandom.current().nextGaussian() == f)
+            ++i;
+        assertTrue(i < NCALLS);
+    }
+
+    /**
+     * nextInt(non-positive) throws IllegalArgumentException
+     */
+    public void testNextIntBoundNonPositive() {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        for (int bound : new int[] { 0, -17, Integer.MIN_VALUE }) {
+            try {
+                rnd.nextInt(bound);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * nextInt(least >= bound) throws IllegalArgumentException
+     */
+    public void testNextIntBadBounds() {
+        int[][] badBoundss = {
+            { 17, 2 },
+            { -42, -42 },
+            { Integer.MAX_VALUE, Integer.MIN_VALUE },
+        };
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        for (int[] badBounds : badBoundss) {
+            try {
+                rnd.nextInt(badBounds[0], badBounds[1]);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * nextInt(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded() {
+        // sample bound space across prime number increments
+        for (int bound = 2; bound < MAX_INT_BOUND; bound += 524959) {
+            int f = ThreadLocalRandom.current().nextInt(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            int j;
+            while (i < NCALLS &&
+                   (j = ThreadLocalRandom.current().nextInt(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextInt(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextIntBounded2() {
+        for (int least = -15485863; least < MAX_INT_BOUND; least += 524959) {
+            for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 49979687) {
+                int f = ThreadLocalRandom.current().nextInt(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                int j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextInt(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextLong(non-positive) throws IllegalArgumentException
+     */
+    public void testNextLongBoundNonPositive() {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        for (long bound : new long[] { 0L, -17L, Long.MIN_VALUE }) {
+            try {
+                rnd.nextLong(bound);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * nextLong(least >= bound) throws IllegalArgumentException
+     */
+    public void testNextLongBadBounds() {
+        long[][] badBoundss = {
+            { 17L, 2L },
+            { -42L, -42L },
+            { Long.MAX_VALUE, Long.MIN_VALUE },
+        };
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        for (long[] badBounds : badBoundss) {
+            try {
+                rnd.nextLong(badBounds[0], badBounds[1]);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * nextLong(bound) returns 0 <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded() {
+        for (long bound = 2; bound < MAX_LONG_BOUND; bound += 15485863) {
+            long f = ThreadLocalRandom.current().nextLong(bound);
+            assertTrue(0 <= f && f < bound);
+            int i = 0;
+            long j;
+            while (i < NCALLS &&
+                   (j = ThreadLocalRandom.current().nextLong(bound)) == f) {
+                assertTrue(0 <= j && j < bound);
+                ++i;
+            }
+            assertTrue(i < NCALLS);
+        }
+    }
+
+    /**
+     * nextLong(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextLongBounded2() {
+        for (long least = -86028121; least < MAX_LONG_BOUND; least += 982451653L) {
+            for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) {
+                long f = ThreadLocalRandom.current().nextLong(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                long j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextLong(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * nextDouble(non-positive) throws IllegalArgumentException
+     */
+    public void testNextDoubleBoundNonPositive() {
+        ThreadLocalRandom rnd = ThreadLocalRandom.current();
+        double[] badBounds = {
+            0.0d,
+            -17.0d,
+            -Double.MIN_VALUE,
+            Double.NEGATIVE_INFINITY,
+            Double.NaN,
+        };
+        for (double bound : badBounds) {
+            try {
+                rnd.nextDouble(bound);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * nextDouble(least, bound) returns least <= value < bound;
+     * repeated calls produce at least two distinct results
+     */
+    public void testNextDoubleBounded2() {
+        for (double least = 0.0001; least < 1.0e20; least *= 8) {
+            for (double bound = least * 1.001; bound < 1.0e20; bound *= 16) {
+                double f = ThreadLocalRandom.current().nextDouble(least, bound);
+                assertTrue(least <= f && f < bound);
+                int i = 0;
+                double j;
+                while (i < NCALLS &&
+                       (j = ThreadLocalRandom.current().nextDouble(least, bound)) == f) {
+                    assertTrue(least <= j && j < bound);
+                    ++i;
+                }
+                assertTrue(i < NCALLS);
+            }
+        }
+    }
+
+    /**
+     * Different threads produce different pseudo-random sequences
+     */
+    public void testDifferentSequences() {
+        // Don't use main thread's ThreadLocalRandom - it is likely to
+        // be polluted by previous tests.
+        final AtomicReference<ThreadLocalRandom> threadLocalRandom =
+            new AtomicReference<ThreadLocalRandom>();
+        final AtomicLong rand = new AtomicLong();
+
+        long firstRand = 0;
+        ThreadLocalRandom firstThreadLocalRandom = null;
+
+        Runnable getRandomState = new CheckedRunnable() {
+            public void realRun() {
+                ThreadLocalRandom current = ThreadLocalRandom.current();
+                assertSame(current, ThreadLocalRandom.current());
+                // test bug: the following is not guaranteed and not true in JDK8
+                //                assertNotSame(current, threadLocalRandom.get());
+                rand.set(current.nextLong());
+                threadLocalRandom.set(current);
+            }};
+
+        Thread first = newStartedThread(getRandomState);
+        awaitTermination(first);
+        firstRand = rand.get();
+        firstThreadLocalRandom = threadLocalRandom.get();
+
+        for (int i = 0; i < NCALLS; i++) {
+            Thread t = newStartedThread(getRandomState);
+            awaitTermination(t);
+            if (firstRand != rand.get())
+                return;
+        }
+        fail("all threads generate the same pseudo-random sequence");
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadLocalTest.java b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalTest.java
new file mode 100644
index 0000000..05588ba
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadLocalTest.java
@@ -0,0 +1,129 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadLocalTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ThreadLocalTest.class);
+    }
+
+    static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
+            public Integer initialValue() {
+                return one;
+            }
+        };
+
+    static InheritableThreadLocal<Integer> itl =
+        new InheritableThreadLocal<Integer>() {
+            protected Integer initialValue() {
+                return zero;
+            }
+
+            protected Integer childValue(Integer parentValue) {
+                return new Integer(parentValue.intValue() + 1);
+            }
+        };
+
+    /**
+     * remove causes next access to return initial value
+     */
+    public void testRemove() {
+        assertSame(tl.get(), one);
+        tl.set(two);
+        assertSame(tl.get(), two);
+        tl.remove();
+        assertSame(tl.get(), one);
+    }
+
+    /**
+     * remove in InheritableThreadLocal causes next access to return
+     * initial value
+     */
+    public void testRemoveITL() {
+        assertSame(itl.get(), zero);
+        itl.set(two);
+        assertSame(itl.get(), two);
+        itl.remove();
+        assertSame(itl.get(), zero);
+    }
+
+    private class ITLThread extends Thread {
+        final int[] x;
+        ITLThread(int[] array) { x = array; }
+        public void run() {
+            Thread child = null;
+            if (itl.get().intValue() < x.length - 1) {
+                child = new ITLThread(x);
+                child.start();
+            }
+            Thread.yield();
+
+            int threadId = itl.get().intValue();
+            for (int j = 0; j < threadId; j++) {
+                x[threadId]++;
+                Thread.yield();
+            }
+
+            if (child != null) { // Wait for child (if any)
+                try {
+                    child.join();
+                } catch (InterruptedException e) {
+                    threadUnexpectedException(e);
+                }
+            }
+        }
+    }
+
+    /**
+     * InheritableThreadLocal propagates generic values.
+     */
+    public void testGenericITL() throws InterruptedException {
+        final int threadCount = 10;
+        final int[] x = new int[threadCount];
+        Thread progenitor = new ITLThread(x);
+        progenitor.start();
+        progenitor.join();
+        for (int i = 0; i < threadCount; i++) {
+            assertEquals(i, x[i]);
+        }
+    }
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java b/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java
new file mode 100644
index 0000000..2e84a6e
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorSubclassTest.java
@@ -0,0 +1,2062 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.RunnableFuture;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeoutException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadPoolExecutorSubclassTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ThreadPoolExecutorSubclassTest.class);
+    }
+
+    static class CustomTask<V> implements RunnableFuture<V> {
+        final Callable<V> callable;
+        final ReentrantLock lock = new ReentrantLock();
+        final Condition cond = lock.newCondition();
+        boolean done;
+        boolean cancelled;
+        V result;
+        Thread thread;
+        Exception exception;
+        CustomTask(Callable<V> c) {
+            if (c == null) throw new NullPointerException();
+            callable = c;
+        }
+        CustomTask(final Runnable r, final V res) {
+            if (r == null) throw new NullPointerException();
+            callable = new Callable<V>() {
+                public V call() throws Exception { r.run(); return res; }};
+        }
+        public boolean isDone() {
+            lock.lock(); try { return done; } finally { lock.unlock() ; }
+        }
+        public boolean isCancelled() {
+            lock.lock(); try { return cancelled; } finally { lock.unlock() ; }
+        }
+        public boolean cancel(boolean mayInterrupt) {
+            lock.lock();
+            try {
+                if (!done) {
+                    cancelled = true;
+                    done = true;
+                    if (mayInterrupt && thread != null)
+                        thread.interrupt();
+                    return true;
+                }
+                return false;
+            }
+            finally { lock.unlock() ; }
+        }
+        public void run() {
+            lock.lock();
+            try {
+                if (done)
+                    return;
+                thread = Thread.currentThread();
+            }
+            finally { lock.unlock() ; }
+            V v = null;
+            Exception e = null;
+            try {
+                v = callable.call();
+            }
+            catch (Exception ex) {
+                e = ex;
+            }
+            lock.lock();
+            try {
+                if (!done) {
+                    result = v;
+                    exception = e;
+                    done = true;
+                    thread = null;
+                    cond.signalAll();
+                }
+            }
+            finally { lock.unlock(); }
+        }
+        public V get() throws InterruptedException, ExecutionException {
+            lock.lock();
+            try {
+                while (!done)
+                    cond.await();
+                if (cancelled)
+                    throw new CancellationException();
+                if (exception != null)
+                    throw new ExecutionException(exception);
+                return result;
+            }
+            finally { lock.unlock(); }
+        }
+        public V get(long timeout, TimeUnit unit)
+            throws InterruptedException, ExecutionException, TimeoutException {
+            long nanos = unit.toNanos(timeout);
+            lock.lock();
+            try {
+                while (!done) {
+                    if (nanos <= 0L)
+                        throw new TimeoutException();
+                    nanos = cond.awaitNanos(nanos);
+                }
+                if (cancelled)
+                    throw new CancellationException();
+                if (exception != null)
+                    throw new ExecutionException(exception);
+                return result;
+            }
+            finally { lock.unlock(); }
+        }
+    }
+
+    static class CustomTPE extends ThreadPoolExecutor {
+        protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
+            return new CustomTask<V>(c);
+        }
+        protected <V> RunnableFuture<V> newTaskFor(Runnable r, V v) {
+            return new CustomTask<V>(r, v);
+        }
+
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue) {
+            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+                  workQueue);
+        }
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  ThreadFactory threadFactory) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+             threadFactory);
+        }
+
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  RejectedExecutionHandler handler) {
+        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
+              handler);
+        }
+        CustomTPE(int corePoolSize,
+                  int maximumPoolSize,
+                  long keepAliveTime,
+                  TimeUnit unit,
+                  BlockingQueue<Runnable> workQueue,
+                  ThreadFactory threadFactory,
+                  RejectedExecutionHandler handler) {
+            super(corePoolSize, maximumPoolSize, keepAliveTime, unit,
+              workQueue, threadFactory, handler);
+        }
+
+        final CountDownLatch beforeCalled = new CountDownLatch(1);
+        final CountDownLatch afterCalled = new CountDownLatch(1);
+        final CountDownLatch terminatedCalled = new CountDownLatch(1);
+
+        public CustomTPE() {
+            super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
+        }
+        protected void beforeExecute(Thread t, Runnable r) {
+            beforeCalled.countDown();
+        }
+        protected void afterExecute(Runnable r, Throwable t) {
+            afterCalled.countDown();
+        }
+        protected void terminated() {
+            terminatedCalled.countDown();
+        }
+
+        public boolean beforeCalled() {
+            return beforeCalled.getCount() == 0;
+        }
+        public boolean afterCalled() {
+            return afterCalled.getCount() == 0;
+        }
+        public boolean terminatedCalled() {
+            return terminatedCalled.getCount() == 0;
+        }
+    }
+
+    static class FailingThreadFactory implements ThreadFactory {
+        int calls = 0;
+        public Thread newThread(Runnable r) {
+            if (++calls > 1) return null;
+            return new Thread(r);
+        }
+    }
+
+    /**
+     * execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          2 * LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
+            p.execute(task);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * getActiveCount increases but doesn't overestimate, when a
+     * thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getActiveCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getActiveCount());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getActiveCount());
+        }
+    }
+
+    /**
+     * prestartCoreThread starts a thread if under corePoolSize, else doesn't
+     */
+    public void testPrestartCoreThread() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 6,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(1, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            assertTrue(p.prestartCoreThread());
+            assertEquals(3, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+        }
+    }
+
+    /**
+     * prestartAllCoreThreads starts all corePoolSize threads
+     */
+    public void testPrestartAllCoreThreads() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 6,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getCompletedTaskCount increases, but doesn't overestimate,
+     * when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(0, p.getCompletedTaskCount());
+                    threadProceed.await();
+                    threadDone.countDown();
+                }});
+            await(threadStarted);
+            assertEquals(0, p.getCompletedTaskCount());
+            threadProceed.countDown();
+            threadDone.await();
+            long startTime = System.nanoTime();
+            while (p.getCompletedTaskCount() != 1) {
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    fail("timed out");
+                Thread.yield();
+            }
+        }
+    }
+
+    /**
+     * getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
+    }
+
+    /**
+     * getKeepAliveTime returns value given in constructor if not otherwise set
+     */
+    public void testGetKeepAliveTime() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          1000, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getKeepAliveTime(SECONDS));
+        }
+    }
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() {
+        final ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          threadFactory,
+                          new NoOpREHandler());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ThreadFactory threadFactory = new SimpleThreadFactory();
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * getRejectedExecutionHandler returns handler in constructor if not set
+     */
+    public void testGetRejectedExecutionHandler() {
+        final RejectedExecutionHandler handler = new NoOpREHandler();
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          handler);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
+    }
+
+    /**
+     * setRejectedExecutionHandler sets the handler returned by
+     * getRejectedExecutionHandler
+     */
+    public void testSetRejectedExecutionHandler() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            RejectedExecutionHandler handler = new NoOpREHandler();
+            p.setRejectedExecutionHandler(handler);
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
+    }
+
+    /**
+     * setRejectedExecutionHandler(null) throws NPE
+     */
+    public void testSetRejectedExecutionHandlerNull() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setRejectedExecutionHandler(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * getLargestPoolSize increases, but doesn't overestimate, when
+     * multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        final int THREADS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(THREADS, THREADS,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getLargestPoolSize());
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+            for (int i = 0; i < THREADS; i++)
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadsStarted.countDown();
+                        await(done);
+                        assertEquals(THREADS, p.getLargestPoolSize());
+                    }});
+            await(threadsStarted);
+            assertEquals(THREADS, p.getLargestPoolSize());
+        }
+        assertEquals(THREADS, p.getLargestPoolSize());
+    }
+
+    /**
+     * getMaximumPoolSize returns value given in constructor if not
+     * otherwise set
+     */
+    public void testGetMaximumPoolSize() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(3, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(5);
+            assertEquals(5, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(4);
+            assertEquals(4, p.getMaximumPoolSize());
+        }
+    }
+
+    /**
+     * getPoolSize increases, but doesn't overestimate, when threads
+     * become active
+     */
+    public void testGetPoolSize() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getPoolSize());
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getTaskCount increases, but doesn't overestimate, when tasks submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+        }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
+    }
+
+    /**
+     * isShutdown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isShutdown());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
+        }
+    }
+
+    /**
+     * isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            FutureTask[] tasks = new FutureTask[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Callable<Boolean> task = new CheckedCallable<Boolean>() {
+                    public Boolean realCall() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertSame(q, p.getQueue());
+                        await(done);
+                        return Boolean.TRUE;
+                    }};
+                tasks[i] = new FutureTask(task);
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertSame(q, p.getQueue());
+            assertFalse(q.contains(tasks[0]));
+            assertTrue(q.contains(tasks[tasks.length - 1]));
+            assertEquals(tasks.length - 1, q.size());
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable[] tasks = new Runnable[6];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            for (int i = 0; i < tasks.length; i++) {
+                tasks[i] = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertFalse(p.remove(tasks[0]));
+            assertTrue(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p.remove(tasks[4]));
+            assertFalse(p.remove(tasks[4]));
+            assertFalse(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p.remove(tasks[3]));
+            assertFalse(q.contains(tasks[3]));
+        }
+    }
+
+    /**
+     * purge removes cancelled tasks from the queue
+     */
+    public void testPurge() throws InterruptedException {
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            FutureTask[] tasks = new FutureTask[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Callable<Boolean> task = new CheckedCallable<Boolean>() {
+                    public Boolean realCall() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                        return Boolean.TRUE;
+                    }};
+                tasks[i] = new FutureTask(task);
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertEquals(tasks.length, p.getTaskCount());
+            assertEquals(tasks.length - 1, q.size());
+            assertEquals(1L, p.getActiveCount());
+            assertEquals(0L, p.getCompletedTaskCount());
+            tasks[4].cancel(true);
+            tasks[3].cancel(false);
+            p.purge();
+            assertEquals(tasks.length - 3, q.size());
+            assertEquals(tasks.length - 2, p.getTaskCount());
+            p.purge();         // Nothing to do
+            assertEquals(tasks.length - 3, q.size());
+            assertEquals(tasks.length - 2, p.getTaskCount());
+        }
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final ThreadPoolExecutor p =
+            new CustomTPE(poolSize, poolSize,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
+    }
+
+    // Exception Tests
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor1() {
+        try {
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor2() {
+        try {
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor3() {
+        try {
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor4() {
+        try {
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor5() {
+        try {
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS, null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor6() {
+        try {
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor7() {
+        try {
+            new CustomTPE(1,-1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor8() {
+        try {
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor9() {
+        try {
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor10() {
+        try {
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException2() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS, null, new SimpleThreadFactory());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if threadFactory is set to null
+     */
+    public void testConstructorNullPointerException3() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          (ThreadFactory) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor11() {
+        try {
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor12() {
+        try {
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor13() {
+        try {
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor14() {
+        try {
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor15() {
+        try {
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException4() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          null,
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is set to null
+     */
+    public void testConstructorNullPointerException5() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          (RejectedExecutionHandler) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor16() {
+        try {
+            new CustomTPE(-1, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor17() {
+        try {
+            new CustomTPE(1, -1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor18() {
+        try {
+            new CustomTPE(1, 0, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor19() {
+        try {
+            new CustomTPE(1, 2, -1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor20() {
+        try {
+            new CustomTPE(2, 1, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is null
+     */
+    public void testConstructorNullPointerException6() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          null,
+                          new SimpleThreadFactory(),
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is null
+     */
+    public void testConstructorNullPointerException7() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          new SimpleThreadFactory(),
+                          (RejectedExecutionHandler) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if ThreadFactory is null
+     */
+    public void testConstructorNullPointerException8() {
+        try {
+            new CustomTPE(1, 2, 1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10),
+                          (ThreadFactory) null,
+                          new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * execute throws RejectedExecutionException if saturated.
+     */
+    public void testSaturatedExecute() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            for (int i = 0; i < 2; ++i)
+                p.execute(task);
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.execute(task);
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
+                assertTrue(p.getTaskCount() <= 2);
+            }
+        }
+    }
+
+    /**
+     * executor using CallerRunsPolicy runs task if saturated.
+     */
+    public void testSaturatedExecute2() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.CallerRunsPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable blocker = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            p.execute(blocker);
+            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = new TrackedNoOpRunnable();
+            for (int i = 0; i < tasks.length; i++)
+                p.execute(tasks[i]);
+            for (int i = 1; i < tasks.length; i++)
+                assertTrue(tasks[i].done);
+            assertFalse(tasks[0].done); // waiting in queue
+        }
+    }
+
+    /**
+     * executor using DiscardPolicy drops task if saturated.
+     */
+    public void testSaturatedExecute3() {
+        final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+        for (int i = 0; i < tasks.length; ++i)
+            tasks[i] = new TrackedNoOpRunnable();
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            p.execute(awaiter(done));
+
+            for (TrackedNoOpRunnable task : tasks)
+                p.execute(task);
+            for (int i = 1; i < tasks.length; i++)
+                assertFalse(tasks[i].done);
+        }
+        for (int i = 1; i < tasks.length; i++)
+            assertFalse(tasks[i].done);
+        assertTrue(tasks[0].done); // was waiting in queue
+    }
+
+    /**
+     * executor using DiscardOldestPolicy drops oldest task if saturated.
+     */
+    public void testSaturatedExecute4() {
+        final CountDownLatch done = new CountDownLatch(1);
+        LatchAwaiter r1 = awaiter(done);
+        LatchAwaiter r2 = awaiter(done);
+        LatchAwaiter r3 = awaiter(done);
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardOldestPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(LatchAwaiter.NEW, r1.state);
+            assertEquals(LatchAwaiter.NEW, r2.state);
+            assertEquals(LatchAwaiter.NEW, r3.state);
+            p.execute(r1);
+            p.execute(r2);
+            assertTrue(p.getQueue().contains(r2));
+            p.execute(r3);
+            assertFalse(p.getQueue().contains(r2));
+            assertTrue(p.getQueue().contains(r3));
+        }
+        assertEquals(LatchAwaiter.DONE, r1.state);
+        assertEquals(LatchAwaiter.NEW, r2.state);
+        assertEquals(LatchAwaiter.DONE, r3.state);
+    }
+
+    /**
+     * execute throws RejectedExecutionException if shutdown
+     */
+    public void testRejectedExecutionExceptionOnShutdown() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(new NoOpRunnable());
+                shouldThrow();
+            } catch (RejectedExecutionException success) {}
+        }
+    }
+
+    /**
+     * execute using CallerRunsPolicy drops task on shutdown
+     */
+    public void testCallerRunsOnShutdown() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.CallerRunsPolicy());
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute using DiscardPolicy drops task on shutdown
+     */
+    public void testDiscardOnShutdown() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardPolicy());
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute using DiscardOldestPolicy drops task on shutdown
+     */
+    public void testDiscardOldestOnShutdown() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new CustomTPE.DiscardOldestPolicy());
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute(null) throws NPE
+     */
+    public void testExecuteNull() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          1L, SECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * setCorePoolSize of negative value throws IllegalArgumentException
+     */
+    public void testCorePoolSizeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(1, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setCorePoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * setMaximumPoolSize(int) throws IllegalArgumentException
+     * if given a value less the core pool size
+     */
+    public void testMaximumPoolSizeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * setMaximumPoolSize throws IllegalArgumentException
+     * if given a negative value
+     */
+    public void testMaximumPoolSizeIllegalArgumentException2() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS,
+                          MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * setKeepAliveTime throws IllegalArgumentException
+     * when given a negative value
+     */
+    public void testKeepAliveTimeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 3,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setKeepAliveTime(-1, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * terminated() is called on termination
+     */
+    public void testTerminated() {
+        CustomTPE p = new CustomTPE();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.terminatedCalled());
+            assertTrue(p.isShutdown());
+        }
+    }
+
+    /**
+     * beforeExecute and afterExecute are called when executing task
+     */
+    public void testBeforeAfter() throws InterruptedException {
+        CustomTPE p = new CustomTPE();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            p.execute(new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                }});
+            await(p.afterCalled);
+            assertEquals(0, done.getCount());
+            assertTrue(p.afterCalled());
+            assertTrue(p.beforeCalled());
+        }
+    }
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        final ExecutorService e =
+            new CustomTPE(2, 2,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p =
+                new CustomTPE(2, 2,
+                              LONG_DELAY_MS, MILLISECONDS,
+                              new ArrayBlockingQueue<Runnable>(10));
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
+        }
+    }
+
+    /**
+     * Execution continues if there is at least one thread even if
+     * thread factory fails to create more
+     */
+    public void testFailingThreadFactory() throws InterruptedException {
+        final ExecutorService e =
+            new CustomTPE(100, 100,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new LinkedBlockingQueue<Runnable>(),
+                          new FailingThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            final int TASKS = 100;
+            final CountDownLatch done = new CountDownLatch(TASKS);
+            for (int k = 0; k < TASKS; ++k)
+                e.execute(new CheckedRunnable() {
+                    public void realRun() {
+                        done.countDown();
+                    }});
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * allowsCoreThreadTimeOut is by default false.
+     */
+    public void testAllowsCoreThreadTimeOut() {
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 2,
+                          1000, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.allowsCoreThreadTimeOut());
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(true) causes idle threads to time out
+     */
+    public void testAllowCoreThreadTimeOut_true() throws Exception {
+        long keepAliveTime = timeoutMillis();
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 10,
+                          keepAliveTime, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.allowCoreThreadTimeOut(true);
+            p.execute(new CheckedRunnable() {
+                public void realRun() {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                }});
+            await(threadStarted);
+            delay(keepAliveTime);
+            long startTime = System.nanoTime();
+            while (p.getPoolSize() > 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            assertEquals(0, p.getPoolSize());
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(false) causes idle threads not to time out
+     */
+    public void testAllowCoreThreadTimeOut_false() throws Exception {
+        long keepAliveTime = timeoutMillis();
+        final ThreadPoolExecutor p =
+            new CustomTPE(2, 10,
+                          keepAliveTime, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.allowCoreThreadTimeOut(false);
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertTrue(p.getPoolSize() >= 1);
+                }});
+            delay(2 * keepAliveTime);
+            assertTrue(p.getPoolSize() >= 1);
+        }
+    }
+
+    /**
+     * get(cancelled task) throws CancellationException
+     * (in part, a test of CustomTPE itself)
+     */
+    public void testGet_cancelled() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ExecutorService e =
+            new CustomTPE(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new LinkedBlockingQueue<Runnable>());
+        try (PoolCleaner cleaner = cleaner(e, done)) {
+            final CountDownLatch blockerStarted = new CountDownLatch(1);
+            final List<Future<?>> futures = new ArrayList<>();
+            for (int i = 0; i < 2; i++) {
+                Runnable r = new CheckedRunnable() { public void realRun()
+                                                         throws Throwable {
+                    blockerStarted.countDown();
+                    assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
+                }};
+                futures.add(e.submit(r));
+            }
+            await(blockerStarted);
+            for (Future<?> future : futures) future.cancel(false);
+            for (Future<?> future : futures) {
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                try {
+                    future.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                assertTrue(future.isCancelled());
+                assertTrue(future.isDone());
+            }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorTest.java b/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorTest.java
new file mode 100644
index 0000000..90f9eb3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadPoolExecutorTest.java
@@ -0,0 +1,2093 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RejectedExecutionHandler;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadPoolExecutorTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(ThreadPoolExecutorTest.class);
+    }
+
+    static class ExtendedTPE extends ThreadPoolExecutor {
+        final CountDownLatch beforeCalled = new CountDownLatch(1);
+        final CountDownLatch afterCalled = new CountDownLatch(1);
+        final CountDownLatch terminatedCalled = new CountDownLatch(1);
+
+        public ExtendedTPE() {
+            super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
+        }
+        protected void beforeExecute(Thread t, Runnable r) {
+            beforeCalled.countDown();
+        }
+        protected void afterExecute(Runnable r, Throwable t) {
+            afterCalled.countDown();
+        }
+        protected void terminated() {
+            terminatedCalled.countDown();
+        }
+
+        public boolean beforeCalled() {
+            return beforeCalled.getCount() == 0;
+        }
+        public boolean afterCalled() {
+            return afterCalled.getCount() == 0;
+        }
+        public boolean terminatedCalled() {
+            return terminatedCalled.getCount() == 0;
+        }
+    }
+
+    static class FailingThreadFactory implements ThreadFactory {
+        int calls = 0;
+        public Thread newThread(Runnable r) {
+            if (++calls > 1) return null;
+            return new Thread(r);
+        }
+    }
+
+    /**
+     * execute successfully executes a runnable
+     */
+    public void testExecute() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Runnable task = new CheckedRunnable() {
+                public void realRun() { done.countDown(); }};
+            p.execute(task);
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * getActiveCount increases but doesn't overestimate, when a
+     * thread becomes active
+     */
+    public void testGetActiveCount() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getActiveCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getActiveCount());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getActiveCount());
+        }
+    }
+
+    /**
+     * prestartCoreThread starts a thread if under corePoolSize, else doesn't
+     */
+    public void testPrestartCoreThread() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 6,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(1, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            assertTrue(p.prestartCoreThread());
+            assertEquals(3, p.getPoolSize());
+            assertTrue(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+            assertFalse(p.prestartCoreThread());
+            assertEquals(4, p.getPoolSize());
+        }
+    }
+
+    /**
+     * prestartAllCoreThreads starts all corePoolSize threads
+     */
+    public void testPrestartAllCoreThreads() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 6,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(0, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(2, p.getPoolSize());
+            p.setCorePoolSize(4);
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+            p.prestartAllCoreThreads();
+            assertEquals(4, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getCompletedTaskCount increases, but doesn't overestimate,
+     * when tasks complete
+     */
+    public void testGetCompletedTaskCount() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch threadProceed = new CountDownLatch(1);
+            final CountDownLatch threadDone = new CountDownLatch(1);
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(0, p.getCompletedTaskCount());
+                    threadProceed.await();
+                    threadDone.countDown();
+                }});
+            await(threadStarted);
+            assertEquals(0, p.getCompletedTaskCount());
+            threadProceed.countDown();
+            threadDone.await();
+            long startTime = System.nanoTime();
+            while (p.getCompletedTaskCount() != 1) {
+                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+                    fail("timed out");
+                Thread.yield();
+            }
+        }
+    }
+
+    /**
+     * getCorePoolSize returns size given in constructor if not otherwise set
+     */
+    public void testGetCorePoolSize() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getCorePoolSize());
+        }
+    }
+
+    /**
+     * getKeepAliveTime returns value given in constructor if not otherwise set
+     */
+    public void testGetKeepAliveTime() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 2,
+                                   1000, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(1, p.getKeepAliveTime(SECONDS));
+        }
+    }
+
+    /**
+     * getThreadFactory returns factory in constructor if not set
+     */
+    public void testGetThreadFactory() {
+        ThreadFactory threadFactory = new SimpleThreadFactory();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   threadFactory,
+                                   new NoOpREHandler());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory sets the thread factory returned by getThreadFactory
+     */
+    public void testSetThreadFactory() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            ThreadFactory threadFactory = new SimpleThreadFactory();
+            p.setThreadFactory(threadFactory);
+            assertSame(threadFactory, p.getThreadFactory());
+        }
+    }
+
+    /**
+     * setThreadFactory(null) throws NPE
+     */
+    public void testSetThreadFactoryNull() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setThreadFactory(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * getRejectedExecutionHandler returns handler in constructor if not set
+     */
+    public void testGetRejectedExecutionHandler() {
+        final RejectedExecutionHandler handler = new NoOpREHandler();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   handler);
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
+    }
+
+    /**
+     * setRejectedExecutionHandler sets the handler returned by
+     * getRejectedExecutionHandler
+     */
+    public void testSetRejectedExecutionHandler() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            RejectedExecutionHandler handler = new NoOpREHandler();
+            p.setRejectedExecutionHandler(handler);
+            assertSame(handler, p.getRejectedExecutionHandler());
+        }
+    }
+
+    /**
+     * setRejectedExecutionHandler(null) throws NPE
+     */
+    public void testSetRejectedExecutionHandlerNull() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setRejectedExecutionHandler(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * getLargestPoolSize increases, but doesn't overestimate, when
+     * multiple threads active
+     */
+    public void testGetLargestPoolSize() throws InterruptedException {
+        final int THREADS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(THREADS, THREADS,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getLargestPoolSize());
+            final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
+            for (int i = 0; i < THREADS; i++)
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadsStarted.countDown();
+                        await(done);
+                        assertEquals(THREADS, p.getLargestPoolSize());
+                    }});
+            await(threadsStarted);
+            assertEquals(THREADS, p.getLargestPoolSize());
+        }
+        assertEquals(THREADS, p.getLargestPoolSize());
+    }
+
+    /**
+     * getMaximumPoolSize returns value given in constructor if not
+     * otherwise set
+     */
+    public void testGetMaximumPoolSize() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertEquals(3, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(5);
+            assertEquals(5, p.getMaximumPoolSize());
+            p.setMaximumPoolSize(4);
+            assertEquals(4, p.getMaximumPoolSize());
+        }
+    }
+
+    /**
+     * getPoolSize increases, but doesn't overestimate, when threads
+     * become active
+     */
+    public void testGetPoolSize() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(0, p.getPoolSize());
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getPoolSize());
+        }
+    }
+
+    /**
+     * getTaskCount increases, but doesn't overestimate, when tasks submitted
+     */
+    public void testGetTaskCount() throws InterruptedException {
+        final int TASKS = 3;
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            assertEquals(0, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertEquals(1, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+            for (int i = 0; i < TASKS; i++) {
+                assertEquals(1 + i, p.getTaskCount());
+                p.execute(new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertEquals(1 + TASKS, p.getTaskCount());
+                        await(done);
+                    }});
+            }
+            assertEquals(1 + TASKS, p.getTaskCount());
+            assertEquals(0, p.getCompletedTaskCount());
+        }
+        assertEquals(1 + TASKS, p.getTaskCount());
+        assertEquals(1 + TASKS, p.getCompletedTaskCount());
+    }
+
+    /**
+     * isShutdown is false before shutdown, true after
+     */
+    public void testIsShutdown() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isShutdown());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.isShutdown());
+        }
+    }
+
+    /**
+     * awaitTermination on a non-shutdown pool times out
+     */
+    public void testAwaitTermination_timesOut() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.isTerminated());
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
+            assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
+            assertFalse(p.awaitTermination(-1L, NANOSECONDS));
+            assertFalse(p.awaitTermination(-1L, MILLISECONDS));
+            assertFalse(p.awaitTermination(0L, NANOSECONDS));
+            assertFalse(p.awaitTermination(0L, MILLISECONDS));
+            long timeoutNanos = 999999L;
+            long startTime = System.nanoTime();
+            assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
+            assertTrue(System.nanoTime() - startTime >= timeoutNanos);
+            assertFalse(p.isTerminated());
+            startTime = System.nanoTime();
+            long timeoutMillis = timeoutMillis();
+            assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
+            assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
+            assertFalse(p.isTerminated());
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+        }
+    }
+
+    /**
+     * isTerminated is false before termination, true after
+     */
+    public void testIsTerminated() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * isTerminating is not true when running or when terminated
+     */
+    public void testIsTerminating() throws InterruptedException {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            final CountDownLatch done = new CountDownLatch(1);
+            assertFalse(p.isTerminating());
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    assertFalse(p.isTerminating());
+                    threadStarted.countDown();
+                    await(done);
+                }});
+            await(threadStarted);
+            assertFalse(p.isTerminating());
+            done.countDown();
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+            assertTrue(p.isTerminated());
+            assertFalse(p.isTerminating());
+        }
+    }
+
+    /**
+     * getQueue returns the work queue, which contains queued tasks
+     */
+    public void testGetQueue() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            FutureTask[] tasks = new FutureTask[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Callable task = new CheckedCallable<Boolean>() {
+                    public Boolean realCall() throws InterruptedException {
+                        threadStarted.countDown();
+                        assertSame(q, p.getQueue());
+                        await(done);
+                        return Boolean.TRUE;
+                    }};
+                tasks[i] = new FutureTask(task);
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertSame(q, p.getQueue());
+            assertFalse(q.contains(tasks[0]));
+            assertTrue(q.contains(tasks[tasks.length - 1]));
+            assertEquals(tasks.length - 1, q.size());
+        }
+    }
+
+    /**
+     * remove(task) removes queued task, and fails to remove active task
+     */
+    public void testRemove() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable[] tasks = new Runnable[6];
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            for (int i = 0; i < tasks.length; i++) {
+                tasks[i] = new CheckedRunnable() {
+                    public void realRun() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                    }};
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertFalse(p.remove(tasks[0]));
+            assertTrue(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p.remove(tasks[4]));
+            assertFalse(p.remove(tasks[4]));
+            assertFalse(q.contains(tasks[4]));
+            assertTrue(q.contains(tasks[3]));
+            assertTrue(p.remove(tasks[3]));
+            assertFalse(q.contains(tasks[3]));
+        }
+    }
+
+    /**
+     * purge removes cancelled tasks from the queue
+     */
+    public void testPurge() throws InterruptedException {
+        final CountDownLatch threadStarted = new CountDownLatch(1);
+        final CountDownLatch done = new CountDownLatch(1);
+        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   q);
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            FutureTask[] tasks = new FutureTask[5];
+            for (int i = 0; i < tasks.length; i++) {
+                Callable task = new CheckedCallable<Boolean>() {
+                    public Boolean realCall() throws InterruptedException {
+                        threadStarted.countDown();
+                        await(done);
+                        return Boolean.TRUE;
+                    }};
+                tasks[i] = new FutureTask(task);
+                p.execute(tasks[i]);
+            }
+            await(threadStarted);
+            assertEquals(tasks.length, p.getTaskCount());
+            assertEquals(tasks.length - 1, q.size());
+            assertEquals(1L, p.getActiveCount());
+            assertEquals(0L, p.getCompletedTaskCount());
+            tasks[4].cancel(true);
+            tasks[3].cancel(false);
+            p.purge();
+            assertEquals(tasks.length - 3, q.size());
+            assertEquals(tasks.length - 2, p.getTaskCount());
+            p.purge();         // Nothing to do
+            assertEquals(tasks.length - 3, q.size());
+            assertEquals(tasks.length - 2, p.getTaskCount());
+        }
+    }
+
+    /**
+     * shutdownNow returns a list containing tasks that were not run,
+     * and those tasks are drained from the queue
+     */
+    public void testShutdownNow() throws InterruptedException {
+        final int poolSize = 2;
+        final int count = 5;
+        final AtomicInteger ran = new AtomicInteger(0);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(poolSize, poolSize,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
+        Runnable waiter = new CheckedRunnable() { public void realRun() {
+            threadsStarted.countDown();
+            try {
+                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
+            } catch (InterruptedException success) {}
+            ran.getAndIncrement();
+        }};
+        for (int i = 0; i < count; i++)
+            p.execute(waiter);
+        await(threadsStarted);
+        assertEquals(poolSize, p.getActiveCount());
+        assertEquals(0, p.getCompletedTaskCount());
+        final List<Runnable> queuedTasks;
+        try {
+            queuedTasks = p.shutdownNow();
+        } catch (SecurityException ok) {
+            return; // Allowed in case test doesn't have privs
+        }
+        assertTrue(p.isShutdown());
+        assertTrue(p.getQueue().isEmpty());
+        assertEquals(count - poolSize, queuedTasks.size());
+        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
+        assertTrue(p.isTerminated());
+        assertEquals(poolSize, ran.get());
+        assertEquals(poolSize, p.getCompletedTaskCount());
+    }
+
+    // Exception Tests
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor1() {
+        try {
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor2() {
+        try {
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor3() {
+        try {
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor4() {
+        try {
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor5() {
+        try {
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   (BlockingQueue) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor6() {
+        try {
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor7() {
+        try {
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor8() {
+        try {
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor9() {
+        try {
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor10() {
+        try {
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException2() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   (BlockingQueue) null,
+                                   new SimpleThreadFactory());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if threadFactory is set to null
+     */
+    public void testConstructorNullPointerException3() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   (ThreadFactory) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor11() {
+        try {
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor12() {
+        try {
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor13() {
+        try {
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor14() {
+        try {
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor15() {
+        try {
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is set to null
+     */
+    public void testConstructorNullPointerException4() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   (BlockingQueue) null,
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is set to null
+     */
+    public void testConstructorNullPointerException5() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   (RejectedExecutionHandler) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize argument is less than zero
+     */
+    public void testConstructor16() {
+        try {
+            new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is less than zero
+     */
+    public void testConstructor17() {
+        try {
+            new ThreadPoolExecutor(1, -1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if maximumPoolSize is equal to zero
+     */
+    public void testConstructor18() {
+        try {
+            new ThreadPoolExecutor(1, 0, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if keepAliveTime is less than zero
+     */
+    public void testConstructor19() {
+        try {
+            new ThreadPoolExecutor(1, 2, -1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if corePoolSize is greater than the maximumPoolSize
+     */
+    public void testConstructor20() {
+        try {
+            new ThreadPoolExecutor(2, 1, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (IllegalArgumentException success) {}
+    }
+
+    /**
+     * Constructor throws if workQueue is null
+     */
+    public void testConstructorNullPointerException6() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   (BlockingQueue) null,
+                                   new SimpleThreadFactory(),
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if handler is null
+     */
+    public void testConstructorNullPointerException7() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   new SimpleThreadFactory(),
+                                   (RejectedExecutionHandler) null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Constructor throws if ThreadFactory is null
+     */
+    public void testConstructorNullPointerException8() {
+        try {
+            new ThreadPoolExecutor(1, 2, 1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10),
+                                   (ThreadFactory) null,
+                                   new NoOpREHandler());
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * get of submitted callable throws InterruptedException if interrupted
+     */
+    public void testInterruptedSubmit() throws InterruptedException {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   60, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            Thread t = newStartedThread(new CheckedInterruptedRunnable() {
+                public void realRun() throws Exception {
+                    Callable task = new CheckedCallable<Boolean>() {
+                        public Boolean realCall() throws InterruptedException {
+                            threadStarted.countDown();
+                            await(done);
+                            return Boolean.TRUE;
+                        }};
+                    p.submit(task).get();
+                }});
+
+            await(threadStarted);
+            t.interrupt();
+            awaitTermination(t);
+        }
+    }
+
+    /**
+     * execute throws RejectedExecutionException if saturated.
+     */
+    public void testSaturatedExecute() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            for (int i = 0; i < 2; ++i)
+                p.execute(task);
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.execute(task);
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
+                assertTrue(p.getTaskCount() <= 2);
+            }
+        }
+    }
+
+    /**
+     * submit(runnable) throws RejectedExecutionException if saturated.
+     */
+    public void testSaturatedSubmitRunnable() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            for (int i = 0; i < 2; ++i)
+                p.submit(task);
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.execute(task);
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
+                assertTrue(p.getTaskCount() <= 2);
+            }
+        }
+    }
+
+    /**
+     * submit(callable) throws RejectedExecutionException if saturated.
+     */
+    public void testSaturatedSubmitCallable() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            Runnable task = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            for (int i = 0; i < 2; ++i)
+                p.submit(Executors.callable(task));
+            for (int i = 0; i < 2; ++i) {
+                try {
+                    p.execute(task);
+                    shouldThrow();
+                } catch (RejectedExecutionException success) {}
+                assertTrue(p.getTaskCount() <= 2);
+            }
+        }
+    }
+
+    /**
+     * executor using CallerRunsPolicy runs task if saturated.
+     */
+    public void testSaturatedExecute2() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS,
+                                   MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1),
+                                   new ThreadPoolExecutor.CallerRunsPolicy());
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            Runnable blocker = new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    await(done);
+                }};
+            p.execute(blocker);
+            TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+            for (int i = 0; i < tasks.length; i++)
+                tasks[i] = new TrackedNoOpRunnable();
+            for (int i = 0; i < tasks.length; i++)
+                p.execute(tasks[i]);
+            for (int i = 1; i < tasks.length; i++)
+                assertTrue(tasks[i].done);
+            assertFalse(tasks[0].done); // waiting in queue
+            done.countDown();
+        }
+    }
+
+    /**
+     * executor using DiscardPolicy drops task if saturated.
+     */
+    public void testSaturatedExecute3() {
+        final CountDownLatch done = new CountDownLatch(1);
+        final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
+        for (int i = 0; i < tasks.length; ++i)
+            tasks[i] = new TrackedNoOpRunnable();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                          LONG_DELAY_MS, MILLISECONDS,
+                          new ArrayBlockingQueue<Runnable>(1),
+                          new ThreadPoolExecutor.DiscardPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            p.execute(awaiter(done));
+
+            for (TrackedNoOpRunnable task : tasks)
+                p.execute(task);
+            for (int i = 1; i < tasks.length; i++)
+                assertFalse(tasks[i].done);
+        }
+        for (int i = 1; i < tasks.length; i++)
+            assertFalse(tasks[i].done);
+        assertTrue(tasks[0].done); // was waiting in queue
+    }
+
+    /**
+     * executor using DiscardOldestPolicy drops oldest task if saturated.
+     */
+    public void testSaturatedExecute4() {
+        final CountDownLatch done = new CountDownLatch(1);
+        LatchAwaiter r1 = awaiter(done);
+        LatchAwaiter r2 = awaiter(done);
+        LatchAwaiter r3 = awaiter(done);
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1),
+                                   new ThreadPoolExecutor.DiscardOldestPolicy());
+        try (PoolCleaner cleaner = cleaner(p, done)) {
+            assertEquals(LatchAwaiter.NEW, r1.state);
+            assertEquals(LatchAwaiter.NEW, r2.state);
+            assertEquals(LatchAwaiter.NEW, r3.state);
+            p.execute(r1);
+            p.execute(r2);
+            assertTrue(p.getQueue().contains(r2));
+            p.execute(r3);
+            assertFalse(p.getQueue().contains(r2));
+            assertTrue(p.getQueue().contains(r3));
+        }
+        assertEquals(LatchAwaiter.DONE, r1.state);
+        assertEquals(LatchAwaiter.NEW, r2.state);
+        assertEquals(LatchAwaiter.DONE, r3.state);
+    }
+
+    /**
+     * execute throws RejectedExecutionException if shutdown
+     */
+    public void testRejectedExecutionExceptionOnShutdown() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1));
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(new NoOpRunnable());
+                shouldThrow();
+            } catch (RejectedExecutionException success) {}
+        }
+    }
+
+    /**
+     * execute using CallerRunsPolicy drops task on shutdown
+     */
+    public void testCallerRunsOnShutdown() {
+        RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1), h);
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute using DiscardPolicy drops task on shutdown
+     */
+    public void testDiscardOnShutdown() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1),
+                                   new ThreadPoolExecutor.DiscardPolicy());
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute using DiscardOldestPolicy drops task on shutdown
+     */
+    public void testDiscardOldestOnShutdown() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(1),
+                                   new ThreadPoolExecutor.DiscardOldestPolicy());
+
+        try { p.shutdown(); } catch (SecurityException ok) { return; }
+        try (PoolCleaner cleaner = cleaner(p)) {
+            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
+            p.execute(r);
+            assertFalse(r.done);
+        }
+    }
+
+    /**
+     * execute(null) throws NPE
+     */
+    public void testExecuteNull() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   1L, SECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.execute(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * setCorePoolSize of negative value throws IllegalArgumentException
+     */
+    public void testCorePoolSizeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setCorePoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * setMaximumPoolSize(int) throws IllegalArgumentException if
+     * given a value less the core pool size
+     */
+    public void testMaximumPoolSizeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * setMaximumPoolSize throws IllegalArgumentException
+     * if given a negative value
+     */
+    public void testMaximumPoolSizeIllegalArgumentException2() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setMaximumPoolSize(-1);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * Configuration changes that allow core pool size greater than
+     * max pool size result in IllegalArgumentException.
+     */
+    public void testPoolSizeInvariants() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int s = 1; s < 5; s++) {
+                p.setMaximumPoolSize(s);
+                p.setCorePoolSize(s);
+                try {
+                    p.setMaximumPoolSize(s - 1);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+                assertEquals(s, p.getCorePoolSize());
+                assertEquals(s, p.getMaximumPoolSize());
+                try {
+                    p.setCorePoolSize(s + 1);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+                assertEquals(s, p.getCorePoolSize());
+                assertEquals(s, p.getMaximumPoolSize());
+            }
+        }
+    }
+
+    /**
+     * setKeepAliveTime throws IllegalArgumentException
+     * when given a negative value
+     */
+    public void testKeepAliveTimeIllegalArgumentException() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 3,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try {
+                p.setKeepAliveTime(-1, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * terminated() is called on termination
+     */
+    public void testTerminated() {
+        ExtendedTPE p = new ExtendedTPE();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            try { p.shutdown(); } catch (SecurityException ok) { return; }
+            assertTrue(p.terminatedCalled());
+            assertTrue(p.isShutdown());
+        }
+    }
+
+    /**
+     * beforeExecute and afterExecute are called when executing task
+     */
+    public void testBeforeAfter() throws InterruptedException {
+        ExtendedTPE p = new ExtendedTPE();
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch done = new CountDownLatch(1);
+            p.execute(new CheckedRunnable() {
+                public void realRun() {
+                    done.countDown();
+                }});
+            await(p.afterCalled);
+            assertEquals(0, done.getCount());
+            assertTrue(p.afterCalled());
+            assertTrue(p.beforeCalled());
+        }
+    }
+
+    /**
+     * completed submit of callable returns result
+     */
+    public void testSubmitCallable() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new StringTask());
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * completed submit of runnable returns successfully
+     */
+    public void testSubmitRunnable() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<?> future = e.submit(new NoOpRunnable());
+            future.get();
+            assertTrue(future.isDone());
+        }
+    }
+
+    /**
+     * completed submit of (runnable, result) returns result
+     */
+    public void testSubmitRunnable2() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
+            String result = future.get();
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAny(null) throws NPE
+     */
+    public void testInvokeAny1() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(empty collection) throws IAE
+     */
+    public void testInvokeAny2() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>());
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * invokeAny(c) throws NPE if c has null elements
+     */
+    public void testInvokeAny3() throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testInvokeAny4() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAny(c) returns result of some task
+     */
+    public void testInvokeAny5() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l);
+            assertSame(TEST_STRING, result);
+        }
+    }
+
+    /**
+     * invokeAll(null) throws NPE
+     */
+    public void testInvokeAll1() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * invokeAll(empty collection) returns empty collection
+     */
+    public void testInvokeAll2() throws InterruptedException {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * invokeAll(c) throws NPE if c has null elements
+     */
+    public void testInvokeAll3() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testInvokeAll4() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * invokeAll(c) returns results of all completed tasks
+     */
+    public void testInvokeAll5() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures = e.invokeAll(l);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAny(null) throws NPE
+     */
+    public void testTimedInvokeAny1() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(,,null) throws NPE
+     */
+    public void testTimedInvokeAnyNullTimeUnit() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(empty collection) throws IAE
+     */
+    public void testTimedInvokeAny2() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAny(new ArrayList<Callable<String>>(),
+                            MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (IllegalArgumentException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAny3() throws Exception {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(latchAwaitingStringTask(latch));
+            l.add(null);
+            try {
+                e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+            latch.countDown();
+        }
+    }
+
+    /**
+     * timed invokeAny(c) throws ExecutionException if no task completes
+     */
+    public void testTimedInvokeAny4() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            try {
+                e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAny(c) returns result of some task
+     */
+    public void testTimedInvokeAny5() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            long startTime = System.nanoTime();
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
+            assertSame(TEST_STRING, result);
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+        }
+    }
+
+    /**
+     * timed invokeAll(null) throws NPE
+     */
+    public void testTimedInvokeAll1() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            try {
+                e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(,,null) throws NPE
+     */
+    public void testTimedInvokeAllNullTimeUnit() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, null);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * timed invokeAll(empty collection) returns empty collection
+     */
+    public void testTimedInvokeAll2() throws InterruptedException {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(),
+                                                 MEDIUM_DELAY_MS, MILLISECONDS);
+            assertTrue(r.isEmpty());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) throws NPE if c has null elements
+     */
+    public void testTimedInvokeAll3() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(null);
+            try {
+                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
+                shouldThrow();
+            } catch (NullPointerException success) {}
+        }
+    }
+
+    /**
+     * get of element of invokeAll(c) throws exception on failed task
+     */
+    public void testTimedInvokeAll4() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new NPETask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(1, futures.size());
+            try {
+                futures.get(0).get();
+                shouldThrow();
+            } catch (ExecutionException success) {
+                assertTrue(success.getCause() instanceof NullPointerException);
+            }
+        }
+    }
+
+    /**
+     * timed invokeAll(c) returns results of all completed tasks
+     */
+    public void testTimedInvokeAll5() throws Exception {
+        final ExecutorService e =
+            new ThreadPoolExecutor(2, 2,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(e)) {
+            List<Callable<String>> l = new ArrayList<>();
+            l.add(new StringTask());
+            l.add(new StringTask());
+            List<Future<String>> futures =
+                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
+            assertEquals(2, futures.size());
+            for (Future<String> future : futures)
+                assertSame(TEST_STRING, future.get());
+        }
+    }
+
+    /**
+     * timed invokeAll(c) cancels tasks not completed by timeout
+     */
+    public void testTimedInvokeAll6() throws Exception {
+        for (long timeout = timeoutMillis();;) {
+            final CountDownLatch done = new CountDownLatch(1);
+            final Callable<String> waiter = new CheckedCallable<String>() {
+                public String realCall() {
+                    try { done.await(LONG_DELAY_MS, MILLISECONDS); }
+                    catch (InterruptedException ok) {}
+                    return "1"; }};
+            final ExecutorService p =
+                new ThreadPoolExecutor(2, 2,
+                                       LONG_DELAY_MS, MILLISECONDS,
+                                       new ArrayBlockingQueue<Runnable>(10));
+            try (PoolCleaner cleaner = cleaner(p, done)) {
+                List<Callable<String>> tasks = new ArrayList<>();
+                tasks.add(new StringTask("0"));
+                tasks.add(waiter);
+                tasks.add(new StringTask("2"));
+                long startTime = System.nanoTime();
+                List<Future<String>> futures =
+                    p.invokeAll(tasks, timeout, MILLISECONDS);
+                assertEquals(tasks.size(), futures.size());
+                assertTrue(millisElapsedSince(startTime) >= timeout);
+                for (Future future : futures)
+                    assertTrue(future.isDone());
+                assertTrue(futures.get(1).isCancelled());
+                try {
+                    assertEquals("0", futures.get(0).get());
+                    assertEquals("2", futures.get(2).get());
+                    break;
+                } catch (CancellationException retryWithLongerTimeout) {
+                    timeout *= 2;
+                    if (timeout >= LONG_DELAY_MS / 2)
+                        fail("expected exactly one task to be cancelled");
+                }
+            }
+        }
+    }
+
+    /**
+     * Execution continues if there is at least one thread even if
+     * thread factory fails to create more
+     */
+    public void testFailingThreadFactory() throws InterruptedException {
+        final ExecutorService e =
+            new ThreadPoolExecutor(100, 100,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new LinkedBlockingQueue<Runnable>(),
+                                   new FailingThreadFactory());
+        try (PoolCleaner cleaner = cleaner(e)) {
+            final int TASKS = 100;
+            final CountDownLatch done = new CountDownLatch(TASKS);
+            for (int k = 0; k < TASKS; ++k)
+                e.execute(new CheckedRunnable() {
+                    public void realRun() {
+                        done.countDown();
+                    }});
+            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * allowsCoreThreadTimeOut is by default false.
+     */
+    public void testAllowsCoreThreadTimeOut() {
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 2,
+                                   1000, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            assertFalse(p.allowsCoreThreadTimeOut());
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(true) causes idle threads to time out
+     */
+    public void testAllowCoreThreadTimeOut_true() throws Exception {
+        long keepAliveTime = timeoutMillis();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 10,
+                                   keepAliveTime, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.allowCoreThreadTimeOut(true);
+            p.execute(new CheckedRunnable() {
+                public void realRun() {
+                    threadStarted.countDown();
+                    assertEquals(1, p.getPoolSize());
+                }});
+            await(threadStarted);
+            delay(keepAliveTime);
+            long startTime = System.nanoTime();
+            while (p.getPoolSize() > 0
+                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
+                Thread.yield();
+            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
+            assertEquals(0, p.getPoolSize());
+        }
+    }
+
+    /**
+     * allowCoreThreadTimeOut(false) causes idle threads not to time out
+     */
+    public void testAllowCoreThreadTimeOut_false() throws Exception {
+        long keepAliveTime = timeoutMillis();
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(2, 10,
+                                   keepAliveTime, MILLISECONDS,
+                                   new ArrayBlockingQueue<Runnable>(10));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            final CountDownLatch threadStarted = new CountDownLatch(1);
+            p.allowCoreThreadTimeOut(false);
+            p.execute(new CheckedRunnable() {
+                public void realRun() throws InterruptedException {
+                    threadStarted.countDown();
+                    assertTrue(p.getPoolSize() >= 1);
+                }});
+            delay(2 * keepAliveTime);
+            assertTrue(p.getPoolSize() >= 1);
+        }
+    }
+
+    /**
+     * execute allows the same task to be submitted multiple times, even
+     * if rejected
+     */
+    public void testRejectedRecycledTask() throws InterruptedException {
+        final int nTasks = 1000;
+        final CountDownLatch done = new CountDownLatch(nTasks);
+        final Runnable recycledTask = new Runnable() {
+            public void run() {
+                done.countDown();
+            }};
+        final ThreadPoolExecutor p =
+            new ThreadPoolExecutor(1, 30,
+                                   60, SECONDS,
+                                   new ArrayBlockingQueue(30));
+        try (PoolCleaner cleaner = cleaner(p)) {
+            for (int i = 0; i < nTasks; ++i) {
+                for (;;) {
+                    try {
+                        p.execute(recycledTask);
+                        break;
+                    }
+                    catch (RejectedExecutionException ignore) {}
+                }
+            }
+            // enough time to run all tasks
+            assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS));
+        }
+    }
+
+    /**
+     * get(cancelled task) throws CancellationException
+     */
+    public void testGet_cancelled() throws Exception {
+        final CountDownLatch done = new CountDownLatch(1);
+        final ExecutorService e =
+            new ThreadPoolExecutor(1, 1,
+                                   LONG_DELAY_MS, MILLISECONDS,
+                                   new LinkedBlockingQueue<Runnable>());
+        try (PoolCleaner cleaner = cleaner(e, done)) {
+            final CountDownLatch blockerStarted = new CountDownLatch(1);
+            final List<Future<?>> futures = new ArrayList<>();
+            for (int i = 0; i < 2; i++) {
+                Runnable r = new CheckedRunnable() { public void realRun()
+                                                         throws Throwable {
+                    blockerStarted.countDown();
+                    assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
+                }};
+                futures.add(e.submit(r));
+            }
+            await(blockerStarted);
+            for (Future<?> future : futures) future.cancel(false);
+            for (Future<?> future : futures) {
+                try {
+                    future.get();
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                try {
+                    future.get(LONG_DELAY_MS, MILLISECONDS);
+                    shouldThrow();
+                } catch (CancellationException success) {}
+                assertTrue(future.isCancelled());
+                assertTrue(future.isDone());
+            }
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/ThreadTest.java b/ojluni/src/test/java/util/concurrent/tck/ThreadTest.java
new file mode 100644
index 0000000..d15ef92
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/ThreadTest.java
@@ -0,0 +1,101 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class ThreadTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(ThreadTest.class);
+    }
+
+    static class MyHandler implements Thread.UncaughtExceptionHandler {
+        public void uncaughtException(Thread t, Throwable e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * getUncaughtExceptionHandler returns ThreadGroup unless set,
+     * otherwise returning value of last setUncaughtExceptionHandler.
+     */
+    public void testGetAndSetUncaughtExceptionHandler() {
+        // these must be done all at once to avoid state
+        // dependencies across tests
+        Thread current = Thread.currentThread();
+        ThreadGroup tg = current.getThreadGroup();
+        MyHandler eh = new MyHandler();
+        assertSame(tg, current.getUncaughtExceptionHandler());
+        current.setUncaughtExceptionHandler(eh);
+        try {
+            assertSame(eh, current.getUncaughtExceptionHandler());
+        } finally {
+            current.setUncaughtExceptionHandler(null);
+        }
+        assertSame(tg, current.getUncaughtExceptionHandler());
+    }
+
+    /**
+     * getDefaultUncaughtExceptionHandler returns value of last
+     * setDefaultUncaughtExceptionHandler.
+     */
+    public void testGetAndSetDefaultUncaughtExceptionHandler() {
+        assertEquals(null, Thread.getDefaultUncaughtExceptionHandler());
+        // failure due to SecurityException is OK.
+        // Would be nice to explicitly test both ways, but cannot yet.
+        Thread.UncaughtExceptionHandler defaultHandler
+            = Thread.getDefaultUncaughtExceptionHandler();
+        MyHandler eh = new MyHandler();
+        try {
+            Thread.setDefaultUncaughtExceptionHandler(eh);
+            try {
+                assertSame(eh, Thread.getDefaultUncaughtExceptionHandler());
+            } finally {
+                Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
+            }
+        } catch (SecurityException ok) {
+            assertNotNull(System.getSecurityManager());
+        }
+        assertSame(defaultHandler, Thread.getDefaultUncaughtExceptionHandler());
+    }
+
+    // How to test actually using UEH within junit?
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/TimeUnitTest.java b/ojluni/src/test/java/util/concurrent/tck/TimeUnitTest.java
new file mode 100644
index 0000000..8ff88597
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/TimeUnitTest.java
@@ -0,0 +1,634 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package test.java.util.concurrent.tck;
+import static java.util.concurrent.TimeUnit.DAYS;
+import static java.util.concurrent.TimeUnit.HOURS;
+import static java.util.concurrent.TimeUnit.MICROSECONDS;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.MINUTES;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TimeUnitTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        return new TestSuite(TimeUnitTest.class);
+    }
+
+    // (loops to 88888 check increments at all time divisions.)
+
+    /**
+     * convert correctly converts sample values across the units
+     */
+    public void testConvert() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*60*24,
+                         SECONDS.convert(t, DAYS));
+            assertEquals(t*60*60,
+                         SECONDS.convert(t, HOURS));
+            assertEquals(t*60,
+                         SECONDS.convert(t, MINUTES));
+            assertEquals(t,
+                         SECONDS.convert(t, SECONDS));
+            assertEquals(t,
+                         SECONDS.convert(1000L*t, MILLISECONDS));
+            assertEquals(t,
+                         SECONDS.convert(1000000L*t, MICROSECONDS));
+            assertEquals(t,
+                         SECONDS.convert(1000000000L*t, NANOSECONDS));
+
+            assertEquals(1000L*t*60*60*24,
+                         MILLISECONDS.convert(t, DAYS));
+            assertEquals(1000L*t*60*60,
+                         MILLISECONDS.convert(t, HOURS));
+            assertEquals(1000L*t*60,
+                         MILLISECONDS.convert(t, MINUTES));
+            assertEquals(1000L*t,
+                         MILLISECONDS.convert(t, SECONDS));
+            assertEquals(t,
+                         MILLISECONDS.convert(t, MILLISECONDS));
+            assertEquals(t,
+                         MILLISECONDS.convert(1000L*t, MICROSECONDS));
+            assertEquals(t,
+                         MILLISECONDS.convert(1000000L*t, NANOSECONDS));
+
+            assertEquals(1000000L*t*60*60*24,
+                         MICROSECONDS.convert(t, DAYS));
+            assertEquals(1000000L*t*60*60,
+                         MICROSECONDS.convert(t, HOURS));
+            assertEquals(1000000L*t*60,
+                         MICROSECONDS.convert(t, MINUTES));
+            assertEquals(1000000L*t,
+                         MICROSECONDS.convert(t, SECONDS));
+            assertEquals(1000L*t,
+                         MICROSECONDS.convert(t, MILLISECONDS));
+            assertEquals(t,
+                         MICROSECONDS.convert(t, MICROSECONDS));
+            assertEquals(t,
+                         MICROSECONDS.convert(1000L*t, NANOSECONDS));
+
+            assertEquals(1000000000L*t*60*60*24,
+                         NANOSECONDS.convert(t, DAYS));
+            assertEquals(1000000000L*t*60*60,
+                         NANOSECONDS.convert(t, HOURS));
+            assertEquals(1000000000L*t*60,
+                         NANOSECONDS.convert(t, MINUTES));
+            assertEquals(1000000000L*t,
+                         NANOSECONDS.convert(t, SECONDS));
+            assertEquals(1000000L*t,
+                         NANOSECONDS.convert(t, MILLISECONDS));
+            assertEquals(1000L*t,
+                         NANOSECONDS.convert(t, MICROSECONDS));
+            assertEquals(t,
+                         NANOSECONDS.convert(t, NANOSECONDS));
+        }
+
+        for (TimeUnit x : TimeUnit.values()) {
+            long[] zs = {
+                0, 1, -1,
+                Integer.MAX_VALUE, Integer.MIN_VALUE,
+                Long.MAX_VALUE, Long.MIN_VALUE,
+            };
+            for (long z : zs) assertEquals(z, x.convert(z, x));
+        }
+    }
+
+    /**
+     * toNanos correctly converts sample values in different units to
+     * nanoseconds
+     */
+    public void testToNanos() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000000000L*60*60*24,
+                         DAYS.toNanos(t));
+            assertEquals(t*1000000000L*60*60,
+                         HOURS.toNanos(t));
+            assertEquals(t*1000000000L*60,
+                         MINUTES.toNanos(t));
+            assertEquals(1000000000L*t,
+                         SECONDS.toNanos(t));
+            assertEquals(1000000L*t,
+                         MILLISECONDS.toNanos(t));
+            assertEquals(1000L*t,
+                         MICROSECONDS.toNanos(t));
+            assertEquals(t,
+                         NANOSECONDS.toNanos(t));
+        }
+    }
+
+    /**
+     * toMicros correctly converts sample values in different units to
+     * microseconds
+     */
+    public void testToMicros() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000000L*60*60*24,
+                         DAYS.toMicros(t));
+            assertEquals(t*1000000L*60*60,
+                         HOURS.toMicros(t));
+            assertEquals(t*1000000L*60,
+                         MINUTES.toMicros(t));
+            assertEquals(1000000L*t,
+                         SECONDS.toMicros(t));
+            assertEquals(1000L*t,
+                         MILLISECONDS.toMicros(t));
+            assertEquals(t,
+                         MICROSECONDS.toMicros(t));
+            assertEquals(t,
+                         NANOSECONDS.toMicros(t*1000L));
+        }
+    }
+
+    /**
+     * toMillis correctly converts sample values in different units to
+     * milliseconds
+     */
+    public void testToMillis() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*1000L*60*60*24,
+                         DAYS.toMillis(t));
+            assertEquals(t*1000L*60*60,
+                         HOURS.toMillis(t));
+            assertEquals(t*1000L*60,
+                         MINUTES.toMillis(t));
+            assertEquals(1000L*t,
+                         SECONDS.toMillis(t));
+            assertEquals(t,
+                         MILLISECONDS.toMillis(t));
+            assertEquals(t,
+                         MICROSECONDS.toMillis(t*1000L));
+            assertEquals(t,
+                         NANOSECONDS.toMillis(t*1000000L));
+        }
+    }
+
+    /**
+     * toSeconds correctly converts sample values in different units to
+     * seconds
+     */
+    public void testToSeconds() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*60*24,
+                         DAYS.toSeconds(t));
+            assertEquals(t*60*60,
+                         HOURS.toSeconds(t));
+            assertEquals(t*60,
+                         MINUTES.toSeconds(t));
+            assertEquals(t,
+                         SECONDS.toSeconds(t));
+            assertEquals(t,
+                         MILLISECONDS.toSeconds(t*1000L));
+            assertEquals(t,
+                         MICROSECONDS.toSeconds(t*1000000L));
+            assertEquals(t,
+                         NANOSECONDS.toSeconds(t*1000000000L));
+        }
+    }
+
+    /**
+     * toMinutes correctly converts sample values in different units to
+     * minutes
+     */
+    public void testToMinutes() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*60*24,
+                         DAYS.toMinutes(t));
+            assertEquals(t*60,
+                         HOURS.toMinutes(t));
+            assertEquals(t,
+                         MINUTES.toMinutes(t));
+            assertEquals(t,
+                         SECONDS.toMinutes(t*60));
+            assertEquals(t,
+                         MILLISECONDS.toMinutes(t*1000L*60));
+            assertEquals(t,
+                         MICROSECONDS.toMinutes(t*1000000L*60));
+            assertEquals(t,
+                         NANOSECONDS.toMinutes(t*1000000000L*60));
+        }
+    }
+
+    /**
+     * toHours correctly converts sample values in different units to
+     * hours
+     */
+    public void testToHours() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t*24,
+                         DAYS.toHours(t));
+            assertEquals(t,
+                         HOURS.toHours(t));
+            assertEquals(t,
+                         MINUTES.toHours(t*60));
+            assertEquals(t,
+                         SECONDS.toHours(t*60*60));
+            assertEquals(t,
+                         MILLISECONDS.toHours(t*1000L*60*60));
+            assertEquals(t,
+                         MICROSECONDS.toHours(t*1000000L*60*60));
+            assertEquals(t,
+                         NANOSECONDS.toHours(t*1000000000L*60*60));
+        }
+    }
+
+    /**
+     * toDays correctly converts sample values in different units to
+     * days
+     */
+    public void testToDays() {
+        for (long t = 0; t < 88888; ++t) {
+            assertEquals(t,
+                         DAYS.toDays(t));
+            assertEquals(t,
+                         HOURS.toDays(t*24));
+            assertEquals(t,
+                         MINUTES.toDays(t*60*24));
+            assertEquals(t,
+                         SECONDS.toDays(t*60*60*24));
+            assertEquals(t,
+                         MILLISECONDS.toDays(t*1000L*60*60*24));
+            assertEquals(t,
+                         MICROSECONDS.toDays(t*1000000L*60*60*24));
+            assertEquals(t,
+                         NANOSECONDS.toDays(t*1000000000L*60*60*24));
+        }
+    }
+
+    /**
+     * convert saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testConvertSaturate() {
+        assertEquals(Long.MAX_VALUE,
+                     NANOSECONDS.convert(Long.MAX_VALUE / 2, SECONDS));
+        assertEquals(Long.MIN_VALUE,
+                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, SECONDS));
+        assertEquals(Long.MAX_VALUE,
+                     NANOSECONDS.convert(Long.MAX_VALUE / 2, MINUTES));
+        assertEquals(Long.MIN_VALUE,
+                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, MINUTES));
+        assertEquals(Long.MAX_VALUE,
+                     NANOSECONDS.convert(Long.MAX_VALUE / 2, HOURS));
+        assertEquals(Long.MIN_VALUE,
+                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, HOURS));
+        assertEquals(Long.MAX_VALUE,
+                     NANOSECONDS.convert(Long.MAX_VALUE / 2, DAYS));
+        assertEquals(Long.MIN_VALUE,
+                     NANOSECONDS.convert(-Long.MAX_VALUE / 4, DAYS));
+
+        for (TimeUnit x : TimeUnit.values())
+            for (TimeUnit y : TimeUnit.values()) {
+                long ratio = x.toNanos(1) / y.toNanos(1);
+                if (ratio >= 1) {
+                    assertEquals(ratio, y.convert(1, x));
+                    assertEquals(1, x.convert(ratio, y));
+                    long max = Long.MAX_VALUE/ratio;
+                    assertEquals(max * ratio, y.convert(max, x));
+                    assertEquals(-max * ratio, y.convert(-max, x));
+                    assertEquals(max, x.convert(max * ratio, y));
+                    assertEquals(-max, x.convert(-max * ratio, y));
+                    if (max < Long.MAX_VALUE) {
+                        assertEquals(Long.MAX_VALUE, y.convert(max + 1, x));
+                        assertEquals(Long.MIN_VALUE, y.convert(-max - 1, x));
+                        assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE + 1, x));
+                    }
+                    assertEquals(Long.MAX_VALUE, y.convert(Long.MAX_VALUE, x));
+                    assertEquals(Long.MIN_VALUE, y.convert(Long.MIN_VALUE, x));
+                }
+            }
+    }
+
+    /**
+     * toNanos saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToNanosSaturate() {
+        assertEquals(Long.MAX_VALUE,
+                     MILLISECONDS.toNanos(Long.MAX_VALUE / 2));
+        assertEquals(Long.MIN_VALUE,
+                     MILLISECONDS.toNanos(-Long.MAX_VALUE / 3));
+
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / NANOSECONDS.toNanos(1);
+            if (ratio >= 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toNanos(z));
+                if (max < Long.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toNanos(max + 1));
+                    assertEquals(Long.MIN_VALUE, x.toNanos(-max - 1));
+                    assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE + 1));
+                }
+                assertEquals(Long.MAX_VALUE, x.toNanos(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toNanos(Long.MIN_VALUE));
+                if (max < Integer.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toNanos(Integer.MAX_VALUE));
+                    assertEquals(Long.MIN_VALUE, x.toNanos(Integer.MIN_VALUE));
+                }
+            }
+        }
+    }
+
+    /**
+     * toMicros saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToMicrosSaturate() {
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / MICROSECONDS.toNanos(1);
+            if (ratio >= 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toMicros(z));
+                if (max < Long.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toMicros(max + 1));
+                    assertEquals(Long.MIN_VALUE, x.toMicros(-max - 1));
+                    assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE + 1));
+                }
+                assertEquals(Long.MAX_VALUE, x.toMicros(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toMicros(Long.MIN_VALUE));
+                if (max < Integer.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toMicros(Integer.MAX_VALUE));
+                    assertEquals(Long.MIN_VALUE, x.toMicros(Integer.MIN_VALUE));
+                }
+            }
+        }
+    }
+
+    /**
+     * toMillis saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToMillisSaturate() {
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / MILLISECONDS.toNanos(1);
+            if (ratio >= 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toMillis(z));
+                if (max < Long.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toMillis(max + 1));
+                    assertEquals(Long.MIN_VALUE, x.toMillis(-max - 1));
+                    assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE + 1));
+                }
+                assertEquals(Long.MAX_VALUE, x.toMillis(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toMillis(Long.MIN_VALUE));
+                if (max < Integer.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toMillis(Integer.MAX_VALUE));
+                    assertEquals(Long.MIN_VALUE, x.toMillis(Integer.MIN_VALUE));
+                }
+            }
+        }
+    }
+
+    /**
+     * toSeconds saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToSecondsSaturate() {
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / SECONDS.toNanos(1);
+            if (ratio >= 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toSeconds(z));
+                if (max < Long.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toSeconds(max + 1));
+                    assertEquals(Long.MIN_VALUE, x.toSeconds(-max - 1));
+                    assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE + 1));
+                }
+                assertEquals(Long.MAX_VALUE, x.toSeconds(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toSeconds(Long.MIN_VALUE));
+                if (max < Integer.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toSeconds(Integer.MAX_VALUE));
+                    assertEquals(Long.MIN_VALUE, x.toSeconds(Integer.MIN_VALUE));
+                }
+            }
+        }
+    }
+
+    /**
+     * toMinutes saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToMinutesSaturate() {
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / MINUTES.toNanos(1);
+            if (ratio > 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toMinutes(z));
+                assertEquals(Long.MAX_VALUE, x.toMinutes(max + 1));
+                assertEquals(Long.MIN_VALUE, x.toMinutes(-max - 1));
+                assertEquals(Long.MAX_VALUE, x.toMinutes(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toMinutes(Long.MIN_VALUE + 1));
+            }
+        }
+    }
+
+    /**
+     * toHours saturates positive too-large values to Long.MAX_VALUE
+     * and negative to LONG.MIN_VALUE
+     */
+    public void testToHoursSaturate() {
+        for (TimeUnit x : TimeUnit.values()) {
+            long ratio = x.toNanos(1) / HOURS.toNanos(1);
+            if (ratio >= 1) {
+                long max = Long.MAX_VALUE/ratio;
+                for (long z : new long[] {0, 1, -1, max, -max})
+                    assertEquals(z * ratio, x.toHours(z));
+                if (max < Long.MAX_VALUE) {
+                    assertEquals(Long.MAX_VALUE, x.toHours(max + 1));
+                    assertEquals(Long.MIN_VALUE, x.toHours(-max - 1));
+                    assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE + 1));
+                }
+                assertEquals(Long.MAX_VALUE, x.toHours(Long.MAX_VALUE));
+                assertEquals(Long.MIN_VALUE, x.toHours(Long.MIN_VALUE));
+            }
+        }
+    }
+
+    /**
+     * toString returns name of unit
+     */
+    public void testToString() {
+        assertEquals("SECONDS", SECONDS.toString());
+    }
+
+    /**
+     * name returns name of unit
+     */
+    public void testName() {
+        assertEquals("SECONDS", SECONDS.name());
+    }
+
+    /**
+     * Timed wait without holding lock throws
+     * IllegalMonitorStateException
+     */
+    public void testTimedWait_IllegalMonitorException() {
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Object o = new Object();
+                TimeUnit tu = MILLISECONDS;
+
+                try {
+                    tu.timedWait(o, LONG_DELAY_MS);
+                    threadShouldThrow();
+                } catch (IllegalMonitorStateException success) {}
+            }});
+
+        awaitTermination(t);
+    }
+
+    /**
+     * timedWait throws InterruptedException when interrupted
+     */
+    public void testTimedWait_Interruptible() {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                Object o = new Object();
+                TimeUnit tu = MILLISECONDS;
+
+                Thread.currentThread().interrupt();
+                try {
+                    synchronized (o) {
+                        tu.timedWait(o, LONG_DELAY_MS);
+                    }
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    synchronized (o) {
+                        tu.timedWait(o, LONG_DELAY_MS);
+                    }
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * timedJoin throws InterruptedException when interrupted
+     */
+    public void testTimedJoin_Interruptible() {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        final Thread s = newStartedThread(new CheckedInterruptedRunnable() {
+            public void realRun() throws InterruptedException {
+                Thread.sleep(LONG_DELAY_MS);
+            }});
+        final Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                TimeUnit tu = MILLISECONDS;
+                Thread.currentThread().interrupt();
+                try {
+                    tu.timedJoin(s, LONG_DELAY_MS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    tu.timedJoin(s, LONG_DELAY_MS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+        s.interrupt();
+        awaitTermination(s);
+    }
+
+    /**
+     * timedSleep throws InterruptedException when interrupted
+     */
+    public void testTimedSleep_Interruptible() {
+        final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+        Thread t = newStartedThread(new CheckedRunnable() {
+            public void realRun() throws InterruptedException {
+                TimeUnit tu = MILLISECONDS;
+                Thread.currentThread().interrupt();
+                try {
+                    tu.sleep(LONG_DELAY_MS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+
+                pleaseInterrupt.countDown();
+                try {
+                    tu.sleep(LONG_DELAY_MS);
+                    shouldThrow();
+                } catch (InterruptedException success) {}
+                assertFalse(Thread.interrupted());
+            }});
+
+        await(pleaseInterrupt);
+        assertThreadStaysAlive(t);
+        t.interrupt();
+        awaitTermination(t);
+    }
+
+    /**
+     * a deserialized serialized unit is the same instance
+     */
+    public void testSerialization() throws Exception {
+        for (TimeUnit x : TimeUnit.values())
+            assertSame(x, serialClone(x));
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/TreeMapTest.java b/ojluni/src/test/java/util/concurrent/tck/TreeMapTest.java
new file mode 100644
index 0000000..0953302
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/TreeMapTest.java
@@ -0,0 +1,1112 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.TreeMap;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TreeMapTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(TreeMapTest.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static TreeMap map5() {
+        TreeMap map = new TreeMap();
+        assertTrue(map.isEmpty());
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map;
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testClear() {
+        TreeMap map = map5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * copy constructor creates map equal to source map
+     */
+    public void testConstructFromSorted() {
+        TreeMap map = map5();
+        TreeMap map2 = new TreeMap(map);
+        assertEquals(map, map2);
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testEquals() {
+        TreeMap map1 = map5();
+        TreeMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        TreeMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        TreeMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testGet() {
+        TreeMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        TreeMap empty = new TreeMap();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        TreeMap empty = new TreeMap();
+        TreeMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testFirstKey() {
+        TreeMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testLastKey() {
+        TreeMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testKeySetToArray() {
+        TreeMap map = map5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingKeySetToArray() {
+        TreeMap map = map5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        TreeMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testKeySetOrder() {
+        TreeMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descending iterator of key set is inverse ordered
+     */
+    public void testKeySetDescendingIteratorOrder() {
+        TreeMap map = map5();
+        NavigableSet s = map.navigableKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descendingKeySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        TreeMap map = map5();
+        Set s = map.descendingKeySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, five);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * descending iterator of descendingKeySet is ordered
+     */
+    public void testDescendingKeySetDescendingIteratorOrder() {
+        TreeMap map = map5();
+        NavigableSet s = map.descendingKeySet();
+        Iterator i = s.descendingIterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        int count = 1;
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+            ++count;
+        }
+        assertEquals(5, count);
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        TreeMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        TreeMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * descendingEntrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        TreeMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * entrySet.toArray contains all entries
+     */
+    public void testEntrySetToArray() {
+        TreeMap map = map5();
+        Set s = map.entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     * descendingEntrySet.toArray contains all entries
+     */
+    public void testDescendingEntrySetToArray() {
+        TreeMap map = map5();
+        Set s = map.descendingMap().entrySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        for (int i = 0; i < 5; ++i) {
+            assertTrue(map.containsKey(((Map.Entry)(ar[i])).getKey()));
+            assertTrue(map.containsValue(((Map.Entry)(ar[i])).getValue()));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        TreeMap empty = new TreeMap();
+        TreeMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        TreeMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        TreeMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        TreeMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        TreeMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        TreeMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * lowerKey returns preceding element
+     */
+    public void testLowerKey() {
+        TreeMap q = map5();
+        Object e1 = q.lowerKey(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lowerKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lowerKey(one);
+        assertNull(e3);
+
+        Object e4 = q.lowerKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherKey returns next element
+     */
+    public void testHigherKey() {
+        TreeMap q = map5();
+        Object e1 = q.higherKey(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higherKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higherKey(five);
+        assertNull(e3);
+
+        Object e4 = q.higherKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorKey returns preceding element
+     */
+    public void testFloorKey() {
+        TreeMap q = map5();
+        Object e1 = q.floorKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floorKey(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floorKey(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floorKey(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingKey returns next element
+     */
+    public void testCeilingKey() {
+        TreeMap q = map5();
+        Object e1 = q.ceilingKey(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceilingKey(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceilingKey(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceilingKey(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        TreeMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        TreeMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testSize() {
+        TreeMap map = map5();
+        TreeMap empty = new TreeMap();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        TreeMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        TreeMap c = map5();
+        try {
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        TreeMap c = map5();
+        try {
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE for nonempty map
+     */
+    public void testRemove1_NullPointerException() {
+        TreeMap c = new TreeMap();
+        c.put("sadsdf", "asdads");
+        try {
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        NavigableMap x = map5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        TreeMap map = map5();
+        NavigableMap sm = map.subMap(two, true, four, false);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        TreeMap map = map5();
+        NavigableMap sm = map.subMap(two, true, three, false);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        TreeMap map = map5();
+        NavigableMap sm = map.headMap(four, false);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        TreeMap map = map5();
+        NavigableMap sm = map.tailMap(two, true);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+        Iterator r = sm.descendingKeySet().iterator();
+        k = (Integer)(r.next());
+        assertEquals(five, k);
+        k = (Integer)(r.next());
+        assertEquals(four, k);
+        k = (Integer)(r.next());
+        assertEquals(three, k);
+        k = (Integer)(r.next());
+        assertEquals(two, k);
+        assertFalse(r.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        NavigableMap ssm = sm.tailMap(four, true);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    Random rnd = new Random(666);
+    BitSet bs;
+
+    /**
+     * Submaps of submaps subdivide correctly
+     */
+    public void testRecursiveSubMaps() throws Exception {
+        int mapSize = expensiveTests ? 1000 : 100;
+        Class cl = TreeMap.class;
+        NavigableMap<Integer, Integer> map = newMap(cl);
+        bs = new BitSet(mapSize);
+
+        populate(map, mapSize);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        mutateMap(map, 0, mapSize - 1);
+        check(map,                 0, mapSize - 1, true);
+        check(map.descendingMap(), 0, mapSize - 1, false);
+
+        bashSubMap(map.subMap(0, true, mapSize, false),
+                   0, mapSize - 1, true);
+    }
+
+    static NavigableMap<Integer, Integer> newMap(Class cl) throws Exception {
+        NavigableMap<Integer, Integer> result
+            = (NavigableMap<Integer, Integer>) cl.getConstructor().newInstance();
+        assertEquals(0, result.size());
+        assertFalse(result.keySet().iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableMap<Integer, Integer> map, int limit) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int key = rnd.nextInt(limit);
+            put(map, key);
+        }
+    }
+
+    void mutateMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min + rnd.nextInt(rangeSize);
+            assertTrue(key >= min && key <= max);
+            put(map, key);
+        }
+    }
+
+    void mutateSubMap(NavigableMap<Integer, Integer> map, int min, int max) {
+        int size = map.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(map, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = map.keySet().iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (map.size() < size) {
+            int key = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (key >= min && key <= max) {
+                put(map, key);
+            } else {
+                try {
+                    map.put(key, 2 * key);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableMap<Integer, Integer> map, int key) {
+        if (map.put(key, 2 * key) == null)
+            bs.set(key);
+    }
+
+    void remove(NavigableMap<Integer, Integer> map, int key) {
+        if (map.remove(key) != null)
+            bs.clear(key);
+    }
+
+    void bashSubMap(NavigableMap<Integer, Integer> map,
+                    int min, int max, boolean ascending) {
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        mutateSubMap(map, min, max);
+        check(map, min, max, ascending);
+        check(map.descendingMap(), min, max, !ascending);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headMap - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> hm = map.headMap(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, min, midPoint - (incl ? 0 : 1), true);
+            else
+                bashSubMap(hm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           false);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubMap(hm, midPoint + (incl ? 0 : 1), max, false);
+            else
+                bashSubMap(hm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           true);
+        }
+
+        // tailMap - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableMap<Integer,Integer> tm = map.tailMap(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubMap(tm, midPoint + (incl ? 0 : 1), max, true);
+            else
+                bashSubMap(tm.descendingMap(), midPoint + (incl ? 0 : 1), max,
+                           false);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubMap(tm, min, midPoint - (incl ? 0 : 1), false);
+            } else {
+                bashSubMap(tm.descendingMap(), min, midPoint - (incl ? 0 : 1),
+                           true);
+            }
+        }
+
+        // subMap - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+        } else {
+            NavigableMap<Integer,Integer> sm = map.subMap(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubMap(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+            else
+                bashSubMap(sm.descendingMap(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableMap<Integer, Integer> map,
+                      final int min, final int max, final boolean ascending) {
+        class ReferenceSet {
+            int lower(int key) {
+                return ascending ? lowerAscending(key) : higherAscending(key);
+            }
+            int floor(int key) {
+                return ascending ? floorAscending(key) : ceilingAscending(key);
+            }
+            int ceiling(int key) {
+                return ascending ? ceilingAscending(key) : floorAscending(key);
+            }
+            int higher(int key) {
+                return ascending ? higherAscending(key) : lowerAscending(key);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int key) {
+                return floorAscending(key - 1);
+            }
+            int floorAscending(int key) {
+                if (key < min)
+                    return -1;
+                else if (key > max)
+                    key = max;
+
+                // BitSet should support this! Test would run much faster
+                while (key >= min) {
+                    if (bs.get(key))
+                        return key;
+                    key--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int key) {
+                if (key < min)
+                    key = min;
+                else if (key > max)
+                    return -1;
+                int result = bs.nextSetBit(key);
+                return result > max ? -1 : result;
+            }
+            int higherAscending(int key) {
+                return ceilingAscending(key + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return result > max ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return result < min ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsKey
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, map.containsKey(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(size, map.size());
+
+        // Test contents using contains keySet iterator
+        int size2 = 0;
+        int previousKey = -1;
+        for (int key : map.keySet()) {
+            assertTrue(bs.get(key));
+            size2++;
+            assertTrue(previousKey < 0 ||
+                (ascending ? key - previousKey > 0 : key - previousKey < 0));
+            previousKey = key;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int key = min - 1; key <= max + 1; key++) {
+            assertEq(map.lowerKey(key), rs.lower(key));
+            assertEq(map.floorKey(key), rs.floor(key));
+            assertEq(map.higherKey(key), rs.higher(key));
+            assertEq(map.ceilingKey(key), rs.ceiling(key));
+        }
+
+        // Test extrema
+        if (map.size() != 0) {
+            assertEq(map.firstKey(), rs.first());
+            assertEq(map.lastKey(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                map.firstKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                map.lastKey();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return i == null ? j == -1 : i == j;
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/TreeSetTest.java b/ojluni/src/test/java/util/concurrent/tck/TreeSetTest.java
new file mode 100644
index 0000000..9f40007
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/TreeSetTest.java
@@ -0,0 +1,1010 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+import java.util.Random;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TreeSetTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(TreeSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * The number of elements to place in collections, arrays, etc.
+     */
+    static final int SIZE = 20;
+
+    /**
+     * Returns a new set of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private TreeSet<Integer> populatedSet(int n) {
+        TreeSet<Integer> q = new TreeSet<>();
+        assertTrue(q.isEmpty());
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.add(new Integer(i)));
+        assertFalse(q.isEmpty());
+        assertEquals(n, q.size());
+        return q;
+    }
+
+    /**
+     * Returns a new set of first 5 ints.
+     */
+    private TreeSet set5() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        assertEquals(5, q.size());
+        return q;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, new TreeSet().size());
+    }
+
+    /**
+     * Initializing from null Collection throws NPE
+     */
+    public void testConstructor3() {
+        try {
+            new TreeSet((Collection)null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection of null elements throws NPE
+     */
+    public void testConstructor4() {
+        try {
+            new TreeSet(Arrays.asList(new Integer[SIZE]));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Initializing from Collection with some null elements throws NPE
+     */
+    public void testConstructor5() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            new TreeSet(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of collection used to initialize
+     */
+    public void testConstructor6() {
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        TreeSet q = new TreeSet(Arrays.asList(ints));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * The comparator used in constructor is used
+     */
+    public void testConstructor7() {
+        MyReverseComparator cmp = new MyReverseComparator();
+        TreeSet q = new TreeSet(cmp);
+        assertEquals(cmp, q.comparator());
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(i);
+        q.addAll(Arrays.asList(ints));
+        for (int i = SIZE - 1; i >= 0; --i)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.isEmpty());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.add(new Integer(2));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        TreeSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE if nonempty
+     */
+    public void testAddNull() {
+        TreeSet q = populatedSet(SIZE);
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.add(zero));
+        assertTrue(q.add(one));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.add(zero));
+        assertFalse(q.add(zero));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        TreeSet q = new TreeSet();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        TreeSet q = new TreeSet();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        TreeSet q = new TreeSet();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        TreeSet q = new TreeSet();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        TreeSet q = new TreeSet();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * pollFirst succeeds unless empty
+     */
+    public void testPollFirst() {
+        TreeSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * pollLast succeeds unless empty
+     */
+    public void testPollLast() {
+        TreeSet q = populatedSet(SIZE);
+        for (int i = SIZE - 1; i >= 0; --i) {
+            assertEquals(i, q.pollLast());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        TreeSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        TreeSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        TreeSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        q.add(new Integer(1));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        TreeSet q = populatedSet(SIZE);
+        TreeSet p = new TreeSet();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        TreeSet q = populatedSet(SIZE);
+        TreeSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            TreeSet q = populatedSet(SIZE);
+            TreeSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        TreeSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        TreeSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        TreeSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        TreeSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements in sorted order
+     */
+    public void testToArray() {
+        TreeSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements in sorted order
+     */
+    public void testToArray2() {
+        TreeSet<Integer> q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        TreeSet q = populatedSet(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(new TreeSet().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final TreeSet q = new TreeSet();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(it.next(), new Integer(2));
+        assertEquals(it.next(), new Integer(3));
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        TreeSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        NavigableSet x = populatedSet(SIZE);
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        TreeSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        TreeSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        TreeSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        TreeSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    Random rnd = new Random(666);
+    BitSet bs;
+
+    /**
+     * Subsets of subsets subdivide correctly
+     */
+    public void testRecursiveSubSets() throws Exception {
+        int setSize = expensiveTests ? 1000 : 100;
+        Class cl = TreeSet.class;
+
+        NavigableSet<Integer> set = newSet(cl);
+        bs = new BitSet(setSize);
+
+        populate(set, setSize);
+        check(set,                 0, setSize - 1, true);
+        check(set.descendingSet(), 0, setSize - 1, false);
+
+        mutateSet(set, 0, setSize - 1);
+        check(set,                 0, setSize - 1, true);
+        check(set.descendingSet(), 0, setSize - 1, false);
+
+        bashSubSet(set.subSet(0, true, setSize, false),
+                   0, setSize - 1, true);
+    }
+
+    /**
+     * addAll is idempotent
+     */
+    public void testAddAll_idempotent() throws Exception {
+        Set x = populatedSet(SIZE);
+        Set y = new TreeSet(x);
+        y.addAll(x);
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    static NavigableSet<Integer> newSet(Class cl) throws Exception {
+        NavigableSet<Integer> result =
+            (NavigableSet<Integer>) cl.getConstructor().newInstance();
+        assertEquals(0, result.size());
+        assertFalse(result.iterator().hasNext());
+        return result;
+    }
+
+    void populate(NavigableSet<Integer> set, int limit) {
+        for (int i = 0, n = 2 * limit / 3; i < n; i++) {
+            int element = rnd.nextInt(limit);
+            put(set, element);
+        }
+    }
+
+    void mutateSet(NavigableSet<Integer> set, int min, int max) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min + rnd.nextInt(rangeSize);
+            assertTrue(element >= min && element <= max);
+            put(set, element);
+        }
+    }
+
+    void mutateSubSet(NavigableSet<Integer> set, int min, int max) {
+        int size = set.size();
+        int rangeSize = max - min + 1;
+
+        // Remove a bunch of entries directly
+        for (int i = 0, n = rangeSize / 2; i < n; i++) {
+            remove(set, min - 5 + rnd.nextInt(rangeSize + 10));
+        }
+
+        // Remove a bunch of entries with iterator
+        for (Iterator<Integer> it = set.iterator(); it.hasNext(); ) {
+            if (rnd.nextBoolean()) {
+                bs.clear(it.next());
+                it.remove();
+            }
+        }
+
+        // Add entries till we're back to original size
+        while (set.size() < size) {
+            int element = min - 5 + rnd.nextInt(rangeSize + 10);
+            if (element >= min && element <= max) {
+                put(set, element);
+            } else {
+                try {
+                    set.add(element);
+                    shouldThrow();
+                } catch (IllegalArgumentException success) {}
+            }
+        }
+    }
+
+    void put(NavigableSet<Integer> set, int element) {
+        if (set.add(element))
+            bs.set(element);
+    }
+
+    void remove(NavigableSet<Integer> set, int element) {
+        if (set.remove(element))
+            bs.clear(element);
+    }
+
+    void bashSubSet(NavigableSet<Integer> set,
+                    int min, int max, boolean ascending) {
+        check(set, min, max, ascending);
+        check(set.descendingSet(), min, max, !ascending);
+
+        mutateSubSet(set, min, max);
+        check(set, min, max, ascending);
+        check(set.descendingSet(), min, max, !ascending);
+
+        // Recurse
+        if (max - min < 2)
+            return;
+        int midPoint = (min + max) / 2;
+
+        // headSet - pick direction and endpoint inclusion randomly
+        boolean incl = rnd.nextBoolean();
+        NavigableSet<Integer> hm = set.headSet(midPoint, incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, min, midPoint - (incl ? 0 : 1), true);
+            else
+                bashSubSet(hm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           false);
+        } else {
+            if (rnd.nextBoolean())
+                bashSubSet(hm, midPoint + (incl ? 0 : 1), max, false);
+            else
+                bashSubSet(hm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           true);
+        }
+
+        // tailSet - pick direction and endpoint inclusion randomly
+        incl = rnd.nextBoolean();
+        NavigableSet<Integer> tm = set.tailSet(midPoint,incl);
+        if (ascending) {
+            if (rnd.nextBoolean())
+                bashSubSet(tm, midPoint + (incl ? 0 : 1), max, true);
+            else
+                bashSubSet(tm.descendingSet(), midPoint + (incl ? 0 : 1), max,
+                           false);
+        } else {
+            if (rnd.nextBoolean()) {
+                bashSubSet(tm, min, midPoint - (incl ? 0 : 1), false);
+            } else {
+                bashSubSet(tm.descendingSet(), min, midPoint - (incl ? 0 : 1),
+                           true);
+            }
+        }
+
+        // subSet - pick direction and endpoint inclusion randomly
+        int rangeSize = max - min + 1;
+        int[] endpoints = new int[2];
+        endpoints[0] = min + rnd.nextInt(rangeSize);
+        endpoints[1] = min + rnd.nextInt(rangeSize);
+        Arrays.sort(endpoints);
+        boolean lowIncl = rnd.nextBoolean();
+        boolean highIncl = rnd.nextBoolean();
+        if (ascending) {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[0], lowIncl, endpoints[1], highIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+        } else {
+            NavigableSet<Integer> sm = set.subSet(
+                endpoints[1], highIncl, endpoints[0], lowIncl);
+            if (rnd.nextBoolean())
+                bashSubSet(sm, endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), false);
+            else
+                bashSubSet(sm.descendingSet(), endpoints[0] + (lowIncl ? 0 : 1),
+                           endpoints[1] - (highIncl ? 0 : 1), true);
+        }
+    }
+
+    /**
+     * min and max are both inclusive.  If max < min, interval is empty.
+     */
+    void check(NavigableSet<Integer> set,
+                      final int min, final int max, final boolean ascending) {
+        class ReferenceSet {
+            int lower(int element) {
+                return ascending ?
+                    lowerAscending(element) : higherAscending(element);
+            }
+            int floor(int element) {
+                return ascending ?
+                    floorAscending(element) : ceilingAscending(element);
+            }
+            int ceiling(int element) {
+                return ascending ?
+                    ceilingAscending(element) : floorAscending(element);
+            }
+            int higher(int element) {
+                return ascending ?
+                    higherAscending(element) : lowerAscending(element);
+            }
+            int first() {
+                return ascending ? firstAscending() : lastAscending();
+            }
+            int last() {
+                return ascending ? lastAscending() : firstAscending();
+            }
+            int lowerAscending(int element) {
+                return floorAscending(element - 1);
+            }
+            int floorAscending(int element) {
+                if (element < min)
+                    return -1;
+                else if (element > max)
+                    element = max;
+
+                // BitSet should support this! Test would run much faster
+                while (element >= min) {
+                    if (bs.get(element))
+                        return element;
+                    element--;
+                }
+                return -1;
+            }
+            int ceilingAscending(int element) {
+                if (element < min)
+                    element = min;
+                else if (element > max)
+                    return -1;
+                int result = bs.nextSetBit(element);
+                return (result > max) ? -1 : result;
+            }
+            int higherAscending(int element) {
+                return ceilingAscending(element + 1);
+            }
+            private int firstAscending() {
+                int result = ceilingAscending(min);
+                return (result > max) ? -1 : result;
+            }
+            private int lastAscending() {
+                int result = floorAscending(max);
+                return (result < min) ? -1 : result;
+            }
+        }
+        ReferenceSet rs = new ReferenceSet();
+
+        // Test contents using containsElement
+        int size = 0;
+        for (int i = min; i <= max; i++) {
+            boolean bsContainsI = bs.get(i);
+            assertEquals(bsContainsI, set.contains(i));
+            if (bsContainsI)
+                size++;
+        }
+        assertEquals(size, set.size());
+
+        // Test contents using contains elementSet iterator
+        int size2 = 0;
+        int previousElement = -1;
+        for (int element : set) {
+            assertTrue(bs.get(element));
+            size2++;
+            assertTrue(previousElement < 0 || (ascending ?
+                element - previousElement > 0 : element - previousElement < 0));
+            previousElement = element;
+        }
+        assertEquals(size2, size);
+
+        // Test navigation ops
+        for (int element = min - 1; element <= max + 1; element++) {
+            assertEq(set.lower(element), rs.lower(element));
+            assertEq(set.floor(element), rs.floor(element));
+            assertEq(set.higher(element), rs.higher(element));
+            assertEq(set.ceiling(element), rs.ceiling(element));
+        }
+
+        // Test extrema
+        if (set.size() != 0) {
+            assertEq(set.first(), rs.first());
+            assertEq(set.last(), rs.last());
+        } else {
+            assertEq(rs.first(), -1);
+            assertEq(rs.last(),  -1);
+            try {
+                set.first();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+            try {
+                set.last();
+                shouldThrow();
+            } catch (NoSuchElementException success) {}
+        }
+    }
+
+    static void assertEq(Integer i, int j) {
+        if (i == null)
+            assertEquals(j, -1);
+        else
+            assertEquals((int) i, j);
+    }
+
+    static boolean eq(Integer i, int j) {
+        return (i == null) ? j == -1 : i == j;
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/TreeSubMapTest.java b/ojluni/src/test/java/util/concurrent/tck/TreeSubMapTest.java
new file mode 100644
index 0000000..77ff558
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/TreeSubMapTest.java
@@ -0,0 +1,1139 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TreeSubMapTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(TreeSubMapTest.class);
+    }
+
+    /**
+     * Returns a new map from Integers 1-5 to Strings "A"-"E".
+     */
+    private static NavigableMap map5() {
+        TreeMap map = new TreeMap();
+        assertTrue(map.isEmpty());
+        map.put(zero, "Z");
+        map.put(one, "A");
+        map.put(five, "E");
+        map.put(three, "C");
+        map.put(two, "B");
+        map.put(four, "D");
+        map.put(seven, "F");
+        assertFalse(map.isEmpty());
+        assertEquals(7, map.size());
+        return map.subMap(one, true, seven, false);
+    }
+
+    private static NavigableMap map0() {
+        TreeMap map = new TreeMap();
+        assertTrue(map.isEmpty());
+        return map.tailMap(one, true);
+    }
+
+    /**
+     * Returns a new map from Integers -5 to -1 to Strings "A"-"E".
+     */
+    private static NavigableMap dmap5() {
+        TreeMap map = new TreeMap();
+        assertTrue(map.isEmpty());
+        map.put(m1, "A");
+        map.put(m5, "E");
+        map.put(m3, "C");
+        map.put(m2, "B");
+        map.put(m4, "D");
+        assertFalse(map.isEmpty());
+        assertEquals(5, map.size());
+        return map.descendingMap();
+    }
+
+    private static NavigableMap dmap0() {
+        TreeMap map = new TreeMap();
+        assertTrue(map.isEmpty());
+        return map;
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testClear() {
+        NavigableMap map = map5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testEquals() {
+        NavigableMap map1 = map5();
+        NavigableMap map2 = map5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testContainsKey() {
+        NavigableMap map = map5();
+        assertTrue(map.containsKey(one));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testContainsValue() {
+        NavigableMap map = map5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testGet() {
+        NavigableMap map = map5();
+        assertEquals("A", (String)map.get(one));
+        NavigableMap empty = map0();
+        assertNull(empty.get(one));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testIsEmpty() {
+        NavigableMap empty = map0();
+        NavigableMap map = map5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testFirstKey() {
+        NavigableMap map = map5();
+        assertEquals(one, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testLastKey() {
+        NavigableMap map = map5();
+        assertEquals(five, map.lastKey());
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testKeySet() {
+        NavigableMap map = map5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(one));
+        assertTrue(s.contains(two));
+        assertTrue(s.contains(three));
+        assertTrue(s.contains(four));
+        assertTrue(s.contains(five));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testKeySetOrder() {
+        NavigableMap map = map5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, one);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) < 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testValues() {
+        NavigableMap map = map5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testEntrySet() {
+        NavigableMap map = map5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(one) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(two) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(three) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(four) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(five) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testPutAll() {
+        NavigableMap empty = map0();
+        NavigableMap map = map5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(one));
+        assertTrue(empty.containsKey(two));
+        assertTrue(empty.containsKey(three));
+        assertTrue(empty.containsKey(four));
+        assertTrue(empty.containsKey(five));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testRemove() {
+        NavigableMap map = map5();
+        map.remove(five);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(five));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testLowerEntry() {
+        NavigableMap map = map5();
+        Map.Entry e1 = map.lowerEntry(three);
+        assertEquals(two, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(one);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testHigherEntry() {
+        NavigableMap map = map5();
+        Map.Entry e1 = map.higherEntry(three);
+        assertEquals(four, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(five);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testFloorEntry() {
+        NavigableMap map = map5();
+        Map.Entry e1 = map.floorEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(six);
+        assertEquals(five, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(one);
+        assertEquals(one, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testCeilingEntry() {
+        NavigableMap map = map5();
+        Map.Entry e1 = map.ceilingEntry(three);
+        assertEquals(three, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(one, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(five);
+        assertEquals(five, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(six);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testPollFirstEntry() {
+        NavigableMap map = map5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(two, e.getKey());
+        map.put(one, "A");
+        e = map.pollFirstEntry();
+        assertEquals(one, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(three, e.getKey());
+        map.remove(four);
+        e = map.pollFirstEntry();
+        assertEquals(five, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        assertTrue(map.isEmpty());
+        Map.Entry f = map.firstEntry();
+        assertNull(f);
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testPollLastEntry() {
+        NavigableMap map = map5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(four, e.getKey());
+        map.put(five, "E");
+        e = map.pollLastEntry();
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(three, e.getKey());
+        map.remove(two);
+        e = map.pollLastEntry();
+        assertEquals(one, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testSize() {
+        NavigableMap map = map5();
+        NavigableMap empty = map0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testToString() {
+        NavigableMap map = map5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception tests
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testGet_NullPointerException() {
+        NavigableMap c = map5();
+        try {
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * containsKey(null) of nonempty map throws NPE
+     */
+    public void testContainsKey_NullPointerException() {
+        NavigableMap c = map5();
+        try {
+            c.containsKey(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testPut1_NullPointerException() {
+        NavigableMap c = map5();
+        try {
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * remove(null) throws NPE
+     */
+    public void testRemove1_NullPointerException() {
+        NavigableMap c = map5();
+        try {
+            c.remove(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testSerialization() throws Exception {
+        NavigableMap x = map5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testSubMapContents() {
+        NavigableMap map = map5();
+        SortedMap sm = map.subMap(two, four);
+        assertEquals(two, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.firstKey());
+        assertEquals(three, sm.lastKey());
+        assertEquals("C", sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testSubMapContents2() {
+        NavigableMap map = map5();
+        SortedMap sm = map.subMap(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.firstKey());
+        assertEquals(two, sm.lastKey());
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertFalse(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(two));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(three), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testHeadMapContents() {
+        NavigableMap map = map5();
+        SortedMap sm = map.headMap(four);
+        assertTrue(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertFalse(sm.containsKey(four));
+        assertFalse(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(four, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testTailMapContents() {
+        NavigableMap map = map5();
+        SortedMap sm = map.tailMap(two);
+        assertFalse(sm.containsKey(one));
+        assertTrue(sm.containsKey(two));
+        assertTrue(sm.containsKey(three));
+        assertTrue(sm.containsKey(four));
+        assertTrue(sm.containsKey(five));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(two, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(three, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(four, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(five, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(four);
+        assertEquals(four, ssm.firstKey());
+        assertEquals(five, ssm.lastKey());
+        assertEquals("D", ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * clear removes all pairs
+     */
+    public void testDescendingClear() {
+        NavigableMap map = dmap5();
+        map.clear();
+        assertEquals(0, map.size());
+    }
+
+    /**
+     * Maps with same contents are equal
+     */
+    public void testDescendingEquals() {
+        NavigableMap map1 = dmap5();
+        NavigableMap map2 = dmap5();
+        assertEquals(map1, map2);
+        assertEquals(map2, map1);
+        map1.clear();
+        assertFalse(map1.equals(map2));
+        assertFalse(map2.equals(map1));
+    }
+
+    /**
+     * containsKey returns true for contained key
+     */
+    public void testDescendingContainsKey() {
+        NavigableMap map = dmap5();
+        assertTrue(map.containsKey(m1));
+        assertFalse(map.containsKey(zero));
+    }
+
+    /**
+     * containsValue returns true for held values
+     */
+    public void testDescendingContainsValue() {
+        NavigableMap map = dmap5();
+        assertTrue(map.containsValue("A"));
+        assertFalse(map.containsValue("Z"));
+    }
+
+    /**
+     * get returns the correct element at the given key,
+     * or null if not present
+     */
+    public void testDescendingGet() {
+        NavigableMap map = dmap5();
+        assertEquals("A", (String)map.get(m1));
+        NavigableMap empty = dmap0();
+        assertNull(empty.get(m1));
+    }
+
+    /**
+     * isEmpty is true of empty map and false for non-empty
+     */
+    public void testDescendingIsEmpty() {
+        NavigableMap empty = dmap0();
+        NavigableMap map = dmap5();
+        assertTrue(empty.isEmpty());
+        assertFalse(map.isEmpty());
+    }
+
+    /**
+     * firstKey returns first key
+     */
+    public void testDescendingFirstKey() {
+        NavigableMap map = dmap5();
+        assertEquals(m1, map.firstKey());
+    }
+
+    /**
+     * lastKey returns last key
+     */
+    public void testDescendingLastKey() {
+        NavigableMap map = dmap5();
+        assertEquals(m5, map.lastKey());
+    }
+
+    /**
+     * keySet returns a Set containing all the keys
+     */
+    public void testDescendingKeySet() {
+        NavigableMap map = dmap5();
+        Set s = map.keySet();
+        assertEquals(5, s.size());
+        assertTrue(s.contains(m1));
+        assertTrue(s.contains(m2));
+        assertTrue(s.contains(m3));
+        assertTrue(s.contains(m4));
+        assertTrue(s.contains(m5));
+    }
+
+    /**
+     * keySet is ordered
+     */
+    public void testDescendingKeySetOrder() {
+        NavigableMap map = dmap5();
+        Set s = map.keySet();
+        Iterator i = s.iterator();
+        Integer last = (Integer)i.next();
+        assertEquals(last, m1);
+        while (i.hasNext()) {
+            Integer k = (Integer)i.next();
+            assertTrue(last.compareTo(k) > 0);
+            last = k;
+        }
+    }
+
+    /**
+     * values collection contains all values
+     */
+    public void testDescendingValues() {
+        NavigableMap map = dmap5();
+        Collection s = map.values();
+        assertEquals(5, s.size());
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * keySet.toArray returns contains all keys
+     */
+    public void testDescendingAscendingKeySetToArray() {
+        NavigableMap map = dmap5();
+        Set s = map.keySet();
+        Object[] ar = s.toArray();
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        assertEquals(5, ar.length);
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * descendingkeySet.toArray returns contains all keys
+     */
+    public void testDescendingDescendingKeySetToArray() {
+        NavigableMap map = dmap5();
+        Set s = map.descendingKeySet();
+        Object[] ar = s.toArray();
+        assertEquals(5, ar.length);
+        assertTrue(s.containsAll(Arrays.asList(ar)));
+        ar[0] = m10;
+        assertFalse(s.containsAll(Arrays.asList(ar)));
+    }
+
+    /**
+     * Values.toArray contains all values
+     */
+    public void testDescendingValuesToArray() {
+        NavigableMap map = dmap5();
+        Collection v = map.values();
+        Object[] ar = v.toArray();
+        ArrayList s = new ArrayList(Arrays.asList(ar));
+        assertEquals(5, ar.length);
+        assertTrue(s.contains("A"));
+        assertTrue(s.contains("B"));
+        assertTrue(s.contains("C"));
+        assertTrue(s.contains("D"));
+        assertTrue(s.contains("E"));
+    }
+
+    /**
+     * entrySet contains all pairs
+     */
+    public void testDescendingEntrySet() {
+        NavigableMap map = dmap5();
+        Set s = map.entrySet();
+        assertEquals(5, s.size());
+        Iterator it = s.iterator();
+        while (it.hasNext()) {
+            Map.Entry e = (Map.Entry) it.next();
+            assertTrue(
+                       (e.getKey().equals(m1) && e.getValue().equals("A")) ||
+                       (e.getKey().equals(m2) && e.getValue().equals("B")) ||
+                       (e.getKey().equals(m3) && e.getValue().equals("C")) ||
+                       (e.getKey().equals(m4) && e.getValue().equals("D")) ||
+                       (e.getKey().equals(m5) && e.getValue().equals("E")));
+        }
+    }
+
+    /**
+     * putAll adds all key-value pairs from the given map
+     */
+    public void testDescendingPutAll() {
+        NavigableMap empty = dmap0();
+        NavigableMap map = dmap5();
+        empty.putAll(map);
+        assertEquals(5, empty.size());
+        assertTrue(empty.containsKey(m1));
+        assertTrue(empty.containsKey(m2));
+        assertTrue(empty.containsKey(m3));
+        assertTrue(empty.containsKey(m4));
+        assertTrue(empty.containsKey(m5));
+    }
+
+    /**
+     * remove removes the correct key-value pair from the map
+     */
+    public void testDescendingRemove() {
+        NavigableMap map = dmap5();
+        map.remove(m5);
+        assertEquals(4, map.size());
+        assertFalse(map.containsKey(m5));
+    }
+
+    /**
+     * lowerEntry returns preceding entry.
+     */
+    public void testDescendingLowerEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e1 = map.lowerEntry(m3);
+        assertEquals(m2, e1.getKey());
+
+        Map.Entry e2 = map.lowerEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.lowerEntry(m1);
+        assertNull(e3);
+
+        Map.Entry e4 = map.lowerEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higherEntry returns next entry.
+     */
+    public void testDescendingHigherEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e1 = map.higherEntry(m3);
+        assertEquals(m4, e1.getKey());
+
+        Map.Entry e2 = map.higherEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.higherEntry(m5);
+        assertNull(e3);
+
+        Map.Entry e4 = map.higherEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floorEntry returns preceding entry.
+     */
+    public void testDescendingFloorEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e1 = map.floorEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.floorEntry(m6);
+        assertEquals(m5, e2.getKey());
+
+        Map.Entry e3 = map.floorEntry(m1);
+        assertEquals(m1, e3.getKey());
+
+        Map.Entry e4 = map.floorEntry(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceilingEntry returns next entry.
+     */
+    public void testDescendingCeilingEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e1 = map.ceilingEntry(m3);
+        assertEquals(m3, e1.getKey());
+
+        Map.Entry e2 = map.ceilingEntry(zero);
+        assertEquals(m1, e2.getKey());
+
+        Map.Entry e3 = map.ceilingEntry(m5);
+        assertEquals(m5, e3.getKey());
+
+        Map.Entry e4 = map.ceilingEntry(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * pollFirstEntry returns entries in order
+     */
+    public void testDescendingPollFirstEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m2, e.getKey());
+        map.put(m1, "A");
+        e = map.pollFirstEntry();
+        assertEquals(m1, e.getKey());
+        assertEquals("A", e.getValue());
+        e = map.pollFirstEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m4);
+        e = map.pollFirstEntry();
+        assertEquals(m5, e.getKey());
+        try {
+            e.setValue("A");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollFirstEntry();
+        assertNull(e);
+    }
+
+    /**
+     * pollLastEntry returns entries in order
+     */
+    public void testDescendingPollLastEntry() {
+        NavigableMap map = dmap5();
+        Map.Entry e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m4, e.getKey());
+        map.put(m5, "E");
+        e = map.pollLastEntry();
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        e = map.pollLastEntry();
+        assertEquals(m3, e.getKey());
+        map.remove(m2);
+        e = map.pollLastEntry();
+        assertEquals(m1, e.getKey());
+        try {
+            e.setValue("E");
+            shouldThrow();
+        } catch (UnsupportedOperationException success) {}
+        e = map.pollLastEntry();
+        assertNull(e);
+    }
+
+    /**
+     * size returns the correct values
+     */
+    public void testDescendingSize() {
+        NavigableMap map = dmap5();
+        NavigableMap empty = dmap0();
+        assertEquals(0, empty.size());
+        assertEquals(5, map.size());
+    }
+
+    /**
+     * toString contains toString of elements
+     */
+    public void testDescendingToString() {
+        NavigableMap map = dmap5();
+        String s = map.toString();
+        for (int i = 1; i <= 5; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    // Exception testDescendings
+
+    /**
+     * get(null) of nonempty map throws NPE
+     */
+    public void testDescendingGet_NullPointerException() {
+        NavigableMap c = dmap5();
+        try {
+            c.get(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * put(null,x) throws NPE
+     */
+    public void testDescendingPut1_NullPointerException() {
+        NavigableMap c = dmap5();
+        try {
+            c.put(null, "whatever");
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * A deserialized map equals original
+     */
+    public void testDescendingSerialization() throws Exception {
+        NavigableMap x = dmap5();
+        NavigableMap y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+    /**
+     * subMap returns map with keys in requested range
+     */
+    public void testDescendingSubMapContents() {
+        NavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m4);
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals(2, sm.size());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.firstKey());
+        assertEquals(m3, sm.lastKey());
+        assertEquals("C", sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, map.size());
+    }
+
+    public void testDescendingSubMapContents2() {
+        NavigableMap map = dmap5();
+        SortedMap sm = map.subMap(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.firstKey());
+        assertEquals(m2, sm.lastKey());
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertFalse(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.keySet().iterator();
+        j.next();
+        j.remove();
+        assertFalse(map.containsKey(m2));
+        assertEquals(4, map.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertSame(sm.remove(m3), null);
+        assertEquals(4, map.size());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingHeadMapContents() {
+        NavigableMap map = dmap5();
+        SortedMap sm = map.headMap(m4);
+        assertTrue(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertFalse(sm.containsKey(m4));
+        assertFalse(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, map.size());
+        assertEquals(m4, map.firstKey());
+    }
+
+    /**
+     * headMap returns map with keys in requested range
+     */
+    public void testDescendingTailMapContents() {
+        NavigableMap map = dmap5();
+        SortedMap sm = map.tailMap(m2);
+        assertFalse(sm.containsKey(m1));
+        assertTrue(sm.containsKey(m2));
+        assertTrue(sm.containsKey(m3));
+        assertTrue(sm.containsKey(m4));
+        assertTrue(sm.containsKey(m5));
+        Iterator i = sm.keySet().iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        Iterator ei = sm.entrySet().iterator();
+        Map.Entry e;
+        e = (Map.Entry)(ei.next());
+        assertEquals(m2, e.getKey());
+        assertEquals("B", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m3, e.getKey());
+        assertEquals("C", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m4, e.getKey());
+        assertEquals("D", e.getValue());
+        e = (Map.Entry)(ei.next());
+        assertEquals(m5, e.getKey());
+        assertEquals("E", e.getValue());
+        assertFalse(i.hasNext());
+
+        SortedMap ssm = sm.tailMap(m4);
+        assertEquals(m4, ssm.firstKey());
+        assertEquals(m5, ssm.lastKey());
+        assertEquals("D", ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, map.size());
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/TreeSubSetTest.java b/ojluni/src/test/java/util/concurrent/tck/TreeSubSetTest.java
new file mode 100644
index 0000000..8b4dddf
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/TreeSubSetTest.java
@@ -0,0 +1,1140 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 test.java.util.concurrent.tck;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class TreeSubSetTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+    public static Test suite() {
+        return new TestSuite(TreeSubSetTest.class);
+    }
+
+    static class MyReverseComparator implements Comparator {
+        public int compare(Object x, Object y) {
+            return ((Comparable)y).compareTo(x);
+        }
+    }
+
+    /**
+     * Returns a new set of given size containing consecutive
+     * Integers 0 ... n - 1.
+     */
+    private NavigableSet<Integer> populatedSet(int n) {
+        TreeSet<Integer> q = new TreeSet<>();
+        assertTrue(q.isEmpty());
+
+        for (int i = n - 1; i >= 0; i -= 2)
+            assertTrue(q.add(new Integer(i)));
+        for (int i = (n & 1); i < n; i += 2)
+            assertTrue(q.add(new Integer(i)));
+        assertTrue(q.add(new Integer(-n)));
+        assertTrue(q.add(new Integer(n)));
+        NavigableSet s = q.subSet(new Integer(0), true, new Integer(n), false);
+        assertFalse(s.isEmpty());
+        assertEquals(n, s.size());
+        return s;
+    }
+
+    /**
+     * Returns a new set of first 5 ints.
+     */
+    private NavigableSet set5() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.isEmpty());
+        q.add(one);
+        q.add(two);
+        q.add(three);
+        q.add(four);
+        q.add(five);
+        q.add(zero);
+        q.add(seven);
+        NavigableSet s = q.subSet(one, true, seven, false);
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    private NavigableSet dset5() {
+        TreeSet q = new TreeSet();
+        assertTrue(q.isEmpty());
+        q.add(m1);
+        q.add(m2);
+        q.add(m3);
+        q.add(m4);
+        q.add(m5);
+        NavigableSet s = q.descendingSet();
+        assertEquals(5, s.size());
+        return s;
+    }
+
+    private static NavigableSet set0() {
+        TreeSet set = new TreeSet();
+        assertTrue(set.isEmpty());
+        return set.tailSet(m1, false);
+    }
+
+    private static NavigableSet dset0() {
+        TreeSet set = new TreeSet();
+        assertTrue(set.isEmpty());
+        return set;
+    }
+
+    /**
+     * A new set has unbounded capacity
+     */
+    public void testConstructor1() {
+        assertEquals(0, set0().size());
+    }
+
+    /**
+     * isEmpty is true before add, false after
+     */
+    public void testEmpty() {
+        NavigableSet q = set0();
+        assertTrue(q.isEmpty());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        assertTrue(q.add(new Integer(2)));
+        q.pollFirst();
+        q.pollFirst();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * add(null) throws NPE
+     */
+    public void testAddNull() {
+        NavigableSet q = set0();
+        try {
+            q.add(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testAdd() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testAddDup() {
+        NavigableSet q = set0();
+        assertTrue(q.add(six));
+        assertFalse(q.add(six));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testAddNonComparable() {
+        NavigableSet q = set0();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testAddAll1() {
+        NavigableSet q = set0();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testAddAll2() {
+        NavigableSet q = set0();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testAddAll3() {
+        NavigableSet q = set0();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        NavigableSet q = set0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertTrue(q.contains(i - 1));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.contains(i));
+            assertTrue(q.remove(i));
+            assertFalse(q.contains(i));
+            assertFalse(q.remove(i + 1));
+            assertFalse(q.contains(i + 1));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = set0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testLower() {
+        NavigableSet q = set5();
+        Object e1 = q.lower(three);
+        assertEquals(two, e1);
+
+        Object e2 = q.lower(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.lower(one);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testHigher() {
+        NavigableSet q = set5();
+        Object e1 = q.higher(three);
+        assertEquals(four, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.higher(five);
+        assertNull(e3);
+
+        Object e4 = q.higher(six);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testFloor() {
+        NavigableSet q = set5();
+        Object e1 = q.floor(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.floor(six);
+        assertEquals(five, e2);
+
+        Object e3 = q.floor(one);
+        assertEquals(one, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testCeiling() {
+        NavigableSet q = set5();
+        Object e1 = q.ceiling(three);
+        assertEquals(three, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(one, e2);
+
+        Object e3 = q.ceiling(five);
+        assertEquals(five, e3);
+
+        Object e4 = q.ceiling(six);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements in sorted order
+     */
+    public void testToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        for (int i = 0; i < o.length; i++)
+            assertSame(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements in sorted order
+     */
+    public void testToArray2() {
+        NavigableSet<Integer> q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        Integer[] array = q.toArray(ints);
+        assertSame(ints, array);
+        for (int i = 0; i < ints.length; i++)
+            assertSame(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        Iterator it = q.iterator();
+        int i;
+        for (i = 0; it.hasNext(); i++)
+            assertTrue(q.contains(it.next()));
+        assertEquals(i, SIZE);
+        assertIteratorExhausted(it);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testEmptyIterator() {
+        assertIteratorExhausted(set0().iterator());
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testIteratorRemove() {
+        final NavigableSet q = set0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(2, it.next());
+        assertEquals(3, it.next());
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testSerialization() throws Exception {
+        NavigableSet x = populatedSet(SIZE);
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testSubSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, four);
+        assertEquals(two, sm.first());
+        assertEquals(three, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(three, sm.first());
+        assertEquals(three, sm.last());
+        assertTrue(sm.remove(three));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testSubSetContents2() {
+        NavigableSet set = set5();
+        SortedSet sm = set.subSet(two, three);
+        assertEquals(1, sm.size());
+        assertEquals(two, sm.first());
+        assertEquals(two, sm.last());
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertFalse(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(two));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(three));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testHeadSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.headSet(four);
+        assertTrue(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertFalse(sm.contains(four));
+        assertFalse(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(one, k);
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(four, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testTailSetContents() {
+        NavigableSet set = set5();
+        SortedSet sm = set.tailSet(two);
+        assertFalse(sm.contains(one));
+        assertTrue(sm.contains(two));
+        assertTrue(sm.contains(three));
+        assertTrue(sm.contains(four));
+        assertTrue(sm.contains(five));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(two, k);
+        k = (Integer)(i.next());
+        assertEquals(three, k);
+        k = (Integer)(i.next());
+        assertEquals(four, k);
+        k = (Integer)(i.next());
+        assertEquals(five, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(four);
+        assertEquals(four, ssm.first());
+        assertEquals(five, ssm.last());
+        assertTrue(ssm.remove(four));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * size changes when elements added and removed
+     */
+    public void testDescendingSize() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(SIZE - i, q.size());
+            q.pollFirst();
+        }
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.size());
+            q.add(new Integer(i));
+        }
+    }
+
+    /**
+     * Add of comparable element succeeds
+     */
+    public void testDescendingAdd() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+    }
+
+    /**
+     * Add of duplicate element fails
+     */
+    public void testDescendingAddDup() {
+        NavigableSet q = dset0();
+        assertTrue(q.add(m6));
+        assertFalse(q.add(m6));
+    }
+
+    /**
+     * Add of non-Comparable throws CCE
+     */
+    public void testDescendingAddNonComparable() {
+        NavigableSet q = dset0();
+        try {
+            q.add(new Object());
+            q.add(new Object());
+            shouldThrow();
+        } catch (ClassCastException success) {}
+    }
+
+    /**
+     * addAll(null) throws NPE
+     */
+    public void testDescendingAddAll1() {
+        NavigableSet q = dset0();
+        try {
+            q.addAll(null);
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with null elements throws NPE
+     */
+    public void testDescendingAddAll2() {
+        NavigableSet q = dset0();
+        Integer[] ints = new Integer[SIZE];
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * addAll of a collection with any null elements throws NPE after
+     * possibly adding some elements
+     */
+    public void testDescendingAddAll3() {
+        NavigableSet q = dset0();
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE - 1; ++i)
+            ints[i] = new Integer(i + SIZE);
+        try {
+            q.addAll(Arrays.asList(ints));
+            shouldThrow();
+        } catch (NullPointerException success) {}
+    }
+
+    /**
+     * Set contains all elements of successful addAll
+     */
+    public void testDescendingAddAll5() {
+        Integer[] empty = new Integer[0];
+        Integer[] ints = new Integer[SIZE];
+        for (int i = 0; i < SIZE; ++i)
+            ints[i] = new Integer(SIZE - 1 - i);
+        NavigableSet q = dset0();
+        assertFalse(q.addAll(Arrays.asList(empty)));
+        assertTrue(q.addAll(Arrays.asList(ints)));
+        for (int i = 0; i < SIZE; ++i)
+            assertEquals(new Integer(i), q.pollFirst());
+    }
+
+    /**
+     * poll succeeds unless empty
+     */
+    public void testDescendingPoll() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertEquals(i, q.pollFirst());
+        }
+        assertNull(q.pollFirst());
+    }
+
+    /**
+     * remove(x) removes x and returns true if present
+     */
+    public void testDescendingRemoveElement() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 1; i < SIZE; i += 2) {
+            assertTrue(q.remove(new Integer(i)));
+        }
+        for (int i = 0; i < SIZE; i += 2) {
+            assertTrue(q.remove(new Integer(i)));
+            assertFalse(q.remove(new Integer(i + 1)));
+        }
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * contains(x) reports true when elements added but not yet removed
+     */
+    public void testDescendingContains() {
+        NavigableSet q = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.contains(new Integer(i)));
+            q.pollFirst();
+            assertFalse(q.contains(new Integer(i)));
+        }
+    }
+
+    /**
+     * clear removes all elements
+     */
+    public void testDescendingClear() {
+        NavigableSet q = populatedSet(SIZE);
+        q.clear();
+        assertTrue(q.isEmpty());
+        assertEquals(0, q.size());
+        assertTrue(q.add(new Integer(1)));
+        assertFalse(q.isEmpty());
+        q.clear();
+        assertTrue(q.isEmpty());
+    }
+
+    /**
+     * containsAll(c) is true when c contains a subset of elements
+     */
+    public void testDescendingContainsAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = dset0();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(q.containsAll(p));
+            assertFalse(p.containsAll(q));
+            p.add(new Integer(i));
+        }
+        assertTrue(p.containsAll(q));
+    }
+
+    /**
+     * retainAll(c) retains only those elements of c and reports true if changed
+     */
+    public void testDescendingRetainAll() {
+        NavigableSet q = populatedSet(SIZE);
+        NavigableSet p = populatedSet(SIZE);
+        for (int i = 0; i < SIZE; ++i) {
+            boolean changed = q.retainAll(p);
+            if (i == 0)
+                assertFalse(changed);
+            else
+                assertTrue(changed);
+
+            assertTrue(q.containsAll(p));
+            assertEquals(SIZE - i, q.size());
+            p.pollFirst();
+        }
+    }
+
+    /**
+     * removeAll(c) removes only those elements of c and reports true if changed
+     */
+    public void testDescendingRemoveAll() {
+        for (int i = 1; i < SIZE; ++i) {
+            NavigableSet q = populatedSet(SIZE);
+            NavigableSet p = populatedSet(i);
+            assertTrue(q.removeAll(p));
+            assertEquals(SIZE - i, q.size());
+            for (int j = 0; j < i; ++j) {
+                Integer x = (Integer)(p.pollFirst());
+                assertFalse(q.contains(x));
+            }
+        }
+    }
+
+    /**
+     * lower returns preceding element
+     */
+    public void testDescendingLower() {
+        NavigableSet q = dset5();
+        Object e1 = q.lower(m3);
+        assertEquals(m2, e1);
+
+        Object e2 = q.lower(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.lower(m1);
+        assertNull(e3);
+
+        Object e4 = q.lower(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * higher returns next element
+     */
+    public void testDescendingHigher() {
+        NavigableSet q = dset5();
+        Object e1 = q.higher(m3);
+        assertEquals(m4, e1);
+
+        Object e2 = q.higher(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.higher(m5);
+        assertNull(e3);
+
+        Object e4 = q.higher(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * floor returns preceding element
+     */
+    public void testDescendingFloor() {
+        NavigableSet q = dset5();
+        Object e1 = q.floor(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.floor(m6);
+        assertEquals(m5, e2);
+
+        Object e3 = q.floor(m1);
+        assertEquals(m1, e3);
+
+        Object e4 = q.floor(zero);
+        assertNull(e4);
+    }
+
+    /**
+     * ceiling returns next element
+     */
+    public void testDescendingCeiling() {
+        NavigableSet q = dset5();
+        Object e1 = q.ceiling(m3);
+        assertEquals(m3, e1);
+
+        Object e2 = q.ceiling(zero);
+        assertEquals(m1, e2);
+
+        Object e3 = q.ceiling(m5);
+        assertEquals(m5, e3);
+
+        Object e4 = q.ceiling(m6);
+        assertNull(e4);
+    }
+
+    /**
+     * toArray contains all elements
+     */
+    public void testDescendingToArray() {
+        NavigableSet q = populatedSet(SIZE);
+        Object[] o = q.toArray();
+        Arrays.sort(o);
+        for (int i = 0; i < o.length; i++)
+            assertEquals(o[i], q.pollFirst());
+    }
+
+    /**
+     * toArray(a) contains all elements
+     */
+    public void testDescendingToArray2() {
+        NavigableSet q = populatedSet(SIZE);
+        Integer[] ints = new Integer[SIZE];
+        assertSame(ints, q.toArray(ints));
+        Arrays.sort(ints);
+        for (int i = 0; i < ints.length; i++)
+            assertEquals(ints[i], q.pollFirst());
+    }
+
+    /**
+     * iterator iterates through all elements
+     */
+    public void testDescendingIterator() {
+        NavigableSet q = populatedSet(SIZE);
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(i, SIZE);
+    }
+
+    /**
+     * iterator of empty set has no elements
+     */
+    public void testDescendingEmptyIterator() {
+        NavigableSet q = dset0();
+        int i = 0;
+        Iterator it = q.iterator();
+        while (it.hasNext()) {
+            assertTrue(q.contains(it.next()));
+            ++i;
+        }
+        assertEquals(0, i);
+    }
+
+    /**
+     * iterator.remove removes current element
+     */
+    public void testDescendingIteratorRemove() {
+        final NavigableSet q = dset0();
+        q.add(new Integer(2));
+        q.add(new Integer(1));
+        q.add(new Integer(3));
+
+        Iterator it = q.iterator();
+        it.next();
+        it.remove();
+
+        it = q.iterator();
+        assertEquals(2, it.next());
+        assertEquals(3, it.next());
+        assertFalse(it.hasNext());
+    }
+
+    /**
+     * toString contains toStrings of elements
+     */
+    public void testDescendingToString() {
+        NavigableSet q = populatedSet(SIZE);
+        String s = q.toString();
+        for (int i = 0; i < SIZE; ++i) {
+            assertTrue(s.contains(String.valueOf(i)));
+        }
+    }
+
+    /**
+     * A deserialized serialized set has same elements
+     */
+    public void testDescendingSerialization() throws Exception {
+        NavigableSet x = dset5();
+        NavigableSet y = serialClone(x);
+
+        assertNotSame(x, y);
+        assertEquals(x.size(), y.size());
+        assertEquals(x.toString(), y.toString());
+        assertEquals(x, y);
+        assertEquals(y, x);
+        while (!x.isEmpty()) {
+            assertFalse(y.isEmpty());
+            assertEquals(x.pollFirst(), y.pollFirst());
+        }
+        assertTrue(y.isEmpty());
+    }
+
+    /**
+     * subSet returns set with keys in requested range
+     */
+    public void testDescendingSubSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m4);
+        assertEquals(m2, sm.first());
+        assertEquals(m3, sm.last());
+        assertEquals(2, sm.size());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(1, sm.size());
+        assertEquals(m3, sm.first());
+        assertEquals(m3, sm.last());
+        assertTrue(sm.remove(m3));
+        assertTrue(sm.isEmpty());
+        assertEquals(3, set.size());
+    }
+
+    public void testDescendingSubSetContents2() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.subSet(m2, m3);
+        assertEquals(1, sm.size());
+        assertEquals(m2, sm.first());
+        assertEquals(m2, sm.last());
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertFalse(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        assertFalse(i.hasNext());
+        Iterator j = sm.iterator();
+        j.next();
+        j.remove();
+        assertFalse(set.contains(m2));
+        assertEquals(4, set.size());
+        assertEquals(0, sm.size());
+        assertTrue(sm.isEmpty());
+        assertFalse(sm.remove(m3));
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * headSet returns set with keys in requested range
+     */
+    public void testDescendingHeadSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.headSet(m4);
+        assertTrue(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertFalse(sm.contains(m4));
+        assertFalse(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m1, k);
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        assertFalse(i.hasNext());
+        sm.clear();
+        assertTrue(sm.isEmpty());
+        assertEquals(2, set.size());
+        assertEquals(m4, set.first());
+    }
+
+    /**
+     * tailSet returns set with keys in requested range
+     */
+    public void testDescendingTailSetContents() {
+        NavigableSet set = dset5();
+        SortedSet sm = set.tailSet(m2);
+        assertFalse(sm.contains(m1));
+        assertTrue(sm.contains(m2));
+        assertTrue(sm.contains(m3));
+        assertTrue(sm.contains(m4));
+        assertTrue(sm.contains(m5));
+        Iterator i = sm.iterator();
+        Object k;
+        k = (Integer)(i.next());
+        assertEquals(m2, k);
+        k = (Integer)(i.next());
+        assertEquals(m3, k);
+        k = (Integer)(i.next());
+        assertEquals(m4, k);
+        k = (Integer)(i.next());
+        assertEquals(m5, k);
+        assertFalse(i.hasNext());
+
+        SortedSet ssm = sm.tailSet(m4);
+        assertEquals(m4, ssm.first());
+        assertEquals(m5, ssm.last());
+        assertTrue(ssm.remove(m4));
+        assertEquals(1, ssm.size());
+        assertEquals(3, sm.size());
+        assertEquals(4, set.size());
+    }
+
+    /**
+     * addAll is idempotent
+     */
+    public void testAddAll_idempotent() throws Exception {
+        Set x = populatedSet(SIZE);
+        Set y = new TreeSet(x);
+        y.addAll(x);
+        assertEquals(x, y);
+        assertEquals(y, x);
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/VectorTest.java b/ojluni/src/test/java/util/concurrent/tck/VectorTest.java
new file mode 100644
index 0000000..4100843
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/VectorTest.java
@@ -0,0 +1,86 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * 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 Martin Buchholz 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 test.java.util.concurrent.tck;
+import java.util.Vector;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+public class VectorTest extends JSR166TestCase {
+    public static void main(String[] args) {
+        main(suite(), args);
+    }
+
+    public static Test suite() {
+        class Implementation implements CollectionImplementation {
+            public Class<?> klazz() { return Vector.class; }
+            public List emptyCollection() { return new Vector(); }
+            public Object makeElement(int i) { return i; }
+            public boolean isConcurrent() { return false; }
+            public boolean permitsNulls() { return true; }
+        }
+        class SubListImplementation extends Implementation {
+            public List emptyCollection() {
+                return super.emptyCollection().subList(0, 0);
+            }
+        }
+        return newTestSuite(
+                VectorTest.class,
+                CollectionTest.testSuite(new Implementation()),
+                CollectionTest.testSuite(new SubListImplementation()));
+    }
+
+    /**
+     * tests for setSize()
+     */
+    public void testSetSize() {
+        final Vector v = new Vector();
+        for (int n : new int[] { 100, 5, 50 }) {
+            v.setSize(n);
+            assertEquals(n, v.size());
+            assertNull(v.get(0));
+            assertNull(v.get(n - 1));
+            assertThrows(
+                    ArrayIndexOutOfBoundsException.class,
+                    new Runnable() { public void run() { v.setSize(-1); }});
+            assertEquals(n, v.size());
+            assertNull(v.get(0));
+            assertNull(v.get(n - 1));
+        }
+    }
+
+}
diff --git a/ojluni/src/test/java/util/concurrent/tck/tck.policy b/ojluni/src/test/java/util/concurrent/tck/tck.policy
new file mode 100644
index 0000000..5816ab3
--- /dev/null
+++ b/ojluni/src/test/java/util/concurrent/tck/tck.policy
@@ -0,0 +1,15 @@
+grant {
+    // Permissions j.u.c. needs directly
+    permission java.lang.RuntimePermission "modifyThread";
+    permission java.lang.RuntimePermission "getClassLoader";
+    permission java.lang.RuntimePermission "setContextClassLoader";
+    permission java.util.PropertyPermission "*", "read";
+    // Permissions needed to change permissions!
+    permission java.security.SecurityPermission "getPolicy";
+    permission java.security.SecurityPermission "setPolicy";
+    permission java.security.SecurityPermission "setSecurityManager";
+    // Permissions needed by the junit test harness
+    permission java.lang.RuntimePermission "accessDeclaredMembers";
+    permission java.io.FilePermission "<<ALL FILES>>", "read";
+    permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
+};
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml b/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml
new file mode 100644
index 0000000..bc916a9
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/SecureProcessingTest.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0"?>
+<helloWorld/>
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java b/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java
new file mode 100644
index 0000000..77fdccb
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/TestBase.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+// Android-changed: Added package
+package test.javax.xml.jaxp.transform;
+
+import java.security.Policy;
+
+/**
+ *
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class TestBase {
+    public static boolean isWindows = false;
+    static {
+        if (System.getProperty("os.name").indexOf("Windows")>-1) {
+            isWindows = true;
+        }
+    };
+
+    String filepath;
+    boolean hasSM;
+    String curDir;
+    Policy origPolicy;
+    String testName;
+    static String errMessage;
+
+    int passed = 0, failed = 0;
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public TestBase(String name) {
+        testName = name;
+    }
+
+    //junit @Override
+    protected void setUp() {
+        if (System.getSecurityManager() != null) {
+            hasSM = true;
+            System.setSecurityManager(null);
+        }
+
+        filepath = System.getProperty("test.src");
+        if (filepath == null) {
+            //current directory
+            filepath = System.getProperty("user.dir");
+        }
+        origPolicy = Policy.getPolicy();
+
+    }
+
+    //junit @Override
+    public void tearDown() {
+        // turn off security manager and restore policy
+        System.setSecurityManager(null);
+        Policy.setPolicy(origPolicy);
+        if (hasSM) {
+            System.setSecurityManager(new SecurityManager());
+        }
+        System.out.println("\nNumber of tests passed: " + passed);
+        System.out.println("Number of tests failed: " + failed + "\n");
+
+        if (errMessage != null ) {
+            throw new RuntimeException(errMessage);
+        }
+    }
+
+    void fail(String errMsg) {
+        if (errMessage == null) {
+            errMessage = errMsg;
+        } else {
+            errMessage = errMessage + "\n" + errMsg;
+        }
+        failed++;
+    }
+
+    void success(String msg) {
+        passed++;
+        System.out.println(msg);
+    }
+
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java
new file mode 100644
index 0000000..637fb8e
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XPathExFuncTest.java
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * @test
+ * @bug 8004476
+ * @summary test XPath extension functions
+ * @run main/othervm XPathExFuncTest
+ */
+// Android-changed: Added package & Test import
+package test.javax.xml.jaxp.transform;
+import org.testng.annotations.Test;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import java.util.Iterator;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+import javax.xml.xpath.XPathFactoryConfigurationException;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+import javax.xml.xpath.XPathFunctionResolver;
+import org.w3c.dom.Document;
+
+/**
+ * test XPath extension functions
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class XPathExFuncTest extends TestBase {
+
+    final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions";
+    final static String CLASSNAME = "DocumentBuilderFactoryImpl";
+    final String XPATH_EXPRESSION = "ext:helloWorld()";
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public XPathExFuncTest(String name) {
+        super(name);
+    }
+    boolean hasSM;
+    // Android-changed: Load the files from java resources.
+    // String xslFile, xslFileId;
+    // String xmlFile, xmlFileId;
+    InputStream xmlStream;
+
+    protected void setUp() {
+        super.setUp();
+        // Android-changed: Load the files from java resources.
+        // xmlFile = filepath + "/SecureProcessingTest.xml";
+        xmlStream = XPathExFuncTest.class.getResourceAsStream("SecureProcessingTest.xml");
+
+    }
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        XPathExFuncTest test = new XPathExFuncTest("OneTest");
+        test.setUp();
+
+        test.testExtFunc();
+        // Android-removed: Android doesn't allow setting a SecurityManager.
+        // test.testExtFuncNotAllowed();
+        // Android-added: Call setUp() before each test
+        test.setUp();
+        test.testEnableExtFunc();
+        test.tearDown();
+
+    }
+
+    /**
+     * by default, extension function is enabled
+     */
+    public void testExtFunc() {
+
+        try {
+            evaluate(false);
+            System.out.println("testExtFunc: OK");
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    /**
+     * Security is enabled, extension function not allowed
+     */
+    public void testExtFuncNotAllowed() {
+         Policy p = new SimplePolicy(new AllPermission());
+         Policy.setPolicy(p);
+         System.setSecurityManager(new SecurityManager());
+
+        try {
+            evaluate(false);
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException ex) {
+            //expected since extension function is disallowed
+            System.out.println("testExtFuncNotAllowed: OK");
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions
+     */
+    public void testEnableExtFunc() {
+        // Android-removed: Android doesn't use SecurityManager.
+        // Policy p = new SimplePolicy(new AllPermission());
+        // Policy.setPolicy(p);
+        // System.setSecurityManager(new SecurityManager());
+
+
+        try {
+            evaluate(true);
+            System.out.println("testEnableExt: OK");
+        } catch (XPathFactoryConfigurationException e) {
+            fail(e.getMessage());
+        } catch (XPathExpressionException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    Document getDocument() {
+        // the xml source
+        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+        DocumentBuilder documentBuilder = null;
+        Document document = null;
+
+        try {
+            documentBuilder = documentBuilderFactory.newDocumentBuilder();
+            // Android-changed: Load the xml file from java resources.
+            // InputStream xmlStream = new FileInputStream(xmlFile);
+            InputStream xmlStream = this.xmlStream; // new FileInputStream(xmlFile);
+            document = documentBuilder.parse(xmlStream);
+        } catch (Exception e) {
+            fail(e.toString());
+        }
+        return document;
+    }
+
+    void evaluate(boolean enableExt) throws XPathFactoryConfigurationException, XPathExpressionException {
+        Document document = getDocument();
+
+        XPathFactory xPathFactory = XPathFactory.newInstance();
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        if (enableExt) {
+            boolean isExtensionSupported = enableExtensionFunction(xPathFactory);
+        }
+
+        xPathFactory.setXPathFunctionResolver(new MyXPathFunctionResolver());
+        if (System.getSecurityManager() == null) {
+            xPathFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false);
+        }
+
+        XPath xPath = xPathFactory.newXPath();
+        xPath.setNamespaceContext(new MyNamespaceContext());
+
+        String xPathResult = xPath.evaluate(XPATH_EXPRESSION, document);
+        System.out.println(
+                "XPath result (enableExtensionFunction == " + enableExt + ") = \""
+                + xPathResult
+                + "\"");
+    }
+
+    public class MyXPathFunctionResolver
+            implements XPathFunctionResolver {
+
+        public XPathFunction resolveFunction(QName functionName, int arity) {
+
+            // not a real ewsolver, always return a default XPathFunction
+            return new MyXPathFunction();
+        }
+    }
+
+    public class MyXPathFunction
+            implements XPathFunction {
+
+        public Object evaluate(List list) throws XPathFunctionException {
+
+            return "Hello World";
+        }
+    }
+
+    public class MyNamespaceContext implements NamespaceContext {
+
+        public String getNamespaceURI(String prefix) {
+            if (prefix == null) {
+                throw new IllegalArgumentException("The prefix cannot be null.");
+            }
+
+            if (prefix.equals("ext")) {
+                return "http://ext.com";
+            } else {
+                return null;
+            }
+        }
+
+        public String getPrefix(String namespace) {
+
+            if (namespace == null) {
+                throw new IllegalArgumentException("The namespace uri cannot be null.");
+            }
+
+            if (namespace.equals("http://ext.com")) {
+                return "ext";
+            } else {
+                return null;
+            }
+        }
+
+        public Iterator getPrefixes(String namespace) {
+            return null;
+        }
+    }
+
+    boolean enableExtensionFunction(XPathFactory factory) {
+        boolean isSupported = true;
+        try {
+            factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true);
+        } catch (XPathFactoryConfigurationException ex) {
+            isSupported = false;
+        }
+        return isSupported;
+    }
+
+    class SimplePolicy extends Policy {
+
+        private final Permissions perms;
+
+        public SimplePolicy(Permission... permissions) {
+            perms = new Permissions();
+            for (Permission permission : permissions) {
+                perms.add(permission);
+            }
+        }
+
+        @Override
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain pd, Permission p) {
+            return perms.implies(p);
+        }
+
+        //for older jdk
+        @Override
+        public void refresh() {
+        }
+    }
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java
new file mode 100644
index 0000000..90304d2
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XSLTExFuncTest.java
@@ -0,0 +1,265 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * @test
+ * @bug 8004476
+ * @summary test XSLT extension functions
+ * @run main/othervm XSLTExFuncTest
+ */
+// Android-changed: Added package & Test import
+package test.javax.xml.jaxp.transform;
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.security.AllPermission;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Policy;
+import java.security.ProtectionDomain;
+import javax.xml.transform.*;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamResult;
+import org.xml.sax.InputSource;
+
+/**
+ * test XSLT extension functions
+ *
+ * @author huizhe.wang@oracle.com
+ */
+public class XSLTExFuncTest extends TestBase {
+
+    final static String ENABLE_EXTENSION_FUNCTIONS = "http://www.oracle.com/xml/jaxp/properties/enableExtensionFunctions";
+    final static String CLASSNAME = "DocumentBuilderFactoryImpl";
+
+    /**
+     * Creates a new instance of StreamReader
+     */
+    public XSLTExFuncTest(String name) {
+        super(name);
+    }
+    boolean hasSM;
+    // Android-changed: Load the files from java resources.
+    // String xslFile, xslFileId;
+    // String xmlFile, xmlFileId;
+    InputStream xslFile, xmlFile;
+    String xslFileId;
+
+    protected void setUp() {
+        super.setUp();
+        // Android-changed: Load the files from java resources.
+        // xmlFile = filepath + "/tokenize.xml";
+        // xslFile = filepath + "/tokenize.xsl";
+        xmlFile = XSLTExFuncTest.class.getResourceAsStream("tokenize.xml");
+        xslFile = XSLTExFuncTest.class.getResourceAsStream("tokenize.xsl");
+
+        /**
+         * On Windows platform it needs triple '/' for valid URL while double '/' is enough on Linux or Solaris.
+         * Here use file:/// directly to make it work on Windows and it will not impact other platforms.
+         */
+        // Android-changed: Load the files from java resources.
+        // xslFileId = "file:///" + xslFile;
+        xslFileId = "file:///" + filepath + "/tokenize.xsl";
+    }
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() {
+        XSLTExFuncTest test = new XSLTExFuncTest("OneTest");
+        test.setUp();
+
+        test.testExtFunc();
+        // Android-removed: Android doesn't allow setting a SecurityManager.
+        // test.testExtFuncNotAllowed();
+        // Android-added: Call setUp() before each test
+        test.setUp();
+        test.testEnableExtFunc();
+        test.setUp();
+        test.testTemplatesEnableExtFunc();
+        test.tearDown();
+
+    }
+
+    /**
+     * by default, extension function is enabled
+     */
+    public void testExtFunc() {
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        try {
+            transform(factory);
+            System.out.println("testExtFunc: OK");
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException ex) {
+            fail(ex.getMessage());
+        }
+    }
+
+    /**
+     * Security is enabled, extension function not allowed
+     */
+    public void testExtFuncNotAllowed() {
+        Policy p = new SimplePolicy(new AllPermission());
+        Policy.setPolicy(p);
+        System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        try {
+            transform(factory);
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException ex) {
+            //expected since extension function is disallowed
+            System.out.println("testExtFuncNotAllowed: OK");
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions
+     */
+    public void testEnableExtFunc() {
+        // Android-removed: Android doesn't use SecurityManager.
+        // Policy p = new SimplePolicy(new AllPermission());
+        // Policy.setPolicy(p);
+        // System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        boolean isExtensionSupported = enableExtensionFunction(factory);
+
+        try {
+            transform(factory);
+            System.out.println("testEnableExt: OK");
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    /**
+     * use Templates template = factory.newTemplates(new StreamSource( new
+     * FileInputStream(xslFilename))); // Use the template to create a
+     * transformer Transformer xformer = template.newTransformer();
+     *
+     * @param factory
+     * @return
+     */
+    /**
+     * Security is enabled, use new feature: enableExtensionFunctions Use the
+     * template to create a transformer
+     */
+    public void testTemplatesEnableExtFunc() {
+        // Android-removed: Android doesn't use SecurityManager.
+        // Policy p = new SimplePolicy(new AllPermission());
+        // Policy.setPolicy(p);
+        // System.setSecurityManager(new SecurityManager());
+        TransformerFactory factory = TransformerFactory.newInstance();
+
+        /**
+         * Use of the extension function 'http://exslt.org/strings:tokenize' is
+         * not allowed when the secure processing feature is set to true.
+         * Attempt to use the new property to enable extension function
+         */
+        boolean isExtensionSupported = enableExtensionFunction(factory);
+
+        try {
+            SAXSource xslSource = new SAXSource(new InputSource(xslFile));
+            xslSource.setSystemId(xslFileId);
+            Templates template = factory.newTemplates(xslSource);
+            Transformer transformer = template.newTransformer();
+            StringWriter stringResult = new StringWriter();
+            Result result = new StreamResult(stringResult);
+            transformer.transform(new SAXSource(new InputSource(xmlFile)), result);
+            System.out.println("testTemplatesEnableExtFunc: OK");
+        } catch (TransformerConfigurationException e) {
+            fail(e.getMessage());
+        } catch (TransformerException e) {
+            fail(e.getMessage());
+        } finally {
+            System.setSecurityManager(null);
+        }
+    }
+
+    boolean enableExtensionFunction(TransformerFactory factory) {
+        boolean isSupported = true;
+        try {
+            factory.setFeature(ENABLE_EXTENSION_FUNCTIONS, true);
+        } catch (TransformerConfigurationException ex) {
+            isSupported = false;
+        }
+        return isSupported;
+    }
+
+    void transform(TransformerFactory factory) throws TransformerConfigurationException, TransformerException {
+        SAXSource xslSource = new SAXSource(new InputSource(xslFile));
+        xslSource.setSystemId(xslFileId);
+        Transformer transformer = factory.newTransformer(xslSource);
+        StringWriter stringResult = new StringWriter();
+        Result result = new StreamResult(stringResult);
+        transformer.transform(new SAXSource(new InputSource(xmlFile)), result);
+    }
+
+    class SimplePolicy extends Policy {
+
+        private final Permissions perms;
+
+        public SimplePolicy(Permission... permissions) {
+            perms = new Permissions();
+            for (Permission permission : permissions) {
+                perms.add(permission);
+            }
+        }
+
+        @Override
+        public PermissionCollection getPermissions(CodeSource cs) {
+            return perms;
+        }
+
+        @Override
+        public PermissionCollection getPermissions(ProtectionDomain pd) {
+            return perms;
+        }
+
+        @Override
+        public boolean implies(ProtectionDomain pd, Permission p) {
+            return perms.implies(p);
+        }
+
+        //for older jdk
+        @Override
+        public void refresh() {
+        }
+    }
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java b/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java
new file mode 100644
index 0000000..a95331c
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/XslSubstringTest.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8062923 8062924 8074297 8076290
+ * @run testng XslSubstringTest
+ * @summary Test xsl substring function with negative, Inf and
+ * NaN length and few other use cases. Also test proper
+ * processing of supplementary characters by substring function.
+ */
+// Android-changed: Added package
+package test.javax.xml.jaxp.transform;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import javax.xml.transform.Source;
+import javax.xml.transform.Templates;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import static org.testng.Assert.assertEquals;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class XslSubstringTest {
+
+    final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><test></test>";
+    final String xslPre = "<xsl:stylesheet version='1.0'"
+            + " xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>"
+            + "<xsl:output method='xml' indent='yes' omit-xml-declaration='yes'/>"
+            + "<xsl:template match='/'><t>";
+    final String xslPost = "</t></xsl:template></xsl:stylesheet>";
+
+    @DataProvider(name = "GeneralTestsData")
+    private Object[][] xmls() {
+        return new Object[][] {
+            { "|<xsl:value-of select=\"substring('asdf',2, 1)\"/>|", "<t>|s|</t>"},
+            { "|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|", "<t>|sdf|</t>"},
+            { "|<xsl:value-of select=\"substring('asdf',2, -0 div 0)\"/>|", "<t>||</t>" },
+            { "|<xsl:value-of select=\"substring('asdf',2, 1 div 0)\"/>|", "<t>|sdf|</t>" },
+            // 8076290 bug test case
+            { "|<xsl:value-of select=\"substring('123', 0, 3)\"/>|", "<t>|12|</t>"},
+        };
+    }
+
+    @DataProvider(name = "SupplementaryCharactersTestData")
+    private Object[][] dataSupplementaryCharacters() {
+        return new Object[][] {
+            // 8074297 bug test cases
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3)\"/>|",    "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 1)\"/>|", "<t>|B|</t>" },
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 2, 2)\"/>|", "<t>|AB|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 2)\"/>|", "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 3, 4)\"/>|", "<t>|BC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 1, 1)\"/>|", "<t>|&#131083;|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 2, 1)\"/>|", "<t>|A|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 1, 1 div 0)\"/>|", "<t>|&#131083;ABC|</t>"},
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', -10, 1 div 0)\"/>|", "<t>|&#131083;ABC|</t>"},
+            // 8076290 bug test case
+            { "|<xsl:value-of select=\"substring('&#131083;ABC', 0, 2)\"/>|", "<t>|&#131083;|</t>"},
+        };
+    }
+
+    private String testTransform(String xsl) throws Exception {
+        //Prepare sources for transormation
+        Source src = new StreamSource(new StringReader(xml));
+        Source xslsrc = new StreamSource(new StringReader(xslPre + xsl + xslPost));
+        //Create factory, template and transformer
+        TransformerFactory tf = TransformerFactory.newInstance();
+        Templates tmpl = tf.newTemplates(xslsrc);
+        Transformer t = tmpl.newTransformer();
+        //Prepare output stream
+        StringWriter xmlResultString = new StringWriter();
+        StreamResult xmlResultStream = new StreamResult(xmlResultString);
+        //Transform
+        t.transform(src, xmlResultStream);
+        return xmlResultString.toString().trim();
+    }
+
+    @Test
+    public void test8062923() throws Exception {
+        assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1)\"/>|"),
+                // TODO(b/181173341): Rollback this patch
+                // Android-changed: Change the expected output until JDK-8062923 is fixed on Android
+                //  "<t>||</t>");
+                "<t>|</t>");
+    }
+
+    @Test
+    public void test8062924() throws Exception {
+        assertEquals(testTransform("|<xsl:value-of select=\"substring('asdf',2,-1 div 0)\"/>|"),
+                // TODO(b/181173341): Rollback this patch
+                // Android-changed: Change the expected output until JDK-8062924 is fixed on Android
+                // "<t>||</t>");
+                "<t>|sdf|</t>");
+    }
+
+    @Test(dataProvider = "GeneralTestsData")
+    public void testGeneralAll(String xsl, String result) throws Exception {
+        assertEquals(testTransform(xsl), result);
+    }
+
+    // TODO(b/181173341): Rollback this patch
+    // Android-removed: Disable the test until JDK-8074297 is fixed on Android.
+    /*
+    @Test(dataProvider = "SupplementaryCharactersTestData")
+    public void testSupplementCharacters(String xsl, String result) throws Exception {
+        assertEquals(testTransform(xsl), result);
+    }
+    */
+
+}
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml
new file mode 100644
index 0000000..1f97559
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<html>
+<a>
+   <b>Is this EXSLT? No. no</b>
+   <c>Is this EXSLT? No. no</c>
+</a>
+</html>
diff --git a/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl
new file mode 100644
index 0000000..d090d3b
--- /dev/null
+++ b/ojluni/src/test/javax/xml/jaxp/transform/tokenize.xsl
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
+                xmlns:str="http://exslt.org/strings"
+                xmlns:xalan="http://xml.apache.org/xalan"
+                version="1.0">
+<xsl:template match="a">
+   <xsl:apply-templates />
+</xsl:template>
+<xsl:template match="//a/c">
+   <xsl:value-of select="." />
+ -
+      <xsl:value-of select="str:tokenize(string(.), ' ')" />
+   <xsl:value-of select="str:tokenize(string(.), '')" />
+   <xsl:for-each select="str:tokenize(string(.), ' ')">
+      <xsl:value-of select="." />
+   </xsl:for-each>
+   <xsl:apply-templates select="*" />
+</xsl:template>
+<xsl:template match="//a/b">
+   <xsl:value-of select="." />
+ -
+      <xsl:value-of select="xalan:tokenize(string(.), ' ')" />
+   <xsl:value-of select="xalan:tokenize(string(.), '')" />
+   <xsl:for-each select="xalan:tokenize(string(.), ' ')">
+      <xsl:value-of select="." />
+   </xsl:for-each>
+   <xsl:apply-templates select="*" />
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/openjdk_java_files.bp b/openjdk_java_files.bp
index 7ba860c..a9f1dee 100644
--- a/openjdk_java_files.bp
+++ b/openjdk_java_files.bp
@@ -259,6 +259,13 @@
         "ojluni/src/main/java/java/lang/invoke/VarHandle.java",
         "ojluni/src/main/java/java/lang/invoke/VolatileCallSite.java",
         "ojluni/src/main/java/java/lang/invoke/WrongMethodTypeException.java",
+        "ojluni/src/main/java/java/math/BigDecimal.java",
+        "ojluni/src/main/java/java/math/BigInteger.java",
+        "ojluni/src/main/java/java/math/BitSieve.java",
+        "ojluni/src/main/java/java/math/MathContext.java",
+        "ojluni/src/main/java/java/math/MutableBigInteger.java",
+        "ojluni/src/main/java/java/math/RoundingMode.java",
+        "ojluni/src/main/java/java/math/SignedMutableBigInteger.java",
         "ojluni/src/main/java/java/net/AbstractPlainDatagramSocketImpl.java",
         "ojluni/src/main/java/java/net/AbstractPlainSocketImpl.java",
         "ojluni/src/main/java/java/net/Authenticator.java",
@@ -1418,7 +1425,6 @@
         "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",
     ],
 }
 
@@ -1792,6 +1798,7 @@
         "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",
diff --git a/support/src/test/java/libcore/java/security/StandardNames.java b/support/src/test/java/libcore/java/security/StandardNames.java
index 7521cf9..64392e4 100644
--- a/support/src/test/java/libcore/java/security/StandardNames.java
+++ b/support/src/test/java/libcore/java/security/StandardNames.java
@@ -608,6 +608,14 @@
             if (Security.getProvider("KnoxAndroidKeyStore") != null) {
                 provide("KeyStore", "KnoxAndroidKeyStore");
             }
+
+            // Elliptic curve Diffie-Hellman
+            provide("KeyAgreement", "XDH");
+            provide("KeyFactory", "XDH");
+            provide("KeyPairGenerator", "XDH");
+
+            // AES-CMAC Mac
+            provide("Mac", "AESCMAC");
         }
     }
 
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/TestCertUtils.java b/support/src/test/java/org/apache/harmony/security/tests/support/TestCertUtils.java
index c9b9c9a..62261db 100644
--- a/support/src/test/java/org/apache/harmony/security/tests/support/TestCertUtils.java
+++ b/support/src/test/java/org/apache/harmony/security/tests/support/TestCertUtils.java
@@ -151,7 +151,7 @@
         private static final byte[] encoded = new byte[] { 1, 2, 3, 4, 5, 6, 7,
                 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
 
-        private static final String serializedData = "Just a dummy string to be serialized instead of real data";
+        private static final String serializedData = "Just a fake string to be serialized instead of real data";
 
         private Certificate[] certs;
 
diff --git a/support/src/test/java/org/apache/harmony/security/tests/support/TestKeyStoreSpi.java b/support/src/test/java/org/apache/harmony/security/tests/support/TestKeyStoreSpi.java
index 86b54c4..4994b72 100644
--- a/support/src/test/java/org/apache/harmony/security/tests/support/TestKeyStoreSpi.java
+++ b/support/src/test/java/org/apache/harmony/security/tests/support/TestKeyStoreSpi.java
@@ -50,13 +50,13 @@
 
     };
 
-    public static final Object DUMMY = new Object();
+    public static final Object FAKE = new Object();
 
     public TestKeyStoreSpi() {
         aliases.put("certalias", CERT);
         aliases.put("chainalias", CERTCHAIN);
         aliases.put("keyalias", KEY);
-        aliases.put("unknownalias", DUMMY);
+        aliases.put("unknownalias", FAKE);
     }
 
     @Override
diff --git a/support/src/test/java/tests/support/Support_ProviderTrust.java b/support/src/test/java/tests/support/Support_ProviderTrust.java
index 9c47e10..dc36930 100644
--- a/support/src/test/java/tests/support/Support_ProviderTrust.java
+++ b/support/src/test/java/tests/support/Support_ProviderTrust.java
@@ -22,7 +22,7 @@
 import java.security.Provider;
 
 /**
- * This class implements a dummy provider.
+ * This class implements a fake provider.
  *
  */
 public class Support_ProviderTrust extends Provider {
@@ -38,7 +38,7 @@
             + " DSA key, parameter generation and signing; SHA-1 digest; SHA1PRNG SecureRandom";
 
     /**
-     * Constructs a new instance of the dummy provider.
+     * Constructs a new instance of the fake provider.
      *
      */
     public Support_ProviderTrust() {
diff --git a/support/src/test/java/tests/support/Support_TestProvider.java b/support/src/test/java/tests/support/Support_TestProvider.java
index 0b5d319..5c87b39 100644
--- a/support/src/test/java/tests/support/Support_TestProvider.java
+++ b/support/src/test/java/tests/support/Support_TestProvider.java
@@ -22,7 +22,7 @@
 import java.security.Provider;
 
 /**
- * This class implements a dummy provider.
+ * This class implements a fake provider.
  */
 public class Support_TestProvider extends Provider {
     private static final long serialVersionUID = 1L;
@@ -38,7 +38,7 @@
             + "SHA1PRNG SecureRandom; PKCS#12/Netscape KeyStore";
 
     /**
-     * Constructs a new instance of the dummy provider.
+     * Constructs a new instance of the fake provider.
      */
     public Support_TestProvider() {
         super(NAME, VERSION, INFO);
@@ -110,7 +110,7 @@
                 put("Alg.Alias.Signature.OID.1.3.14.3.2.27", "SHA1withDSA");
 
                 put("KeyStore.PKCS#12/Netscape",
-                        "tests.support.Support_DummyPKCS12Keystore");
+                        "tests.support.Support_FakePKCS12Keystore");
 
                 // Certificate
                 put("CertificateFactory.X509",
@@ -122,4 +122,4 @@
             }
         });
     }
-}
\ No newline at end of file
+}
diff --git a/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java b/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
index b526707..4fd3208 100644
--- a/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
+++ b/test-rules/src/platform_compat/java/libcore/junit/util/CoreCompatChangeRule.java
@@ -17,7 +17,6 @@
 package libcore.junit.util.compat;
 
 import android.compat.Compatibility;
-import android.compat.Compatibility.Callbacks;
 import android.compat.Compatibility.ChangeConfig;
 
 import org.junit.rules.TestRule;
diff --git a/test-rules/src/test/java/android/compat/testing/DummyApi.java b/test-rules/src/test/java/android/compat/testing/FakeApi.java
similarity index 90%
rename from test-rules/src/test/java/android/compat/testing/DummyApi.java
rename to test-rules/src/test/java/android/compat/testing/FakeApi.java
index dfe40cc..95fc8a0 100644
--- a/test-rules/src/test/java/android/compat/testing/DummyApi.java
+++ b/test-rules/src/test/java/android/compat/testing/FakeApi.java
@@ -19,21 +19,21 @@
 import android.compat.Compatibility;
 
 /**
- * This is a dummy API to test gating
+ * This is a fake API to test gating
  *
  * @hide
  */
-public class DummyApi {
+public class FakeApi {
 
     public static final long CHANGE_ID = 666013;
     public static final long CHANGE_ID_1 = 666014;
     public static final long CHANGE_ID_2 = 666015;
 
     /**
-     * Dummy method
+     * Fake method
      * @return "A" if change is enabled, "B" otherwise.
      */
-    public static String dummyFunc() {
+    public static String fakeFunc() {
         if (Compatibility.isChangeEnabled(CHANGE_ID)) {
             return "A";
         }
@@ -41,13 +41,13 @@
     }
 
     /**
-     * Dummy combined method
+     * Fake combined method
      * @return "0" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is disabled,
                "1" if {@link CHANGE_ID_1} is disabled and {@link CHANGE_ID_2} is enabled,
                "2" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is disabled,
                "3" if {@link CHANGE_ID_1} is enabled and {@link CHANGE_ID_2} is enabled.
      */
-    public static String dummyCombinedFunc() {
+    public static String fakeCombinedFunc() {
         if (!Compatibility.isChangeEnabled(CHANGE_ID_1)
                 && !Compatibility.isChangeEnabled(CHANGE_ID_2)) {
             return "0";
diff --git a/test-rules/src/test/java/libcore/junit/util/compat/CoreCompatChangeRuleTest.java b/test-rules/src/test/java/libcore/junit/util/compat/CoreCompatChangeRuleTest.java
index 87b9446..1df8888 100644
--- a/test-rules/src/test/java/libcore/junit/util/compat/CoreCompatChangeRuleTest.java
+++ b/test-rules/src/test/java/libcore/junit/util/compat/CoreCompatChangeRuleTest.java
@@ -17,7 +17,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.compat.testing.DummyApi;
+import android.compat.testing.FakeApi;
 
 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -38,40 +38,40 @@
     public TestRule compatChangeRule = new CoreCompatChangeRule();
 
     @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID})
-    public void testDummyGatingPositive() {
-        assertThat(DummyApi.dummyFunc()).isEqualTo("A");
+    @EnableCompatChanges({FakeApi.CHANGE_ID})
+    public void testFakeGatingPositive() {
+        assertThat(FakeApi.fakeFunc()).isEqualTo("A");
     }
 
     @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID})
-    public void testDummyGatingNegative() {
-        assertThat(DummyApi.dummyFunc()).isEqualTo("B");
+    @DisableCompatChanges({FakeApi.CHANGE_ID})
+    public void testFakeGatingNegative() {
+        assertThat(FakeApi.fakeFunc()).isEqualTo("B");
     }
 
     @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined0() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("0");
+    @DisableCompatChanges({FakeApi.CHANGE_ID_1, FakeApi.CHANGE_ID_2})
+    public void testFakeGatingCombined0() {
+        assertThat(FakeApi.fakeCombinedFunc()).isEqualTo("0");
     }
 
     @Test
-    @DisableCompatChanges({DummyApi.CHANGE_ID_1})
-    @EnableCompatChanges({DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined1() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("1");
+    @DisableCompatChanges({FakeApi.CHANGE_ID_1})
+    @EnableCompatChanges({FakeApi.CHANGE_ID_2})
+    public void testFakeGatingCombined1() {
+        assertThat(FakeApi.fakeCombinedFunc()).isEqualTo("1");
     }
 
     @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID_1})
-    @DisableCompatChanges({DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined2() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("2");
+    @EnableCompatChanges({FakeApi.CHANGE_ID_1})
+    @DisableCompatChanges({FakeApi.CHANGE_ID_2})
+    public void testFakeGatingCombined2() {
+        assertThat(FakeApi.fakeCombinedFunc()).isEqualTo("2");
     }
 
     @Test
-    @EnableCompatChanges({DummyApi.CHANGE_ID_1, DummyApi.CHANGE_ID_2})
-    public void testDummyGatingCombined3() {
-        assertThat(DummyApi.dummyCombinedFunc()).isEqualTo("3");
+    @EnableCompatChanges({FakeApi.CHANGE_ID_1, FakeApi.CHANGE_ID_2})
+    public void testFakeGatingCombined3() {
+        assertThat(FakeApi.fakeCombinedFunc()).isEqualTo("3");
     }
 }
\ 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 9b7e5f0..3369bcd 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -141,7 +141,7 @@
         // suites are disabled in that case, so check for both
         SSLContext pskContext = SSLContext.getInstance("TLS");
         pskContext.init(
-                new KeyManager[] {new DummyKeyManager()},
+                new KeyManager[] {new FakeKeyManager()},
                 new TrustManager[0],
                 null);
         for (SSLContext sslContext : new SSLContext[] {defaultContext, tls13Context, pskContext}) {
@@ -163,7 +163,7 @@
         System.out.println("END ALGORITHM LIST");
     }
 
-    private static class DummyKeyManager implements PSKKeyManager {
+    private static class FakeKeyManager 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; }
diff --git a/tools/patch-style/libcore-patch-style.awk b/tools/patch-style/libcore-patch-style.awk
new file mode 100644
index 0000000..e138298
--- /dev/null
+++ b/tools/patch-style/libcore-patch-style.awk
@@ -0,0 +1,175 @@
+# Copyright 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.
+
+# Simple libcore patch-style checking based on http://go/libcore-patch-style.
+#
+# See sample-input.java for examples of matches and failures.
+#
+# Usage:
+#  awk -f libcore-patch-style.awk <file0> [... fileN]
+#
+# This script ignores any files whose name does not end in the suffix ".java".
+#
+# To scan all source code in the libcore tree:
+#  $ cd libcore
+#  $ find . -type f | xargs awk -f tools/patch-style/libcore-patch-style.awk
+#
+# To find sources with the most issues:
+#  $ cd libcore
+#  $ find . -type f | xargs awk -f tools/patch-style/libcore-patch-style.awk \
+#                   | grep -F ./ | sed -e 's/:.*//' | uniq -c | sort -n -r | head
+
+BEGIN {
+  g_errors = 0                    # Number of errors accumulated.
+  g_expected_end = ""             # Expected END line.
+  g_max_length = 100              # Maximum line length for markers (0 == no checking).
+  g_stop_oneline_interleaving = 0 # Error one-line comments between BEGIN and END markers.
+}
+
+BEGINFILE {
+  # Skip files whose names do not have a .java suffix.
+  if (FILENAME !~ /\.java$/) {
+    nextfile
+  }
+
+  # Reset the line number for reporting errors back to zero.
+  NR = 0
+
+  # Clear expected end marker as processing a new file.
+  g_expected_end = ""
+}
+
+function error(message) {
+  print(FILENAME ":" NR ":", message "\n")
+  g_errors += 1;
+}
+
+function expectationError(reason, expected, actual) {
+  error(reason "\n  Expected: \"" expected "\"\n  Actual:   \"" actual "\"")
+}
+
+function inputError(reason, actual) {
+  error(reason "\n  Input:    \"" actual "\"")
+}
+
+function checkLineLength(line) {
+  if (g_max_length > 0 && length(line) > g_max_length) {
+    inputError("Line too long", line)
+  }
+}
+
+function leftTrim(message) {
+  return gensub(/^ */, "", 1, message)
+}
+
+function failIfEndExpected() {
+  if (g_expected_end != "") {
+    expectationError("Missing END marker.", g_expected_end, $0)
+    g_expected_end = ""
+  }
+}
+
+function expectEndFor(begin_line) {
+  g_expected_end = begin_line
+  sub("BEGIN", "END", g_expected_end)
+}
+
+function actualEndFor(actual_line) {
+  if (actual_line != g_expected_end) {
+    expectationError("Bad END marker.", g_expected_end, actual_line)
+  }
+  g_expected_end = ""
+}
+
+function processBeginMarker(line) {
+  failIfEndExpected()
+  expectEndFor(line)
+}
+
+function processEndMarker(line) {
+  actualEndFor(line)
+}
+
+# BEGIN marker ending in a period.
+/^ *\/\/ BEGIN Android-(added|changed|note|removed):.*\./ {
+  checkLineLength($0)
+  processBeginMarker($0)
+  next
+}
+
+# BEGIN marker ending in a period.
+/^ *\/\/ END Android-(added|changed|note|removed):.*\./ {
+  checkLineLength($0)
+  processEndMarker($0)
+  next
+}
+
+# BEGIN marker ending in a bug reference.
+/^ *\/\/ BEGIN Android-(added|changed|note|removed):.*[.](http:\/\/)?b\/[1-9][0-9]*/ {
+  checkLineLength($0)
+  processBeginMarker($0)
+  next
+}
+
+# BEGIN marker ending in anything else, oops!
+/^ *\/\/ BEGIN Android-(added|changed|note|removed)[^:].*/ {
+  inputError("BEGIN marker is missing colon or description.", $0)
+  next
+}
+
+# END marker, should be paired with last BEGIN marker.
+/^ *\/\/ END Android-(added|changed|note|removed):.*/ {
+  checkLineLength($0)
+  processEndMarker($0)
+  next
+}
+
+# One line change marker ending in a period.
+/^ *\/\/ Android-(added|changed|note|removed):.*[.]/ {
+  checkLineLength($0)
+  if (g_stop_oneline_interleaving) {
+    failIfEndExpected()
+  }
+  next
+}
+
+# One line change marker ending in a bug reference.
+/^ *\/\/ Android-(added|changed|note|removed):[.](http:\/\/)?b\/[1-9][0-9]*/ {
+  checkLineLength($0)
+  if (g_stop_oneline_interleaving) {
+    failIfEndExpected()
+  }
+  next
+}
+
+# One line change marker missing comment after colon.
+/^ *\/\/ BEGIN Android-(added|changed|note|removed).*/ {
+  inputError("Bad change marker: missing colon or description.", $0)
+  next
+}
+
+# Something that looks like a potential change marker.
+/^ *(\/\*|\/\/|\*) *(Android|ANDROID)-/ {
+  if (g_stop_oneline_interleaving) {
+    failIfEndExpected()
+  }
+  inputError("Bad change marker.", $0)
+  next
+}
+
+END {
+  failIfEndExpected()
+  printf("Found " g_errors " libcore patch style issues.\n")
+  exit g_errors == 0
+}
diff --git a/tools/patch-style/sample-input.java b/tools/patch-style/sample-input.java
new file mode 100644
index 0000000..8d55cfe
--- /dev/null
+++ b/tools/patch-style/sample-input.java
@@ -0,0 +1,32 @@
+# HAPPY PATHS
+    // BEGIN Android-added: something bot like.
+    // END Android-added: something bot like.
+
+    // BEGIN Android-changed: something bot like. http://b/12345
+    // END Android-changed: something bot like. http://b/12345
+
+    // BEGIN Android-removed: coffee stain. b/12345
+    // END Android-changed: something bot like. http://b/12345
+
+    // Android-added: hello world.
+    // Android-change: hello world. http://b/1100
+    // Android-remove: goodbye world. http://b/999912
+
+# UNHAPPY PATHS
+
+    //  BEGIN Android-added something bot like.
+    //  END Android-added something bot like.
+
+    // Android-note: blah
+    // Android-note: blah.
+    // Android-changed hello
+    // Android-added: hello
+
+    /* Android-note blah balh */
+    /* Android note: blah balh */
+    /* ANDROID android android android */
+    * ANDROID *
+
+Android-bar
+
+// BEGIN Android-removed: END from last line.
diff --git a/tools/testmapping/README b/tools/testmapping/README
new file mode 100644
index 0000000..0222018
--- /dev/null
+++ b/tools/testmapping/README
@@ -0,0 +1,36 @@
+These scripts help generate the libcore TEST_MAPPING smoke tests, i.e. a set of
+tests to run on every change, chosen to run as many as possible in less than
+some time limit.
+
+The process is as follows.
+1. Do `source build/envsetup.sh` and `lunch <whatever>` as normal.
+2. Run the CtsLibcoreTestCases tests to generate logs to extract timings from.
+   This can be done with `atest CtsLibcoreTestCases` as normal. Make sure to use
+   an appropriate device (virtual or physical).
+3. Do that two more times. We'll use best-of-three timings, since sometimes a
+   test takes an unusual amount of time (perhaps because of GC pause or other
+   jank) and it should not be excluded for that.
+4. Run the save_logs.py script to copy the logs from out/ to libcore/smoketest.
+   (Empty that directory if it exists already). This is interactive and allows
+   you to pick the runs you want. (If you prefer, you can run this after each
+   run, rather than once after all three runs.)
+5. Run the gen_smoke_tests.py script to generate libcore/TEST_MAPPING.
+6. Check stdout from the script looks okay (not too many warnings, sensible
+   numbers, etc.).
+7. Check the generated TEST_MAPPING looks okay.
+8. Do e.g. `time atest --test-mapping libcore` to check it runs okay.
+9. Delete libcore/smoketest/ once you're happy.
+10. Submit the new TEST_MAPPING.
+
+The scripts take no options. There are some constants at the start you can
+adjust. (These could be converted to command-line options if convenient.)
+
+See comments in the scripts for more on how they work.
+
+At time of writing, with the current configuration, this generates a sensible
+number of classes to exclude, so the TEST_MAPPING looks reasonable. If this list
+becomes too long, we'll have to find a way to simplify it, by rolling up to a
+higher granularity. Given the way that atest et al are configured, that will
+probably mean excluding more things.
+
+TODO(peteg): What about PTS?
diff --git a/tools/testmapping/gen_smoke_tests.py b/tools/testmapping/gen_smoke_tests.py
new file mode 100755
index 0000000..159be1b
--- /dev/null
+++ b/tools/testmapping/gen_smoke_tests.py
@@ -0,0 +1,474 @@
+#!/usr/bin/env python2
+#
+#   Copyright 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.
+
+"""Tool to generate data for smoke tests."""
+
+from __future__ import print_function
+
+import collections
+import datetime
+import gzip
+import operator
+import os
+import re
+import tempfile
+
+import jinja2
+import util
+
+ANDROID_REPOSITORY_ROOT = util.android_repository_root()
+LIBCORE_DIR = os.path.join(ANDROID_REPOSITORY_ROOT, 'libcore')
+LOGS_DIR = os.path.join(LIBCORE_DIR, 'smoketest')
+REQUIRED_RUNS = 3
+CTS_LOG_LINE_PATTERN = (r'(\d+)-(\d+) +(\d+):(\d+):(\d+)\.(\d+) +\d+ +\d+ +'
+                        r'[^ ]+ (CtsTestRunListener|TestRunner) *: *(.+)')
+THIS_YEAR = datetime.datetime.now().year
+START_MATCHER = ('CtsTestRunListener', r'Now executing\s*:\s*(.+)')
+TESTS_RAN_MATCHER = ('TestRunner', r'started\s*:.*')
+END_MATCHER = ('CtsTestRunListener', r'Total memory\s*:.+')
+HARD_END_MATCHER = ('TestRunner', r'run finished\s*:.+')
+JAVA_CLASS_PATTERN = r'(?:([a-zA-Z_][a-zA-Z0-9_]*(?:\.[a-zA-Z_][a-zA-Z0-9_]*)*)\.)?[a-zA-Z_][a-zA-Z0-9_]*'
+MAX_RUN_TIME = datetime.timedelta(minutes=10)
+OUT_DIR = tempfile.mkdtemp()
+ROLL_UP_TEST_CLASSES_TO_PACKAGE = False
+CTS_MODULE_NAME = 'CtsLibcoreTestCases'
+
+TEST_MAPPING_TEMPLATE = jinja2.Template("""
+{
+  "presubmit": [
+    {
+      "name": "{{module}}",
+      "options": [{% for test in exclusions %}
+        {
+          "exclude-filter": "{{test}}"
+        }{% if not loop.last %},{% endif %}{% endfor %}
+      ]
+    }
+  ]
+}
+""".strip())
+
+
+def find_all_log_files():
+  """Returns a list of the log files to read."""
+  if not os.path.isdir(LOGS_DIR):
+    raise Exception('Could not find logs directory ' + LOGS_DIR)
+  filenames = os.listdir(LOGS_DIR)
+  if not filenames:
+    raise Exception('Found empty logs directory ' + LOGS_DIR)
+  if len(filenames) != REQUIRED_RUNS:
+    raise Exception('Expected to find exactly %d files in %s, found %d' %
+                    (REQUIRED_RUNS, LOGS_DIR, len(filenames)))
+  return map(lambda f: os.path.join(LOGS_DIR, f), filenames)
+
+
+def read_cts_logs(filename):
+  """Read CTS entries from a log file.
+
+  Args:
+    filename: The name of the file to read.
+
+  Yields:
+    Tuples of timestamps (as datetimes), log sources, and log messages.
+  """
+  print('Reading ' + util.printable_path(filename))
+  with gzip.open(filename, mode='rt') as log_file:
+    for line in log_file:
+      cts_match = re.match(CTS_LOG_LINE_PATTERN, line)
+      if cts_match:
+        assert len(cts_match.groups()) == 8
+        timestamp = datetime.datetime(
+            year=THIS_YEAR,
+            month=int(cts_match.group(1)),
+            day=int(cts_match.group(2)),
+            hour=int(cts_match.group(3)),
+            minute=int(cts_match.group(4)),
+            second=int(cts_match.group(5)),
+            microsecond=1000 * int(cts_match.group(6)))
+        source = cts_match.group(7)
+        message = cts_match.group(8)
+        yield (timestamp, source, message)
+
+
+def match(matcher, got_source, message):
+  """Check whether a log line matches requirements.
+
+  Args:
+    matcher: A pair of the required log source and a pattern to match messages.
+    got_source: The actual log source.
+    message: The actual message.
+
+  Returns:
+    A MatchObject from the pattern match against the message, or None.
+  """
+  (want_source, pattern) = matcher
+  if got_source == want_source:
+    return re.match(pattern, message)
+  else:
+    return None
+
+
+def parse_running_times(filename):
+  """Parse the running times from a log file.
+
+  Args:
+    filename: The name of the file to read.
+
+  Yields:
+    Pairs of test names and running times (as timedeltas). Also emits the
+    overall elapsed time from the start of the first test to the end of the last
+    test with the key 'OVERALL'.
+
+  Raises:
+    Exception: The log file entries didn't look like we expected.
+  """
+  executing = None
+  start_timestamp = None
+  ran_tests = False
+  overall_start_timestamp = None
+  overall_end_timestamp = None
+  for (timestamp, source, message) in read_cts_logs(filename):
+    start_match = match(START_MATCHER, source, message)
+    tests_ran_match = match(TESTS_RAN_MATCHER, source, message)
+    end_match = match(END_MATCHER, source, message)
+    hard_end_match = match(HARD_END_MATCHER, source, message)
+    if not executing:
+      if start_match:
+        assert len(start_match.groups()) == 1
+        executing = start_match.group(1)
+        start_timestamp = timestamp
+        if not overall_start_timestamp:
+          overall_start_timestamp = timestamp
+    else:
+      if start_match:
+        raise Exception(
+            'Found start for %s while waiting for end for %s at %s in %s' %
+            (start_match.group(1), executing, str(timestamp), filename))
+      if tests_ran_match:
+        ran_tests = True
+      if end_match or hard_end_match:
+        running_time = timestamp - start_timestamp
+        # We see two types of execution in the logs. One appears to be some kind
+        # of dry run which doesn't actually run any tests (and completes
+        # significantly faster). We want the one that actually runs tests.
+        if ran_tests:
+          yield (executing, running_time)
+        executing = None
+        start_timestamp = None
+        ran_tests = False
+        overall_end_timestamp = timestamp
+  if executing:
+    raise Exception('Reached EOF while waiting for end for %s in %s' %
+                    (executing, filename))
+  yield ('OVERALL', overall_end_timestamp - overall_start_timestamp)
+
+
+def collect_running_times(filenames):
+  """Collect running times from some log file.
+
+  Args:
+    filenames: The names of the files to read.
+
+  Returns:
+    A tuple containing (1) a dictionary mapping test names to sets of running
+    times (as timedeltas), and (2) a list of overall running times (i.e. elapsed
+    times from the start of the first test to the end of the last test).
+  """
+  times_by_test = collections.defaultdict(list)
+  output_path = os.path.join(OUT_DIR, 'test_times.txt')
+  overall_times = []
+  with open(output_path, 'w') as output:
+    for filename in filenames:
+      for (test_name, time) in parse_running_times(filename):
+        output.write('%s: %g ms\n' % (test_name, time.total_seconds() * 1000))
+        if test_name == 'OVERALL':
+          overall_times.append(time)
+        else:
+          times_by_test[test_name].append(time)
+  print('Wrote test times to ' + util.printable_path(output_path))
+  return (times_by_test, overall_times)
+
+
+def process_running_times(times_by_test):
+  """Processes the collected running times.
+
+  Args:
+    times_by_test: A dictionary mapping test names to sets of running times.
+
+  Returns:
+    A dictionary mapping test names to fastest running times.
+  """
+  for (test, times) in times_by_test.iteritems():
+    if len(times) != REQUIRED_RUNS:
+      print('Warning: Only found %d runs for %s' % (len(times), test))
+  return {test: min(times) for (test, times) in times_by_test.iteritems()}
+
+
+def calculate_overhead_ratio(overall_times, fastest_time_by_test):
+  """Calculates a ratio for the actual overall time to the sum of test times.
+
+   The actual overall times are the elapsed times from the start of the first
+   test to the end of the last test. The average of these is used. The ratio is
+   taken with the sume of the fastest time for each test (which is what will be
+   used for scoring).
+
+  Args:
+    overall_times: A list of overall running times.
+    fastest_time_by_test: A dictionary mapping test names to fastest running
+      times.
+
+  Returns:
+    The ratio.
+  """
+  average_overall_time = sum(overall_times,
+                             datetime.timedelta(0)) / len(overall_times)
+  total_time_by_test = sum(fastest_time_by_test.values(), datetime.timedelta(0))
+  ratio = (
+      average_overall_time.total_seconds() / total_time_by_test.total_seconds())
+  print(
+      'Average time for run is %g seconds, sum of fastest test times is %g, ratio is %g'
+      % (average_overall_time.total_seconds(),
+         total_time_by_test.total_seconds(), ratio))
+................................................................................
+  # N.B. Possible future enhancement: Currently, because# we take the fastest of
+  # three runs, a real run will always be slightly slower than we predict. We
+  # could multiply in another overhead factor to account for this, e.g. by
+  # looking at the ratio of the mean of the three to the fastest of the three.
+  # (This factor should be applied globally rather than individually to each
+  # test so as not to penalize tests which happened to have a slow run or two.)
+  # This is not a high priority since for now we can just set MAX_RUN_TIME a bit
+  # low to allow for this.
+  return ratio
+
+
+def get_parent(name):
+  """Returns the parent of a Java class or package name."""
+  class_match = re.match(JAVA_CLASS_PATTERN, name)
+  if not class_match:
+    raise Exception('Could not parse Java class name ' + name)
+  assert len(class_match.groups()) == 1
+  return class_match.group(1)
+
+
+def group_times_by_package(times_by_test):
+  """Groups the test classes by package name, summing the times.
+
+  Args:
+    times_by_test: A dictionary mapping test names to fastest running times.
+
+  Returns:
+    A dictionary mapping package names to total fastest running times.
+  """
+  time_by_package = collections.defaultdict(datetime.timedelta)
+  for (clazz, time) in times_by_test.iteritems():
+    package = get_parent(clazz)
+    if package:  # A few tests have no package. They're weird, let's skip them.
+      time_by_package[package] = time_by_package[package] + time
+  output_path = os.path.join(OUT_DIR, 'package_times.txt')
+  with open(output_path, 'w') as output:
+    for (package, time) in time_by_package.iteritems():
+      output.write('%s: %s ms\n' % (package, time.total_seconds() * 1000.0))
+  print('Wrote package times to ' + util.printable_path(output_path))
+  return time_by_package
+
+
+def find_tests_to_run(time_by_test, overhead_ratio):
+  """Finds the tests to actually run.
+
+  The tests chosen will be the fastest set such that their total time, when
+  multiplied by the overhead ratio, is less than the maximum.
+
+  Args:
+    time_by_test: A dictionary mapping test names to total fastest running
+      times. The names can be packages, classes, or a mixture of the two.
+    overhead_ratio: A ratio for the actual overall time to the sum of test
+      times.
+
+  Returns:
+    A list of test names whose running times are below the threshold.
+
+  Raises:
+    Exception: The total running time of all the tests is below the threhold.
+  """
+  test_inclusions = {test: False for test in time_by_test.keys()}
+  included = 0
+  total_time = datetime.timedelta()
+  output_path = os.path.join(OUT_DIR, 'included_tests.txt')
+  adjusted_max_run_time_seconds = MAX_RUN_TIME.total_seconds() / overhead_ratio
+  with open(output_path, 'w') as output:
+    for (test, time) in sorted(
+        time_by_test.iteritems(), key=operator.itemgetter(1)):
+      if (total_time + time).total_seconds() <= adjusted_max_run_time_seconds:
+        test_inclusions[test] = True
+        included += 1
+        total_time += time
+        output.write('%s: %g ms -> %g ms\n' %
+                     (test, time.total_seconds() * 1000.0,
+                      total_time.total_seconds() * 1000.0))
+      else:
+        print('Can run fastest %d of %d tests in %g * %g = %g seconds' %
+              (included, len(time_by_test), total_time.total_seconds(),
+               overhead_ratio, total_time.total_seconds() * overhead_ratio))
+        print('Wrote tests to include to ' + util.printable_path(output_path))
+        return test_inclusions
+  raise Exception('Apparently we can run all the tests? This smells wrong.')
+
+
+def build_test_tree(tests):
+  """Builds a tree of tests.
+
+  Args:
+    tests: The list of tests to build into a tree. These can be packages,
+      classes, or a mixture of the two.
+
+  Returns:
+    A dictionary mapping every test's ancestors to its children. The roots
+    appear as children of None.
+  """
+  tree = collections.defaultdict(set)
+  for test in tests:
+    while True:
+      parent = get_parent(test)
+      tree[parent].add(test)
+      if parent:
+        test = parent
+      else:
+        break
+  return tree
+
+
+def build_exclusion_list(test_inclusions):
+  """Builds a list of tests to exclude.
+
+  Args:
+    test_inclusions: A dictionary mapping test names to whether or not they
+      should be included in the smoke tests. The names can be packages, classes,
+      or a mixture of the two.
+
+  Returns:
+    A list of the exclusions. These could be individual tests, or packages or
+    some part of the package hierarchy if they are to be entirely excluded.
+  """
+  tree = build_test_tree(test_inclusions.keys())
+  exclusions = []
+
+  # We do a DFS of the tree, rolling up exclusions as far as possible, i.e. if
+  # an entire branch is excluded, we exclude that branch rather than all of its
+  # leaves.
+
+  def visit(test):
+    """Visitor for a DFS of the tree.
+
+    Args:
+      test: The test to visit (either a class or package name).
+
+    Returns:
+      Whether or not the parent should include this node in the tree.
+
+    Raises:
+      Exception: The tree had an unexpected structure.
+    """
+    if test in test_inclusions:
+      # We only expect to have inclusion status for the leaves of the tree.
+      # Check that this is the case.
+      if test in tree:
+        raise Exception('The name %s is used for a leaf and a branch!' % test)
+      # Return to the parent node whether this leaf is included.
+      return test_inclusions[test]
+    else:
+      # We expect to have inclusion status for all leaves of the tree. Check
+      # that this is the case.
+      if test not in tree:
+        raise Exception('Leaf %s has no inclusion status!' % test)
+      # Look at all the children of this node.
+      any_child_included = False
+      child_exclusions = []
+      for child in tree[test]:
+        child_included = visit(child)
+        if child_included:
+          any_child_included = True
+        else:
+          child_exclusions.append(child)
+      # If any children are included, we will count this node as included, so we
+      # have to add any excluded children to the exclusion list.
+      if any_child_included:
+        for child in child_exclusions:
+          exclusions.append(child)
+      # Now return whether this node should be counted as included, which means
+      # whether any children are included.
+      return any_child_included
+
+  # Start the DFS at each root of the tree.
+  for root in tree[None]:
+    root_included = visit(root)
+    # If any of the roots are counted as excluded, add them to the list.
+    if not root_included:
+      exclusions.append(root)
+
+  # Finally, sort and return the list of exclusions.
+  return sorted(exclusions)
+
+
+def self_test():
+  """Self-test for the build_include_exclude_list logic."""
+  test_inclusions = {
+      'a.x': True,
+      'a.y': True,
+      'b.x': True,
+      'b.y': False,
+      'c.x': False,
+      'c.y': False,
+      'd.x.m': True,
+      'd.x.n': True,
+      'd.y.m': True,
+      'd.y.n': False,
+      'd.z.m': False,
+      'd.z.n': False,
+  }
+  expected_exclusions = [
+      'b.y',
+      'c',
+      'd.y.n',
+      'd.z',
+  ]
+  actual_exclusions = build_exclusion_list(test_inclusions)
+  if actual_exclusions != expected_exclusions:
+    raise Exception('Self test failed! Expected %s but got %s' %
+                    (expected_exclusions, actual_exclusions))
+
+
+def main():
+  """The main method."""
+  self_test()
+  filenames = find_all_log_files()
+  (times_by_test, overall_times) = collect_running_times(filenames)
+  fastest_time_by_test = process_running_times(times_by_test)
+  overhead_ratio = calculate_overhead_ratio(overall_times, fastest_time_by_test)
+  if ROLL_UP_TEST_CLASSES_TO_PACKAGE:
+    time_by_package = group_times_by_package(fastest_time_by_test)
+    test_inclusions = find_tests_to_run(time_by_package, overhead_ratio)
+  else:
+    test_inclusions = find_tests_to_run(fastest_time_by_test, overhead_ratio)
+  exclusions = build_exclusion_list(test_inclusions)
+  output_path = os.path.join(LIBCORE_DIR, 'TEST_MAPPING')
+  with open(output_path, 'w') as output:
+    output.write(
+        TEST_MAPPING_TEMPLATE.render(
+            module=CTS_MODULE_NAME, exclusions=exclusions))
+  print('Wrote test mapping to ' + util.printable_path(output_path))
+
+
+main()
diff --git a/tools/testmapping/save_logs.py b/tools/testmapping/save_logs.py
new file mode 100755
index 0000000..8f737b3e
--- /dev/null
+++ b/tools/testmapping/save_logs.py
@@ -0,0 +1,142 @@
+#!/usr/bin/env python2
+#
+#   Copyright 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.
+
+"""Tool to save logs files for use by gen_smoke_tests.py."""
+
+from __future__ import print_function
+
+import glob
+import os
+import shutil
+import sys
+
+import util
+
+ANDROID_REPOSITORY_ROOT = util.android_repository_root()
+LOGS_ROOT = os.path.join(ANDROID_REPOSITORY_ROOT, 'out', 'host', 'linux-x86',
+                         'cts', 'android-cts', 'logs')
+CTS_LOGS_PATTERN = os.path.join(LOGS_ROOT, '*', '*',
+                                'device_logcat_test_*.txt.gz')
+LIBCORE_DIR = os.path.join(ANDROID_REPOSITORY_ROOT, 'libcore')
+DESTINATION_DIR = os.path.join(LIBCORE_DIR, 'smoketest')
+
+
+def check_destination():
+  """Ensures the destination directory to copy the files to exists."""
+  if not os.path.isdir(LIBCORE_DIR):
+    raise Exception('Could not find directory ' + LIBCORE_DIR)
+  if not os.path.isdir(DESTINATION_DIR):
+    print('Making destination directory ' +
+          util.printable_path(DESTINATION_DIR))
+    os.mkdir(DESTINATION_DIR, 0o755)
+  else:
+    print('Found destination directory ' + util.printable_path(DESTINATION_DIR))
+
+
+def is_real_log_file(filename):
+  """Returns whether the filename is one we should use or not."""
+  return 'latest' not in filename
+
+
+def find_all_log_files():
+  """Finds all CTS log files in the expected directory.
+
+  Returns:
+    A list of filenames, sorted by mtime, most recent first.
+  Raises:
+    Exception: Not enough log files found.
+  """
+  print('Looking for logs in %s' % util.printable_path(LOGS_ROOT))
+  print('+++ ' + CTS_LOGS_PATTERN)
+  for f in glob.glob(CTS_LOGS_PATTERN):
+    print('*** ' + f)
+  sources = [f for f in glob.glob(CTS_LOGS_PATTERN) if is_real_log_file(f)]
+  if not sources:
+    raise Exception('Found no logs files!')
+  return sorted(sources, key=os.path.getmtime, reverse=True)
+
+
+def relative_source_name(source):
+  """Returns the name of a source file, relative to the logs root."""
+  return os.path.relpath(source, LOGS_ROOT)
+
+
+def flatten_name(name):
+  """Returns a flattened version of a path, using _ to separate."""
+  parts = []
+  while name:
+    (head, tail) = os.path.split(name)
+    parts.insert(0, tail)
+    name = head
+  return '_'.join(parts)
+
+
+def destination_path(name):
+  """Returns the destination path for a given name (which must be flattened)."""
+  assert not os.path.dirname(name)
+  return os.path.join(DESTINATION_DIR, name)
+
+
+def get_indexes_from_user(prompt, options):
+  """Gets a sequence of indexes between 1 and max from the user.
+
+  Args:
+    prompt: A prompt to show to the user.
+    options: The options to show to the user.
+
+  Yields:
+    The indexes.
+  """
+  for (index, option) in enumerate(options):
+    print('%d: %s' % (index + 1, option))
+  while True:
+    print(prompt)
+    instr = sys.stdin.readline().strip()
+    if instr.lower() == 'q':
+      break
+    try:
+      index = int(instr)
+    except ValueError:
+      print('Not a valid index! Please try again')
+      continue
+    if index < 1 or index > len(options):
+      print('Not a valid index! Please try again')
+      continue
+    yield index - 1
+
+
+def do_copy(source):
+  """Copies the given source into the destination directory."""
+  destination = destination_path(flatten_name(relative_source_name(source)))
+  if os.path.exists(destination):
+    print('File already exists: ' + util.printable_path(destination))
+  else:
+    print('Copying %s to %s' %
+          (util.printable_path(source), util.printable_path(destination)))
+    shutil.copyfile(source, destination)
+
+
+def main():
+  check_destination()
+  sources = find_all_log_files()
+  for index in get_indexes_from_user(
+      'Enter the number of the file to save, or Q to quit',
+      map(relative_source_name, sources)):
+    do_copy(sources[index])
+  print('Bye!')
+
+
+main()
diff --git a/tools/testmapping/util.py b/tools/testmapping/util.py
new file mode 100644
index 0000000..b1cf937
--- /dev/null
+++ b/tools/testmapping/util.py
@@ -0,0 +1,34 @@
+#
+#   Copyright 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.
+
+"""Common functions shared between the scripts."""
+
+import os
+
+
+def android_repository_root():
+  """Returns the root of the tree."""
+  if 'ANDROID_BUILD_TOP' not in os.environ:
+    raise Exception('Environment variable ANDROID_BUILD_TOP not set')
+  return os.environ['ANDROID_BUILD_TOP']
+
+
+def printable_path(filename):
+  """Returns the filename relative to the current dir, if it's under it."""
+  relative_path = os.path.relpath(filename)
+  if not relative_path.startswith('../'):
+    return relative_path
+  else:
+    return filename
diff --git a/tools/upstream/Android.bp b/tools/upstream/Android.bp
index dd01c30..63a88e2 100644
--- a/tools/upstream/Android.bp
+++ b/tools/upstream/Android.bp
@@ -16,6 +16,14 @@
 
 //#############################################################
 
+package {
+    // http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // the below license kinds from "libcore_license":
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["libcore_license"],
+}
+
 java_library_host {
     name: "libcore-compare-upstreams",
     srcs: ["src/main/java/**/*.java"],
